// File: cphinton42[P]hinton-language/src/check.cpp
// Function: typecheck_all(Pool_Allocator*, Array<Decl_AST*>)
bool typecheck_all(Pool_Allocator *ast_pool, Array<Decl_AST*> decls)
{
    Dynamic_Array<Job> job_arrays[2] = {0};
    auto current = &job_arrays[0];
    auto next = &job_arrays[1];
    
    Context ctx;
    ctx.ast_pool = ast_pool;
    ctx.waiting_jobs = next;
    ctx.success = true;
    
    for(u64 i = 0; i < decls.count; ++i)
    {
        auto job = make_typecheck_job(nullptr, decls[i]);
        do_typecheck_job(&ctx, job);
    }
    
    if(!ctx.success)
    {
        print_err("Success flag was unset (1)\n");
        return false;
    }
    
    while(true)
    {
        auto tmp = current;
        current = next;
        next = tmp;
        
        if(current->count == 0)
        {
            return true;
        }
        next->count = 0;
        ctx.waiting_jobs = next;
        
        bool change = false;
        for(u64 i = 0; i < current->count; ++i)
        {
            if(do_typecheck_job(&ctx, (*current)[i]))
            {
                change = true;
            }
        }
        
        if(!ctx.success)
        {
            print_err("Success flag was unset (2)\n");
            return false;
        }
        else if(!change)
        {
            // TODO: detect error
            print_err("Error: no progress (%lu waiting jobs)\n", next->count);
            print_jobs(next->array);
            return false;
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x110, %rsp            # imm = 0x110
movq %rsi, -0x18(%rbp)
movq %rdx, -0x10(%rbp)
movq %rdi, -0x20(%rbp)
leaq -0x50(%rbp), %rdi
xorl %esi, %esi
movl $0x30, %edx
callq 0x3060
leaq -0x50(%rbp), %rax
movq %rax, -0x58(%rbp)
leaq -0x50(%rbp), %rax
addq $0x18, %rax
movq %rax, -0x60(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x70(%rbp)
movb $0x1, -0x68(%rbp)
movq $0x0, -0x80(%rbp)
movq -0x80(%rbp), %rax
cmpq -0x18(%rbp), %rax
jae 0x9a5b
movq -0x80(%rbp), %rsi
leaq -0x18(%rbp), %rdi
callq 0x16fb0
movq (%rax), %rdx
leaq -0x98(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
xorl %ecx, %ecx
callq 0x4a80
movq -0x98(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0x90(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq -0x88(%rbp), %rax
movq %rax, -0xa0(%rbp)
leaq -0x78(%rbp), %rdi
leaq -0xb0(%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 -0x80(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x80(%rbp)
jmp 0x99c7
testb $0x1, -0x68(%rbp)
jne 0x9a78
leaq 0x107b6(%rip), %rdi     # 0x1a21e
movb $0x0, %al
callq 0x4990
movb $0x0, -0x1(%rbp)
jmp 0x9bd0
jmp 0x9a7a
movq -0x58(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0xb8(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x58(%rbp), %rax
cmpq $0x0, (%rax)
jne 0x9aab
movb $0x1, -0x1(%rbp)
jmp 0x9bd0
movq -0x60(%rbp), %rax
movq $0x0, (%rax)
movq -0x60(%rbp), %rax
movq %rax, -0x70(%rbp)
movb $0x0, -0xb9(%rbp)
movq $0x0, -0xc8(%rbp)
movq -0xc8(%rbp), %rax
movq -0x58(%rbp), %rcx
cmpq (%rcx), %rax
jae 0x9b5f
movq -0x58(%rbp), %rdi
movq -0xc8(%rbp), %rsi
callq 0x170a0
movq (%rax), %rcx
movq %rcx, -0xe0(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0xd8(%rbp)
movq 0x10(%rax), %rax
movq %rax, -0xd0(%rbp)
leaq -0x78(%rbp), %rdi
leaq -0xe0(%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
testb $0x1, %al
jne 0x9b3f
jmp 0x9b46
movb $0x1, -0xb9(%rbp)
jmp 0x9b48
movq -0xc8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xc8(%rbp)
jmp 0x9ad0
testb $0x1, -0x68(%rbp)
jne 0x9b79
leaq 0x106ce(%rip), %rdi     # 0x1a23a
movb $0x0, %al
callq 0x4990
movb $0x0, -0x1(%rbp)
jmp 0x9bd0
testb $0x1, -0xb9(%rbp)
jne 0x9bc9
movq -0x60(%rbp), %rax
movq (%rax), %rsi
leaq 0x106c6(%rip), %rdi     # 0x1a256
movb $0x0, %al
callq 0x4990
movq -0x60(%rbp), %rax
movq (%rax), %rcx
movq %rcx, -0xf0(%rbp)
movq 0x8(%rax), %rax
movq %rax, -0xe8(%rbp)
movq -0xf0(%rbp), %rdi
movq -0xe8(%rbp), %rsi
callq 0x98e0
movb $0x0, -0x1(%rbp)
jmp 0x9bd0
jmp 0x9bcb
jmp 0x9a7a
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x110, %rsp            # imm = 0x110
popq %rbp
retq
nop