// File: /workspace/github_c_makefile_star2_O1/atomlang[P]atomlang/src/pk_compiler.c
// Function: exprName
static void exprName(Compiler* compiler) {

  const char* start = compiler->previous.start;
  int length = compiler->previous.length;
  int line = compiler->previous.line;
  NameSearchResult result = compilerSearchName(compiler, start, length);

  if (result.type == NAME_NOT_DEFINED) {
    if (compiler->l_value && match(compiler, TK_EQ)) {
      skipNewLines(compiler);

      int index = compilerAddVariable(compiler, start, length, line);

      // Compile the assigned value.
      compileExpression(compiler);

      // Store the value to the variable.
      if (compiler->scope_depth == DEPTH_GLOBAL) {
        emitStoreVariable(compiler, index, true);

      } else {
        // This will prevent the assignment from being popped out from the
        // stack since the assigned value itself is the local and not a temp.
        compiler->new_local = true;
        emitStoreVariable(compiler, index, false);
      }
    } else {

      // The name could be a function which hasn't been defined at this point.
      if (peek(compiler) == TK_LPARAN) {
        emitOpcode(compiler, OP_PUSH_FN);
        int index = emitByte(compiler, 0xff);
        compilerAddForward(compiler, index, _FN, start, length, line);
      } else {
        parseError(compiler, "Name '%.*s' is not defined.", length, start);
      }
    }

  } else {

    switch (result.type) {
      case NAME_LOCAL_VAR:
      case NAME_GLOBAL_VAR: {
        const bool is_global = result.type == NAME_GLOBAL_VAR;

        if (compiler->l_value && matchAssignment(compiler)) {
          skipNewLines(compiler);

          TokenType assignment = compiler->previous.type;
          if (assignment != TK_EQ) {
            emitPushVariable(compiler, result.index, is_global);
            compileExpression(compiler);
            emitAssignment(compiler, assignment);

          } else {
            compileExpression(compiler);
          }

          emitStoreVariable(compiler, result.index, is_global);

        } else {
          emitPushVariable(compiler, result.index, is_global);
        }
        break;
      }

      case NAME_FUNCTION:
        emitOpcode(compiler, OP_PUSH_FN);
        emitByte(compiler, result.index);
        break;

      case NAME_CLASS:
        emitOpcode(compiler, OP_PUSH_TYPE);
        emitByte(compiler, result.index);
        break;

      case NAME_BUILTIN:
        emitOpcode(compiler, OP_PUSH_BUILTIN_FN);
        emitByte(compiler, result.index);
        break;

      case NAME_NOT_DEFINED:
        UNREACHABLE(); // Case already handled.
    }
  }

  compiler->is_last_call = false;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movq %rdi, %rbx
movq 0x38(%rdi), %r15
movl 0x40(%rdi), %ebp
movl 0x44(%rdi), %r12d
movq %r15, %rsi
movl %ebp, %edx
callq 0x116bc
movq %rax, %r14
cmpl $0x5, %r14d
ja 0x1009f
movl %r14d, %eax
leaq 0xdcba(%rip), %rcx      # 0x1dc58
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
cmpb $0x1, 0x38cd(%rbx)
jne 0xffe2
movq %rbx, %rdi
callq 0x12445
testb %al, %al
je 0xffe2
movq %rbx, %rdi
callq 0x11e66
movl 0x30(%rbx), %ebp
cmpl $0x1a, %ebp
jne 0x10119
movq %rbx, %rdi
movl $0x1, %esi
callq 0x12323
jmp 0x10148
xorl %edx, %edx
cmpl $0x2, %r14d
sete %dl
shrq $0x20, %r14
movq %rbx, %rdi
movl %r14d, %esi
callq 0x12496
jmp 0x1009f
movq %rbx, %rdi
movl $0x22, %esi
jmp 0x10081
cmpb $0x1, 0x38cd(%rbx)
jne 0x100af
cmpl $0x1a, 0x50(%rbx)
jne 0x100af
movq %rbx, %rdi
callq 0x10b76
movq %rbx, %rdi
callq 0x11e66
movq %rbx, %rdi
movq %r15, %rsi
movl %ebp, %edx
movl %r12d, %ecx
callq 0x11846
movl %eax, %ebp
movq %rbx, %rdi
movl $0x1, %esi
callq 0x12323
cmpl $-0x1, 0xa0(%rbx)
je 0x101ac
movb $0x1, 0x38cc(%rbx)
movq %rbx, %rdi
movl %ebp, %esi
xorl %edx, %edx
jmp 0x1015b
movq %rbx, %rdi
movl $0x24, %esi
jmp 0x10081
movq %rbx, %rdi
movl $0x23, %esi
callq 0x1135b
movq %rbx, %rdi
xorl %esi, %esi
callq 0x113b1
shrq $0x20, %r14
movq %rbx, %rdi
movl %r14d, %esi
callq 0x1135b
movb $0x0, 0x38ce(%rbx)
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
cmpl $0x9, 0x50(%rbx)
jne 0x10101
movq %rbx, %rdi
movl $0x22, %esi
callq 0x1135b
movq %rbx, %rdi
xorl %esi, %esi
callq 0x113b1
movq %rbx, %rdi
movl $0xff, %esi
callq 0x1135b
movslq 0x38c8(%rbx), %rcx
cmpq $0x100, %rcx            # imm = 0x100
jne 0x10165
leaq 0xe135(%rip), %rsi      # 0x1e225
movq %rbx, %rdi
movl $0x100, %edx            # imm = 0x100
xorl %eax, %eax
callq 0x110cb
jmp 0x1009f
leaq 0xdcf9(%rip), %rsi      # 0x1de01
movq %rbx, %rdi
movl %ebp, %edx
movq %r15, %rcx
xorl %eax, %eax
callq 0x110cb
jmp 0x1009f
xorl %edx, %edx
cmpl $0x2, %r14d
sete %dl
movq %r14, %rsi
shrq $0x20, %rsi
movq %rbx, %rdi
callq 0x12496
movq %rbx, %rdi
movl $0x1, %esi
callq 0x12323
movq %rbx, %rdi
movl %ebp, %esi
callq 0x124f5
xorl %edx, %edx
cmpl $0x2, %r14d
sete %dl
shrq $0x20, %r14
movq %rbx, %rdi
movl %r14d, %esi
callq 0x123e6
jmp 0x1009f
movq 0x18c0(%rbx), %rdx
movq 0x8(%rdx), %rdx
movq 0x38(%rdx), %rdx
leal 0x1(%rcx), %esi
movl %esi, 0x38c8(%rbx)
shlq $0x5, %rcx
movl %eax, 0x18c8(%rbx,%rcx)
movq %rdx, 0x18d0(%rbx,%rcx)
movq %r15, 0x18d8(%rbx,%rcx)
movl %ebp, 0x18e0(%rbx,%rcx)
movl %r12d, 0x18e4(%rbx,%rcx)
jmp 0x1009f
movq %rbx, %rdi
movl %ebp, %esi
movl $0x1, %edx
jmp 0x1015b