// File: /workspace/github_c_makefile_star2_O0/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:
subq $0x58, %rsp
movq %rdi, 0x50(%rsp)
movq 0x50(%rsp), %rax
movq 0x38(%rax), %rax
movq %rax, 0x48(%rsp)
movq 0x50(%rsp), %rax
movl 0x40(%rax), %eax
movl %eax, 0x44(%rsp)
movq 0x50(%rsp), %rax
movl 0x44(%rax), %eax
movl %eax, 0x40(%rsp)
movq 0x50(%rsp), %rdi
movq 0x48(%rsp), %rsi
movl 0x44(%rsp), %edx
callq 0x16dd0
movl %edx, 0x28(%rsp)
movq %rax, 0x20(%rsp)
movq 0x20(%rsp), %rax
movq %rax, 0x34(%rsp)
movl 0x28(%rsp), %eax
movl %eax, 0x3c(%rsp)
cmpl $0x0, 0x34(%rsp)
jne 0x15229
movq 0x50(%rsp), %rax
testb $0x1, 0x38cd(%rax)
je 0x151a2
movq 0x50(%rsp), %rdi
movl $0x1a, %esi
callq 0x15f50
testb $0x1, %al
jne 0x1512f
jmp 0x151a2
movq 0x50(%rsp), %rdi
callq 0x15f40
movq 0x50(%rsp), %rdi
movq 0x48(%rsp), %rsi
movl 0x44(%rsp), %edx
movl 0x40(%rsp), %ecx
callq 0x17070
movl %eax, 0x1c(%rsp)
movq 0x50(%rsp), %rdi
callq 0x17be0
movq 0x50(%rsp), %rax
cmpl $-0x1, 0xa0(%rax)
jne 0x15181
movq 0x50(%rsp), %rdi
movl 0x1c(%rsp), %esi
movl $0x1, %edx
callq 0x18350
jmp 0x1519d
movq 0x50(%rsp), %rax
movb $0x1, 0x38cc(%rax)
movq 0x50(%rsp), %rdi
movl 0x1c(%rsp), %esi
xorl %edx, %edx
callq 0x18350
jmp 0x15224
movq 0x50(%rsp), %rdi
callq 0x17480
cmpl $0x9, %eax
jne 0x15206
movq 0x50(%rsp), %rdi
movl $0x22, %esi
callq 0x16650
movq 0x50(%rsp), %rdi
movl $0xff, %esi
callq 0x166d0
movl %eax, 0x18(%rsp)
movq 0x50(%rsp), %rdi
movl 0x18(%rsp), %esi
movq 0x50(%rsp), %rax
movq 0x18c0(%rax), %rax
movq 0x8(%rax), %rax
movq 0x38(%rax), %rdx
movq 0x48(%rsp), %rcx
movl 0x44(%rsp), %r8d
movl 0x40(%rsp), %r9d
callq 0x183d0
jmp 0x15222
movq 0x50(%rsp), %rdi
movl 0x44(%rsp), %edx
movq 0x48(%rsp), %rcx
leaq 0x15d76(%rip), %rsi     # 0x2af91
movb $0x0, %al
callq 0x15f90
jmp 0x15224
jmp 0x153a2
movl 0x34(%rsp), %eax
movq %rax, 0x8(%rsp)
subq $0x5, %rax
ja 0x153a0
movq 0x8(%rsp), %rax
leaq 0x15ab0(%rip), %rcx     # 0x2acf8
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
cmpl $0x2, 0x34(%rsp)
sete %al
andb $0x1, %al
movb %al, 0x17(%rsp)
movq 0x50(%rsp), %rax
testb $0x1, 0x38cd(%rax)
je 0x152f2
movq 0x50(%rsp), %rdi
callq 0x18490
testb $0x1, %al
jne 0x15281
jmp 0x152f2
movq 0x50(%rsp), %rdi
callq 0x15f40
movq 0x50(%rsp), %rax
movl 0x30(%rax), %eax
movl %eax, 0x10(%rsp)
cmpl $0x1a, 0x10(%rsp)
je 0x152cf
movq 0x50(%rsp), %rdi
movl 0x38(%rsp), %esi
movb 0x17(%rsp), %al
andb $0x1, %al
movzbl %al, %edx
callq 0x185f0
movq 0x50(%rsp), %rdi
callq 0x17be0
movq 0x50(%rsp), %rdi
movl 0x10(%rsp), %esi
callq 0x18670
jmp 0x152d9
movq 0x50(%rsp), %rdi
callq 0x17be0
movq 0x50(%rsp), %rdi
movl 0x38(%rsp), %esi
movb 0x17(%rsp), %al
andb $0x1, %al
movzbl %al, %edx
callq 0x18350
jmp 0x15309
movq 0x50(%rsp), %rdi
movl 0x38(%rsp), %esi
movb 0x17(%rsp), %al
andb $0x1, %al
movzbl %al, %edx
callq 0x185f0
jmp 0x153a0
movq 0x50(%rsp), %rdi
movl $0x22, %esi
callq 0x16650
movq 0x50(%rsp), %rdi
movl 0x38(%rsp), %esi
callq 0x166d0
jmp 0x153a0
movq 0x50(%rsp), %rdi
movl $0x23, %esi
callq 0x16650
movq 0x50(%rsp), %rdi
movl 0x38(%rsp), %esi
callq 0x166d0
jmp 0x153a0
movq 0x50(%rsp), %rdi
movl $0x24, %esi
callq 0x16650
movq 0x50(%rsp), %rdi
movl 0x38(%rsp), %esi
callq 0x166d0
jmp 0x153a0
jmp 0x1536d
movq 0x1dc84(%rip), %rax     # 0x32ff8
movq (%rax), %rdi
leaq 0x14e5c(%rip), %rsi     # 0x2a1da
leaq 0x16030(%rip), %rdx     # 0x2b3b5
leaq 0x15c4b(%rip), %rcx     # 0x2afd7
movl $0x54d, %r8d            # imm = 0x54D
movb $0x0, %al
callq 0x2240
ud2
callq 0x2040
jmp 0x153a2
movq 0x50(%rsp), %rax
movb $0x0, 0x38ce(%rax)
addq $0x58, %rsp
retq
nopw %cs:(%rax,%rax)