// File: /workspace/github_c_makefile_star2_O0/naleksiev[P]fin/src/fin_mod.c
// Function: fin_mod_resolve_type
static fin_str_t* fin_mod_resolve_type(fin_ctx_t* ctx, fin_mod_compiler_t* cmp, fin_ast_expr_t* expr) {
    switch (expr->type) {
        case fin_ast_expr_type_init:
        case fin_ast_expr_type_assign:
            return NULL;
        case fin_ast_expr_type_bool:
            return fin_str_create(ctx, "bool", -1);
        case fin_ast_expr_type_int:
            return fin_str_create(ctx, "int", -1);
        case fin_ast_expr_type_float:
            return fin_str_create(ctx, "float", -1);
        case fin_ast_expr_type_str:
        case fin_ast_expr_type_str_interp:
            return fin_str_create(ctx, "string", -1);
        case fin_ast_expr_type_id: {
            fin_ast_id_expr_t* id_expr = (fin_ast_id_expr_t*)expr;
            if (id_expr->primary) {
                fin_str_t* type_name = fin_mod_resolve_type(ctx, cmp, id_expr->primary);
                fin_mod_type_t* type = fin_mod_find_type(ctx, cmp->mod, type_name);
                fin_str_destroy(ctx, type_name);
                for (int32_t i=0; i<type->fields_count; i++) {
                    if (type->fields[i].name == id_expr->name)
                        return fin_str_clone(type->fields[i].type);
                }
                printf("Unresolved field %s\n", fin_str_cstr(id_expr->name));
                assert(0);
            }
            else {
                fin_mod_local_t* local = fin_mod_resolve_local(cmp, id_expr->name);
                assert(local);
                return fin_str_clone(local->type);
            }
        }
        case fin_ast_expr_type_unary: {
            fin_ast_unary_expr_t* unary_expr = (fin_ast_unary_expr_t*)expr;
            fin_str_t* sign = fin_mod_unary_get_signature(ctx, cmp, unary_expr);
            fin_mod_func_t* func = fin_mod_find_func(ctx, cmp->mod, sign);
            fin_str_destroy(ctx, sign);
            return fin_str_clone(func->ret_type);
        }
        case fin_ast_expr_type_binary: {
            fin_ast_binary_expr_t* bin_expr = (fin_ast_binary_expr_t*)expr;
            fin_str_t* sign = fin_mod_binary_get_signature(ctx, cmp, bin_expr);
            fin_mod_func_t* func = fin_mod_find_func(ctx, cmp->mod, sign);
            fin_str_destroy(ctx, sign);
            return fin_str_clone(func->ret_type);
        }
        case fin_ast_expr_type_cond: {
            fin_ast_cond_expr_t* cond_expr = (fin_ast_cond_expr_t*)expr;
            fin_str_t* true_type = fin_mod_resolve_type(ctx, cmp, cond_expr->true_expr);
            fin_str_t* false_type = fin_mod_resolve_type(ctx, cmp, cond_expr->false_expr);
            assert(true_type == false_type);
            fin_str_destroy(ctx, false_type);
            return true_type;
        }
        case fin_ast_expr_type_arg: {
            fin_ast_arg_expr_t* arg_expr = (fin_ast_arg_expr_t*)expr;
            return fin_mod_resolve_type(ctx, cmp, arg_expr->expr);
        }
        case fin_ast_expr_type_invoke: {
            fin_ast_invoke_expr_t* invoke_expr = (fin_ast_invoke_expr_t*)expr;
            fin_str_t* sign = fin_mod_invoke_get_signature(ctx, cmp, invoke_expr);
            fin_mod_func_t* func = fin_mod_find_func(ctx, cmp->mod, sign);
            fin_str_destroy(ctx, sign);
            return fin_str_clone(func->ret_type);
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x20(%rbp), %rax
movl (%rax), %eax
movq %rax, -0xb8(%rbp)
subq $0xc, %rax
ja 0xa096
movq -0xb8(%rbp), %rax
leaq 0x38f0(%rip), %rcx      # 0xd5dc
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq $0x0, -0x8(%rbp)
jmp 0xa096
movq -0x10(%rbp), %rdi
leaq 0x3b12(%rip), %rsi      # 0xd81f
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0xae20
movq %rax, -0x8(%rbp)
jmp 0xa096
movq -0x10(%rbp), %rdi
leaq 0x3af9(%rip), %rsi      # 0xd824
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0xae20
movq %rax, -0x8(%rbp)
jmp 0xa096
movq -0x10(%rbp), %rdi
leaq 0x3adf(%rip), %rsi      # 0xd828
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0xae20
movq %rax, -0x8(%rbp)
jmp 0xa096
movq -0x10(%rbp), %rdi
leaq 0x3a4c(%rip), %rsi      # 0xd7b3
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0xae20
movq %rax, -0x8(%rbp)
jmp 0xa096
movq -0x20(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x9e71
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x28(%rbp), %rax
movq 0x8(%rax), %rdx
callq 0x9cb0
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq (%rax), %rsi
movq -0x30(%rbp), %rdx
callq 0xa8b0
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0xb0b0
movl $0x0, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
movq -0x38(%rbp), %rcx
cmpl 0x10(%rcx), %eax
jge 0x9e34
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x3c(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rax
movq -0x28(%rbp), %rcx
cmpq 0x10(%rcx), %rax
jne 0x9e27
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x3c(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rdi
callq 0xb130
movq %rax, -0x8(%rbp)
jmp 0xa096
jmp 0x9e29
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x9dd6
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0xb370
movq %rax, %rsi
leaq 0x39e3(%rip), %rdi      # 0xd82e
movb $0x0, %al
callq 0x3100
leaq 0x33bc(%rip), %rdi      # 0xd215
leaq 0x3844(%rip), %rsi      # 0xd6a4
movl $0x11d, %edx            # imm = 0x11D
leaq 0x39d7(%rip), %rcx      # 0xd843
callq 0x3110
movq -0x18(%rbp), %rdi
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rsi
callq 0x9c30
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
je 0x9e8f
jmp 0x9eae
leaq 0x38c8(%rip), %rdi      # 0xd75e
leaq 0x3807(%rip), %rsi      # 0xd6a4
movl $0x121, %edx            # imm = 0x121
leaq 0x399a(%rip), %rcx      # 0xd843
callq 0x3110
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0xb130
movq %rax, -0x8(%rbp)
jmp 0xa096
movq -0x20(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x50(%rbp), %rdx
callq 0xa2a0
movq %rax, -0x58(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq (%rax), %rsi
movq -0x58(%rbp), %rdx
callq 0x8250
movq %rax, -0x60(%rbp)
movq -0x10(%rbp), %rdi
movq -0x58(%rbp), %rsi
callq 0xb0b0
movq -0x60(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0xb130
movq %rax, -0x8(%rbp)
jmp 0xa096
movq -0x20(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x68(%rbp), %rdx
callq 0xa3f0
movq %rax, -0x70(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq (%rax), %rsi
movq -0x70(%rbp), %rdx
callq 0x8250
movq %rax, -0x78(%rbp)
movq -0x10(%rbp), %rdi
movq -0x70(%rbp), %rsi
callq 0xb0b0
movq -0x78(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0xb130
movq %rax, -0x8(%rbp)
jmp 0xa096
movq -0x20(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x80(%rbp), %rax
movq 0x10(%rax), %rdx
callq 0x9cb0
movq %rax, -0x88(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x80(%rbp), %rax
movq 0x18(%rax), %rdx
callq 0x9cb0
movq %rax, -0x90(%rbp)
movq -0x88(%rbp), %rax
cmpq -0x90(%rbp), %rax
jne 0x9fc6
jmp 0x9fe5
leaq 0x38cb(%rip), %rdi      # 0xd898
leaq 0x36d0(%rip), %rsi      # 0xd6a4
movl $0x137, %edx            # imm = 0x137
leaq 0x3863(%rip), %rcx      # 0xd843
callq 0x3110
movq -0x10(%rbp), %rdi
movq -0x90(%rbp), %rsi
callq 0xb0b0
movq -0x88(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xa096
movq -0x20(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x98(%rbp), %rax
movq 0x8(%rax), %rdx
callq 0x9cb0
movq %rax, -0x8(%rbp)
jmp 0xa096
movq -0x20(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0xa0(%rbp), %rdx
callq 0xa6e0
movq %rax, -0xa8(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq (%rax), %rsi
movq -0xa8(%rbp), %rdx
callq 0x8250
movq %rax, -0xb0(%rbp)
movq -0x10(%rbp), %rdi
movq -0xa8(%rbp), %rsi
callq 0xb0b0
movq -0xb0(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0xb130
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0xc0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)