// File: cphinton42[P]hinton-language/src/check.cpp
// Function: typecheck_struct(Context*, unsigned int, Expr_AST*, Struct_AST*)
internal
bool typecheck_struct(Context *ctx, u32 stage, Expr_AST *type, Struct_AST *struct_ast)
{
    u32 new_stage = 0;
    switch(stage)
    {
        case 0: {
            if(type)
            {
                Status status = types_match(ctx, type, &type_t_ast);
                if(status != Status::good)
                {
                    break;
                }
            }
        } // fall through
        case 1: {
            new_stage = 1;
            set_resolved_type(struct_ast, &type_t_ast);
            
            for(u64 i = 0; i < struct_ast->constants.count; ++i)
            {
                auto job = make_typecheck_job(nullptr, struct_ast->constants[i]);
                do_typecheck_job(ctx, job);
            }
            for(u64 i = 0; i < struct_ast->fields.count; ++i)
            {
                auto job = make_typecheck_job(nullptr, struct_ast->fields[i]);
                do_typecheck_job(ctx, job);
            }
            new_stage = 2;
        } // fall through
        // TODO: size struct
    }
    
    if(new_stage < 2)
    {
        auto job = make_typecheck_job(type, struct_ast, new_stage);
        array_add(ctx->waiting_jobs, job);
    }
    return new_stage != stage;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x100, %rsp            # imm = 0x100
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, -0xdc(%rbp)
testl %eax, %eax
je 0x8220
jmp 0x8210
movl -0xdc(%rbp), %eax
subl $0x1, %eax
je 0x8252
jmp 0x8389
cmpq $0x0, -0x18(%rbp)
je 0x8250
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rsi
leaq 0x17cba(%rip), %rdx     # 0x1fef0
movl $0x1, %ecx
callq 0x9240
movl %eax, -0x28(%rbp)
cmpl $0x0, -0x28(%rbp)
je 0x824e
jmp 0x8389
jmp 0x8250
jmp 0x8252
movl $0x1, -0x24(%rbp)
movq -0x20(%rbp), %rdi
leaq 0x17c8c(%rip), %rsi     # 0x1fef0
callq 0x3be0
movq $0x0, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq -0x20(%rbp), %rcx
cmpq 0x20(%rcx), %rax
jae 0x82ee
movq -0x20(%rbp), %rdi
addq $0x20, %rdi
movq -0x30(%rbp), %rsi
callq 0x16fb0
movq (%rax), %rdx
leaq -0x48(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
xorl %ecx, %ecx
callq 0x4a80
movq -0x8(%rbp), %rdi
movq -0x48(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0x50(%rbp)
leaq -0x60(%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 0x4b40
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0x8271
movq $0x0, -0x68(%rbp)
movq -0x68(%rbp), %rax
movq -0x20(%rbp), %rcx
cmpq 0x30(%rcx), %rax
jae 0x8382
movq -0x20(%rbp), %rdi
addq $0x30, %rdi
movq -0x68(%rbp), %rsi
callq 0x16fb0
movq (%rax), %rdx
leaq -0x80(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
xorl %ecx, %ecx
callq 0x4a80
movq -0x8(%rbp), %rdi
movq -0x80(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x78(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x70(%rbp), %rax
movq %rax, -0x88(%rbp)
leaq -0x98(%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 0x4b40
movq -0x68(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x68(%rbp)
jmp 0x82f6
movl $0x2, -0x24(%rbp)
cmpl $0x2, -0x24(%rbp)
jae 0x842b
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
movl -0x24(%rbp), %ecx
leaq -0xb0(%rbp), %rdi
callq 0x4a80
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0xb0(%rbp), %rax
movq %rax, -0xc8(%rbp)
movq -0xa8(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0xa0(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq 0x1789d(%rip), %rax     # 0x1fc80
movq %rax, -0xd8(%rbp)
movq 0x17897(%rip), %rax     # 0x1fc88
movq %rax, -0xd0(%rbp)
movq -0xd8(%rbp), %rsi
movq -0xd0(%rbp), %rdx
leaq -0xc8(%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 $0x100, %rsp            # imm = 0x100
popq %rbp
retq
nop