// File: cphinton42[P]hinton-language/src/main.cpp
// Function: main
int main(int argc, char **argv)
{
    // Note: if this becomes multi-threaded, we can get rid of the globals (writes smaller than 4K are supposed to be atomic IIRC)
    // Alternatively, formatting could occur in thread-local buffers, and output is guarded by a global mutex
    init_std_print_buffers();
    init_primitive_types();
    
    String file_contents = read_entire_file("test.txt");
    if(!file_contents.data)
    {
        print_err("Unable to read test.txt\n");
    }
    
    Dynamic_Array<Token> tokens = lex_string(file_contents);
    if(!tokens.data)
    {
        return 1;
    }
    
    Pool_Allocator ast_pool;
    Parsing_Context ctx;
    
    pool_init(&ast_pool, 4096);
    init_parsing_context(&ctx, file_contents, tokens.array, &ast_pool);
    Dynamic_Array<Decl_AST*> decls = parse_tokens(&ctx);
    
    array_trim(&decls);
    
    Atom_Table atom_table;
    init_atom_table(&atom_table, 128, 4096);
    
    Scoping_Context scoping_ctx;
    scoping_ctx.atom_table = &atom_table;
    scoping_ctx.ast_pool = &ast_pool;
    bool success = create_scope_metadata(&scoping_ctx, decls.array);
    if(!success)
    {
        return 1;
    }
    success = typecheck_all(&ast_pool, decls.array);
    if(!success)
    {
        print_err("No success\n");
        return 1;
    }
    
    for(u64 i = 0; i < decls.count; ++i)
    {
        check_for_untyped(decls[i]);
    }
    
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x190, %rsp            # imm = 0x190
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0x400, %esi            # imm = 0x400
movq %rsi, %rdi
callq 0x9f50
callq 0x3450
leaq 0xe264(%rip), %rdi      # 0x1a376
callq 0x9be0
movq %rax, -0x20(%rbp)
movq %rdx, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
jne 0xc134
leaq 0xe252(%rip), %rdi      # 0x1a37f
movb $0x0, %al
callq 0x4990
movq -0x20(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x48(%rbp), %rsi
movq -0x40(%rbp), %rdx
leaq -0x38(%rbp), %rdi
callq 0xa320
cmpq $0x0, -0x30(%rbp)
jne 0xc168
movl $0x1, -0x4(%rbp)
jmp 0xc345
leaq -0x80(%rbp), %rdi
movl $0x1000, %esi           # imm = 0x1000
callq 0xc360
movq -0x20(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0xc8(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0xb8(%rbp), %rsi
movq -0xb0(%rbp), %rdx
movq -0xc8(%rbp), %rcx
movq -0xc0(%rbp), %r8
leaq -0xa8(%rbp), %rdi
leaq -0x80(%rbp), %r9
callq 0xc390
leaq -0xe0(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0xc3f0
movq 0x13a98(%rip), %rax     # 0x1fc80
movq %rax, -0xf0(%rbp)
movq 0x13a92(%rip), %rax     # 0x1fc88
movq %rax, -0xe8(%rbp)
movq -0xf0(%rbp), %rsi
movq -0xe8(%rbp), %rdx
leaq -0xe0(%rbp), %rdi
callq 0x17300
leaq -0x148(%rbp), %rdi
movl $0x80, %esi
movl $0x1000, %edx           # imm = 0x1000
callq 0xc560
leaq -0x148(%rbp), %rax
movq %rax, -0x160(%rbp)
leaq -0x80(%rbp), %rax
movq %rax, -0x158(%rbp)
movq -0xe0(%rbp), %rax
movq %rax, -0x178(%rbp)
movq -0xd8(%rbp), %rax
movq %rax, -0x170(%rbp)
movq -0x178(%rbp), %rsi
movq -0x170(%rbp), %rdx
leaq -0x160(%rbp), %rdi
callq 0xc5a0
andb $0x1, %al
movb %al, -0x161(%rbp)
testb $0x1, -0x161(%rbp)
jne 0xc299
movl $0x1, -0x4(%rbp)
jmp 0xc345
movq -0xe0(%rbp), %rax
movq %rax, -0x188(%rbp)
movq -0xd8(%rbp), %rax
movq %rax, -0x180(%rbp)
movq -0x188(%rbp), %rsi
movq -0x180(%rbp), %rdx
leaq -0x80(%rbp), %rdi
callq 0x9970
andb $0x1, %al
movb %al, -0x161(%rbp)
testb $0x1, -0x161(%rbp)
jne 0xc2f4
leaq 0xe0b4(%rip), %rdi      # 0x1a398
movb $0x0, %al
callq 0x4990
movl $0x1, -0x4(%rbp)
jmp 0xc345
movq $0x0, -0x190(%rbp)
movq -0x190(%rbp), %rax
cmpq -0xe0(%rbp), %rax
jae 0xc33e
movq -0x190(%rbp), %rsi
leaq -0xe0(%rbp), %rdi
callq 0x17370
movq (%rax), %rdi
callq 0xbb40
movq -0x190(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x190(%rbp)
jmp 0xc2ff
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x190, %rsp            # imm = 0x190
popq %rbp
retq
nopw %cs:(%rax,%rax)