// File: cphinton42[P]hinton-language/src/check.cpp
// Function: typecheck_ident(Context*, unsigned int, Expr_AST*, Ident_AST*)
bool typecheck_ident(Context *ctx, u32 stage, Expr_AST *type, Ident_AST *ident_ast)
{
    u32 new_stage = 0;
    switch(stage)
    {
        case 0: {
            ident_ast->flags |= EXPR_FLAG_LVALUE;
            Expr_AST *expr = scope_find(ident_ast->scope, ident_ast->atom, ident_ast->scope_index);
            if(expr)
            {
                ident_set_expr(ident_ast, expr);
            }
            else
            {
                String *str = ident_ast->atom.str;
                print_err("Error: %d:%d: Undeclared identifier \"%.*s\"\n", ident_ast->line_number, ident_ast->line_offset, str->count, str->data);
                ctx->success = false;
                break;
            }
        } // fall through
        case 1: {
            new_stage = 1;
            Expr_AST *expr = ident_get_expr(ident_ast);
            if(!type_resolved(expr))
            {
                break;
            }
        } // fall through
        case 2: {
            new_stage = 2;
            Expr_AST *expr = ident_get_expr(ident_ast);
            if(type)
            {
                Status status = types_match(ctx, type, expr->resolved_type);
                if(status != Status::good)
                {
                    break;
                }
            }
            set_resolved_type(ident_ast, expr->resolved_type);
            new_stage = 3;
        } // fall through
    }
    
    if(new_stage < 3)
    {
        auto job = make_typecheck_job(type, ident_ast, new_stage);
        array_add(ctx->waiting_jobs, job);
    }
    return new_stage != stage;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movl $0x0, -0x24(%rbp)
movl -0xc(%rbp), %eax
movl %eax, -0x9c(%rbp)
testl %eax, %eax
je 0x5e15
jmp 0x5df0
movl -0x9c(%rbp), %eax
subl $0x1, %eax
je 0x5eae
jmp 0x5e01
movl -0x9c(%rbp), %eax
subl $0x2, %eax
je 0x5ed3
jmp 0x5f2d
movq -0x20(%rbp), %rax
movzwl 0x2(%rax), %ecx
orl $0x10, %ecx
movw %cx, 0x2(%rax)
movq -0x20(%rbp), %rax
movq 0x38(%rax), %rdi
movq -0x20(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x20(%rbp), %rax
movq 0x30(%rax), %rdx
movq -0x38(%rbp), %rsi
movl $0x1, %ecx
callq 0xd4d0
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x5e68
movq -0x20(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x17c00
jmp 0x5eac
movq -0x20(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x20(%rbp), %rax
movl 0x8(%rax), %esi
movq -0x20(%rbp), %rax
movl 0xc(%rax), %edx
movq -0x40(%rbp), %rax
movq (%rax), %rcx
movq -0x40(%rbp), %rax
movq 0x8(%rax), %r8
leaq 0x14e7b(%rip), %rdi     # 0x1ad13
movb $0x0, %al
callq 0x4990
movq -0x8(%rbp), %rax
movb $0x0, 0x10(%rax)
jmp 0x5f2d
jmp 0x5eae
movl $0x1, -0x24(%rbp)
movq -0x20(%rbp), %rdi
callq 0x17030
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rdi
callq 0x5600
testb $0x1, %al
jne 0x5ed1
jmp 0x5f2d
jmp 0x5ed3
movl $0x2, -0x24(%rbp)
movq -0x20(%rbp), %rdi
callq 0x17030
movq %rax, -0x50(%rbp)
cmpq $0x0, -0x18(%rbp)
je 0x5f15
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x50(%rbp), %rax
movq 0x18(%rax), %rdx
movl $0x1, %ecx
callq 0x9240
movl %eax, -0x54(%rbp)
cmpl $0x0, -0x54(%rbp)
je 0x5f13
jmp 0x5f2d
jmp 0x5f15
movq -0x20(%rbp), %rdi
movq -0x50(%rbp), %rax
movq 0x18(%rax), %rsi
callq 0x3be0
movl $0x3, -0x24(%rbp)
cmpl $0x3, -0x24(%rbp)
jae 0x5fbd
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
movl -0x24(%rbp), %ecx
leaq -0x70(%rbp), %rdi
callq 0x4a80
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x70(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x68(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x78(%rbp)
movq 0x19d0b(%rip), %rax     # 0x1fc80
movq %rax, -0x98(%rbp)
movq 0x19d05(%rip), %rax     # 0x1fc88
movq %rax, -0x90(%rbp)
movq -0x98(%rbp), %rsi
movq -0x90(%rbp), %rdx
leaq -0x88(%rbp), %rax
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rax
movq %rax, 0x10(%rsp)
callq 0x17c30
movl -0x24(%rbp), %eax
cmpl -0xc(%rbp), %eax
setne %al
andb $0x1, %al
addq $0xc0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)