// File: /workspace/github_c_makefile_star2_O3/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 0x1132e
movq %rax, %r14
cmpl $0x5, %r14d
ja 0xfd64
movl %r14d, %eax
leaq 0xd0bf(%rip), %rcx      # 0x1cc58
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
cmpb $0x1, 0x38cd(%rbx)
jne 0xfc02
movl 0x50(%rbx), %eax
leal -0x21(%rax), %ecx
cmpl $0x8, %ecx
jb 0xfbcd
cmpl $0x2c, %eax
ja 0xfc02
movl %eax, %eax
movabsq $0x180004000000, %rcx   # imm = 0x180004000000
btq %rax, %rcx
jae 0xfc02
movq %rbx, %rdi
callq 0x10771
movq %rbx, %rdi
callq 0x11bcc
movl 0x30(%rbx), %ebp
cmpl $0x1a, %ebp
jne 0xfd1e
movq %rbx, %rdi
movl $0x1, %esi
callq 0x11eb4
movq %r14, %r15
shrq $0x20, %r15
jmp 0xfd50
xorl %edx, %edx
cmpl $0x2, %r14d
sete %dl
shrq $0x20, %r14
movq %rbx, %rdi
movl %r14d, %esi
callq 0x11fd6
jmp 0xfd64
movq %rbx, %rdi
movl $0x22, %esi
jmp 0xfca2
movl 0x50(%rbx), %eax
cmpl $0x1a, %eax
sete %cl
andb 0x38cd(%rbx), %cl
cmpb $0x1, %cl
jne 0xfcc5
movq %rbx, %rdi
callq 0x10771
movq %rbx, %rdi
callq 0x11bcc
movq %rbx, %rdi
movq %r15, %rsi
movl %ebp, %edx
movl %r12d, %ecx
callq 0x11440
movl %eax, %ebp
movq %rbx, %rdi
movl $0x1, %esi
callq 0x11eb4
cmpl $-0x1, 0xa0(%rbx)
je 0xfd8c
movb $0x1, 0x38cc(%rbx)
movq %rbx, %rdi
movl %ebp, %esi
xorl %edx, %edx
jmp 0xfd5f
movq %rbx, %rdi
movl $0x24, %esi
jmp 0xfca2
movq %rbx, %rdi
movl $0x23, %esi
callq 0x10fbe
movq %rbx, %rdi
xorl %esi, %esi
callq 0x11014
shrq $0x20, %r14
movq %rbx, %rdi
movl %r14d, %esi
callq 0x10fbe
jmp 0xfd64
cmpl $0x9, %eax
jne 0xfd74
movq %rbx, %rdi
movl $0x22, %esi
callq 0x10fbe
movq %rbx, %rdi
xorl %esi, %esi
callq 0x11014
movq %rbx, %rdi
movl $0xff, %esi
callq 0x10fbe
movslq 0x38c8(%rbx), %rcx
cmpq $0x100, %rcx            # imm = 0x100
jne 0xfd98
leaq 0xd554(%rip), %rsi      # 0x1d261
movq %rbx, %rdi
movl $0x100, %edx            # imm = 0x100
xorl %eax, %eax
callq 0x10d4f
jmp 0xfd64
xorl %edx, %edx
cmpl $0x2, %r14d
sete %dl
movq %r14, %r15
shrq $0x20, %r15
movq %rbx, %rdi
movl %r15d, %esi
callq 0x11fd6
movq %rbx, %rdi
movl $0x1, %esi
callq 0x11eb4
movq %rbx, %rdi
movl %ebp, %esi
callq 0x12035
xorl %edx, %edx
cmpl $0x2, %r14d
sete %dl
movq %rbx, %rdi
movl %r15d, %esi
callq 0x11f77
movb $0x0, 0x38ce(%rbx)
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
leaq 0xd0c2(%rip), %rsi      # 0x1ce3d
movq %rbx, %rdi
movl %ebp, %edx
movq %r15, %rcx
xorl %eax, %eax
callq 0x10d4f
jmp 0xfd64
movq %rbx, %rdi
movl %ebp, %esi
movl $0x1, %edx
jmp 0xfd5f
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 0xfd64