// File: /workspace/github_c_makefile_star2_O1/naleksiev[P]fin/src/fin_mod.c
// Function: fin_mod_compile_stmt
static void fin_mod_compile_stmt(fin_ctx_t* ctx, fin_mod_compiler_t* cmp, fin_ast_stmt_t* stmt) {
    switch (stmt->type) {
        case fin_ast_stmt_type_expr: {
            fin_ast_expr_stmt_t* expr_stmt = (fin_ast_expr_stmt_t*)stmt;
            fin_mod_compile_expr(ctx, cmp, expr_stmt->expr);
            break;
        }
        case fin_ast_stmt_type_ret: {
            fin_ast_ret_stmt_t* ret_stmt = (fin_ast_ret_stmt_t*)stmt;
            if (ret_stmt->expr) {
                if (ret_stmt->expr->type == fin_ast_expr_type_init)
                    fin_mod_compile_init_expr(ctx, cmp, (fin_ast_init_expr_t*)ret_stmt->expr, cmp->ret_type);
                else
                    fin_mod_compile_expr(ctx, cmp, ret_stmt->expr);
            }
            fin_mod_code_emit_uint8(ctx, &cmp->code, fin_op_return);
            FIN_LOG("\tret\n");
            break;
        }
        case fin_ast_stmt_type_if: {
            fin_ast_if_stmt_t* if_stmt = (fin_ast_if_stmt_t*)stmt;
            fin_mod_compile_expr(ctx, cmp, if_stmt->cond);
            fin_mod_code_emit_uint8(ctx, &cmp->code, fin_op_branch_if_n);
            uint8_t* lbl_else = cmp->code.top;
            fin_mod_code_emit_uint16(ctx, &cmp->code, 0);
            FIN_LOG("\tbr_if_n     lbl_%d\n", (int32_t)(lbl_else - cmp->code.begin));
            fin_mod_scope_begin(cmp);
            fin_mod_compile_stmt(ctx, cmp, if_stmt->true_stmt);
            fin_mod_scope_end(cmp);
            if (if_stmt->false_stmt) {
                fin_mod_code_emit_uint8(ctx, &cmp->code, fin_op_branch);
                uint8_t* lbl_end = cmp->code.top;
                fin_mod_code_emit_uint16(ctx, &cmp->code, 0);
                FIN_LOG("\tbr          lbl_%d\n", (int32_t)(lbl_end - cmp->code.begin));
                FIN_LOG("lbl_%d:\n", (int32_t)(lbl_else - cmp->code.begin));
                uint16_t offset = cmp->code.top - lbl_else - 2;
                *lbl_else++ = offset & 0xFF;
                *lbl_else++ = (offset >> 8) & 0xFF;
                fin_mod_scope_begin(cmp);
                fin_mod_compile_stmt(ctx, cmp, if_stmt->false_stmt);
                fin_mod_scope_end(cmp);
                FIN_LOG("lbl_%d:\n", (int32_t)(lbl_end - cmp->code.begin));
                offset = cmp->code.top - lbl_end - 2;
                *lbl_end++ = offset & 0xFF;
                *lbl_end++ = (offset >> 8) & 0xFF;
            }
            else {
                FIN_LOG("lbl_%d:\n", (int32_t)(lbl_else - cmp->code.begin));
                uint16_t offset = cmp->code.top - lbl_else - 2;
                *lbl_else++ = offset & 0xFF;
                *lbl_else++ = (offset >> 8) & 0xFF;
            }
            break;
        }
        case fin_ast_stmt_type_for: {
            fin_ast_for_stmt_t* for_stmt = (fin_ast_for_stmt_t*)stmt;
            fin_mod_scope_begin(cmp);
            fin_mod_compile_expr(ctx, cmp, for_stmt->init);
            uint8_t* lbl_loop = cmp->code.top;
            FIN_LOG("lbl_%d:\n", (int32_t)(lbl_loop - cmp->code.begin));
            fin_mod_compile_expr(ctx, cmp, for_stmt->cond);
            fin_mod_code_emit_uint8(ctx, &cmp->code, fin_op_branch_if_n);
            uint8_t* lbl_end = cmp->code.top;
            fin_mod_code_emit_uint16(ctx, &cmp->code, 0);
            FIN_LOG("\tbr_if_n     lbl_%d\n", (int32_t)(lbl_end - cmp->code.begin));
            fin_mod_scope_begin(cmp);
            fin_mod_compile_stmt(ctx, cmp, for_stmt->stmt);
            fin_mod_scope_end(cmp);
            fin_mod_compile_expr(ctx, cmp, for_stmt->loop);
            uint16_t offset = lbl_loop - cmp->code.top - 3;
            fin_mod_code_emit_uint8(ctx, &cmp->code, fin_op_branch);
            fin_mod_code_emit_uint16(ctx, &cmp->code, offset);
            FIN_LOG("\tbr          lbl_%d\n", (int32_t)(lbl_loop - cmp->code.begin));
            FIN_LOG("lbl_%d:\n", (int32_t)(lbl_end - cmp->code.begin));
            offset = cmp->code.top - lbl_end - 2;
            *lbl_end++ = offset & 0xFF;
            *lbl_end++ = (offset >> 8) & 0xFF;
            fin_mod_scope_end(cmp);
            break;
        }
        case fin_ast_stmt_type_while: {
            fin_ast_while_stmt_t* while_stmt = (fin_ast_while_stmt_t*)stmt;
            fin_mod_scope_begin(cmp);
            uint8_t* lbl_loop = cmp->code.top;
            FIN_LOG("lbl_%d:\n", (int32_t)(lbl_loop - cmp->code.begin));
            fin_mod_compile_expr(ctx, cmp, while_stmt->cond);
            fin_mod_code_emit_uint8(ctx, &cmp->code, fin_op_branch_if_n);
            uint8_t* lbl_end = cmp->code.top;
            fin_mod_code_emit_uint16(ctx, &cmp->code, 0);
            FIN_LOG("\tbr_if_n     lbl_%d\n", (int32_t)(lbl_end - cmp->code.begin));
            fin_mod_scope_begin(cmp);
            fin_mod_compile_stmt(ctx, cmp, while_stmt->stmt);
            fin_mod_scope_end(cmp);
            uint16_t offset = lbl_loop - cmp->code.top - 3;
            fin_mod_code_emit_uint8(ctx, &cmp->code, fin_op_branch);
            fin_mod_code_emit_uint16(ctx, &cmp->code, offset);
            FIN_LOG("\tbr          lbl_%d\n", (int32_t)(lbl_loop - cmp->code.begin));
            FIN_LOG("lbl_%d:\n", (int32_t)(lbl_end - cmp->code.begin));
            offset = cmp->code.top - lbl_end - 2;
            *lbl_end++ = offset & 0xFF;
            *lbl_end++ = (offset >> 8) & 0xFF;
            fin_mod_scope_end(cmp);
            break;
        }
        case fin_ast_stmt_type_do: {
            fin_ast_do_stmt_t* do_stmt = (fin_ast_do_stmt_t*)stmt;
            uint8_t* lbl_loop = cmp->code.top;
            FIN_LOG("lbl_%d:\n", (int32_t)(lbl_loop - cmp->code.begin));
            fin_mod_scope_begin(cmp);
            fin_mod_compile_stmt(ctx, cmp, do_stmt->stmt);
            fin_mod_scope_end(cmp);
            fin_mod_compile_expr(ctx, cmp, do_stmt->cond);
            fin_mod_code_emit_uint8(ctx, &cmp->code, fin_op_branch_if);
            FIN_LOG("\tbr_if       lbl_%d\n", (int32_t)(lbl_loop - cmp->code.begin));
            uint16_t offset = lbl_loop - cmp->code.top - 2;
            fin_mod_code_emit_uint16(ctx, &cmp->code, offset);
            break;
        }
        case fin_ast_stmt_type_decl: {
            fin_ast_decl_stmt_t* decl_stmt = (fin_ast_decl_stmt_t*)stmt;
            assert(!fin_mod_resolve_local(cmp, decl_stmt->name));
            fin_mod_local_t* local = &cmp->locals[cmp->locals_count++];
            local->name = decl_stmt->name;
            local->type = decl_stmt->type->name;
            local->idx = cmp->locals_count - cmp->params_count - 1;
            local->is_param = false;
            if (decl_stmt->init) {
                if (decl_stmt->init->type == fin_ast_expr_type_init)
                    fin_mod_compile_init_expr(ctx, cmp, (fin_ast_init_expr_t*)decl_stmt->init, decl_stmt->type->name);
                else
                    fin_mod_compile_expr(ctx, cmp, decl_stmt->init);
                fin_mod_code_emit_uint8(ctx, &cmp->code, fin_op_store_local);
                fin_mod_code_emit_uint8(ctx, &cmp->code, local->idx);
                FIN_LOG("\tstore_loc  %2d\n", local->idx);
            }
            break;
        }
        case fin_ast_stmt_type_block: {
            fin_ast_block_stmt_t* block_stmt = (fin_ast_block_stmt_t*)stmt;
            fin_mod_scope_begin(cmp);
            for (fin_ast_stmt_t* s = block_stmt->stmts; s; s = s->next)
                fin_mod_compile_stmt(ctx, cmp, s);
            fin_mod_scope_end(cmp);
            break;
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl (%rdx), %eax
cmpq $0x7, %rax
ja 0x6bf9
movq %rdx, %r15
movq %rsi, %rbx
movq %rdi, %r14
leaq 0x3df0(%rip), %rcx      # 0xa340
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x10(%r15), %rdx
movq %r14, %rdi
movq %rbx, %rsi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x6c27
movb 0x1a30(%rbx), %al
movzbl 0x1a33(%rbx), %ecx
leal 0x1(%rcx), %edx
movb %dl, 0x1a33(%rbx)
movb %al, 0x1930(%rbx,%rcx)
leaq 0x18(%rbx), %r12
movq 0x18(%rbx), %rax
movq %rax, -0x30(%rbp)
movq 0x10(%r15), %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x6c27
movq %r14, %rdi
movq %r12, %rsi
movl $0x1, %edx
callq 0x7eaf
movq 0x18(%rbx), %rax
leaq 0x1(%rax), %rcx
movq %rcx, 0x18(%rbx)
movb $0xa, (%rax)
movq 0x18(%rbx), %r13
movq %r14, %rdi
movq %r12, %rsi
movl $0x2, %edx
callq 0x7eaf
movq 0x18(%rbx), %rax
leaq 0x1(%rax), %rcx
movq %rcx, 0x18(%rbx)
xorl %ecx, %ecx
movb %cl, (%rax)
movq 0x18(%rbx), %rax
leaq 0x1(%rax), %rdx
movq %rdx, 0x18(%rbx)
movb %cl, (%rax)
movb 0x1a30(%rbx), %al
movzbl 0x1a33(%rbx), %ecx
leal 0x1(%rcx), %edx
movb %dl, 0x1a33(%rbx)
movb %al, 0x1930(%rbx,%rcx)
movq 0x18(%r15), %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x6526
movb 0x1a30(%rbx), %al
cmpb %al, 0x1a31(%rbx)
jae 0x663f
movb %al, 0x1a31(%rbx)
movb 0x1a33(%rbx), %al
decb %al
movb %al, 0x1a33(%rbx)
movzbl %al, %eax
movb 0x1930(%rbx,%rax), %al
movb %al, 0x1a30(%rbx)
jmp 0x6909
movq 0x10(%r15), %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x6c27
leaq 0x18(%rbx), %r12
movq %r14, %rdi
movq %r12, %rsi
movl $0x1, %edx
callq 0x7eaf
movq 0x18(%rbx), %rax
leaq 0x1(%rax), %rcx
movq %rcx, 0x18(%rbx)
movb $0xa, (%rax)
movq 0x18(%rbx), %r13
movq %r14, %rdi
movq %r12, %rsi
movl $0x2, %edx
callq 0x7eaf
movq 0x18(%rbx), %rax
leaq 0x1(%rax), %rcx
movq %rcx, 0x18(%rbx)
xorl %ecx, %ecx
movb %cl, (%rax)
movq 0x18(%rbx), %rax
leaq 0x1(%rax), %rdx
movq %rdx, 0x18(%rbx)
movb %cl, (%rax)
movb 0x1a30(%rbx), %al
movzbl 0x1a33(%rbx), %ecx
leal 0x1(%rcx), %edx
movb %dl, 0x1a33(%rbx)
movb %al, 0x1930(%rbx,%rcx)
movq 0x18(%r15), %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x6526
movb 0x1a30(%rbx), %al
cmpb %al, 0x1a31(%rbx)
jae 0x6706
movb %al, 0x1a31(%rbx)
movb 0x1a33(%rbx), %al
decb %al
movb %al, 0x1a33(%rbx)
movzbl %al, %eax
movb 0x1930(%rbx,%rax), %al
movb %al, 0x1a30(%rbx)
cmpq $0x0, 0x20(%r15)
je 0x6b69
movq %r14, %rdi
movq %r12, %rsi
movl $0x1, %edx
callq 0x7eaf
movq 0x18(%rbx), %rax
leaq 0x1(%rax), %rcx
movq %rcx, 0x18(%rbx)
movb $0x8, (%rax)
movq 0x18(%rbx), %rax
movq %rax, -0x30(%rbp)
movq %r14, %rdi
movq %r12, %rsi
movl $0x2, %edx
callq 0x7eaf
movq 0x18(%rbx), %rax
leaq 0x1(%rax), %rcx
movq %rcx, 0x18(%rbx)
xorl %ecx, %ecx
movb %cl, (%rax)
movq 0x18(%rbx), %rax
leaq 0x1(%rax), %rdx
movq %rdx, 0x18(%rbx)
movb %cl, (%rax)
movl 0x18(%rbx), %eax
subl %r13d, %eax
addl $-0x2, %eax
movw %ax, (%r13)
movb 0x1a30(%rbx), %al
movzbl 0x1a33(%rbx), %ecx
leal 0x1(%rcx), %edx
movb %dl, 0x1a33(%rbx)
movb %al, 0x1930(%rbx,%rcx)
movq 0x20(%r15), %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x6526
movb 0x1a30(%rbx), %al
cmpb %al, 0x1a31(%rbx)
jae 0x67d2
movb %al, 0x1a31(%rbx)
movb 0x1a33(%rbx), %al
decb %al
movb %al, 0x1a33(%rbx)
movzbl %al, %eax
movb 0x1930(%rbx,%rax), %al
movb %al, 0x1a30(%rbx)
movl 0x18(%rbx), %eax
movq -0x30(%rbp), %rcx
subl %ecx, %eax
addl $-0x2, %eax
movw %ax, (%rcx)
jmp 0x6bf9
movb 0x1a30(%rbx), %al
movzbl 0x1a33(%rbx), %ecx
leal 0x1(%rcx), %edx
movb %dl, 0x1a33(%rbx)
movb %al, 0x1930(%rbx,%rcx)
movq 0x10(%r15), %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x6c27
leaq 0x18(%rbx), %r12
movq 0x18(%rbx), %rax
movq %rax, -0x30(%rbp)
movq 0x18(%r15), %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x6c27
movq %r14, %rdi
movq %r12, %rsi
movl $0x1, %edx
callq 0x7eaf
movq 0x18(%rbx), %rax
leaq 0x1(%rax), %rcx
movq %rcx, 0x18(%rbx)
movb $0xa, (%rax)
movq 0x18(%rbx), %r13
movq %r14, %rdi
movq %r12, %rsi
movl $0x2, %edx
callq 0x7eaf
movq 0x18(%rbx), %rax
leaq 0x1(%rax), %rcx
movq %rcx, 0x18(%rbx)
xorl %ecx, %ecx
movb %cl, (%rax)
movq 0x18(%rbx), %rax
leaq 0x1(%rax), %rdx
movq %rdx, 0x18(%rbx)
movb %cl, (%rax)
movb 0x1a30(%rbx), %al
movzbl 0x1a33(%rbx), %ecx
leal 0x1(%rcx), %edx
movb %dl, 0x1a33(%rbx)
movb %al, 0x1930(%rbx,%rcx)
movq 0x28(%r15), %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x6526
movb 0x1a30(%rbx), %al
cmpb %al, 0x1a31(%rbx)
jae 0x68dc
movb %al, 0x1a31(%rbx)
movb 0x1a33(%rbx), %al
decb %al
movb %al, 0x1a33(%rbx)
movzbl %al, %eax
movb 0x1930(%rbx,%rax), %al
movb %al, 0x1a30(%rbx)
movq 0x20(%r15), %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x6c27
movq -0x30(%rbp), %rax
subl 0x18(%rbx), %eax
addl $-0x3, %eax
movq %rax, %r15
movq %r14, %rdi
movq %r12, %rsi
movl $0x1, %edx
callq 0x7eaf
movq 0x18(%rbx), %rax
leaq 0x1(%rax), %rcx
movq %rcx, 0x18(%rbx)
movb $0x8, (%rax)
movq %r14, %rdi
movq %r12, %rsi
movl $0x2, %edx
callq 0x7eaf
movq 0x18(%rbx), %rax
leaq 0x1(%rax), %rcx
movq %rcx, 0x18(%rbx)
movq %r15, %rdx
movb %dl, (%rax)
movq 0x18(%rbx), %rax
leaq 0x1(%rax), %rcx
movq %rcx, 0x18(%rbx)
movb %dh, (%rax)
movl 0x18(%rbx), %eax
subl %r13d, %eax
addl $-0x2, %eax
movw %ax, (%r13)
movb 0x1a30(%rbx), %al
cmpb %al, 0x1a31(%rbx)
jae 0x6986
movb %al, 0x1a31(%rbx)
movb 0x1a33(%rbx), %al
decb %al
movb %al, 0x1a33(%rbx)
movzbl %al, %eax
movb 0x1930(%rbx,%rax), %al
movb %al, 0x1a30(%rbx)
jmp 0x6bf9
movb 0x1a30(%rbx), %al
movzbl 0x1a33(%rbx), %ecx
leal 0x1(%rcx), %edx
movb %dl, 0x1a33(%rbx)
movb %al, 0x1930(%rbx,%rcx)
movq 0x10(%r15), %r15
testq %r15, %r15
je 0x6972
movq %r14, %rdi
movq %rbx, %rsi
movq %r15, %rdx
callq 0x6526
movq 0x8(%r15), %r15
jmp 0x69ca
movq 0x10(%r15), %rdx
testq %rdx, %rdx
je 0x6b85
cmpl $0xb, (%rdx)
jne 0x6b7a
movq 0x10(%rbx), %rcx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x7374
jmp 0x6b85
leaq 0x18(%rbx), %r12
movq 0x18(%rbx), %r13
movb 0x1a30(%rbx), %al
movzbl 0x1a33(%rbx), %ecx
leal 0x1(%rcx), %edx
movb %dl, 0x1a33(%rbx)
movb %al, 0x1930(%rbx,%rcx)
movq 0x10(%r15), %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x6526
movb 0x1a30(%rbx), %al
cmpb %al, 0x1a31(%rbx)
jae 0x6a55
movb %al, 0x1a31(%rbx)
movb 0x1a33(%rbx), %al
decb %al
movb %al, 0x1a33(%rbx)
movzbl %al, %eax
movb 0x1930(%rbx,%rax), %al
movb %al, 0x1a30(%rbx)
movq 0x18(%r15), %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x6c27
movq %r14, %rdi
movq %r12, %rsi
movl $0x1, %edx
callq 0x7eaf
movq 0x18(%rbx), %rax
leaq 0x1(%rax), %rcx
movq %rcx, 0x18(%rbx)
movb $0x9, (%rax)
subl 0x18(%rbx), %r13d
addl $-0x2, %r13d
movq %r14, %rdi
movq %r12, %rsi
movl $0x2, %edx
callq 0x7eaf
movq 0x18(%rbx), %rax
leaq 0x1(%rax), %rcx
movq %rcx, 0x18(%rbx)
movq %r13, %rdx
movb %dl, (%rax)
movq 0x18(%rbx), %rax
leaq 0x1(%rax), %rcx
movq %rcx, 0x18(%rbx)
movb %dh, (%rax)
jmp 0x6bf9
movq 0x18(%r15), %rcx
leaq 0x130(%rbx), %rax
movzbl 0x1a30(%rbx), %edx
testq %rdx, %rdx
je 0x6b14
leal (,%rdx,8), %esi
leaq (%rsi,%rsi,2), %rsi
xorl %edi, %edi
cmpq %rcx, (%rax,%rdi)
je 0x6c08
addq $0x18, %rdi
cmpq %rdi, %rsi
jne 0x6b01
leal 0x1(%rdx), %esi
movb %sil, 0x1a30(%rbx)
leaq (%rdx,%rdx,2), %rsi
movq %rcx, (%rax,%rsi,8)
movq 0x10(%r15), %rcx
movq 0x8(%rcx), %rcx
movq %rcx, 0x8(%rax,%rsi,8)
movb 0x1a32(%rbx), %dil
subb %dil, %dl
movb %dl, 0x10(%rax,%rsi,8)
movb $0x0, 0x11(%rax,%rsi,8)
movq 0x20(%r15), %rdx
testq %rdx, %rdx
je 0x6bf9
leaq (%rax,%rsi,8), %r12
cmpl $0xb, (%rdx)
jne 0x6ba7
movq %r14, %rdi
movq %rbx, %rsi
callq 0x7374
jmp 0x6bb2
movl (%r12), %eax
subl %r13d, %eax
addl $-0x2, %eax
movw %ax, (%r13)
jmp 0x6bf9
movq %r14, %rdi
movq %rbx, %rsi
callq 0x6c27
leaq 0x18(%rbx), %rsi
movq %r14, %rdi
movl $0x1, %edx
callq 0x7eaf
movq 0x18(%rbx), %rax
leaq 0x1(%rax), %rcx
movq %rcx, 0x18(%rbx)
movb $0xb, (%rax)
jmp 0x6bf9
movq %r14, %rdi
movq %rbx, %rsi
callq 0x6c27
leaq 0x18(%rbx), %r15
movq %r14, %rdi
movq %r15, %rsi
movl $0x1, %edx
callq 0x7eaf
movq 0x18(%rbx), %rax
leaq 0x1(%rax), %rcx
movq %rcx, 0x18(%rbx)
movb $0x4, (%rax)
movb 0x10(%r12), %r12b
movq %r14, %rdi
movq %r15, %rsi
movl $0x1, %edx
callq 0x7eaf
movq 0x18(%rbx), %rax
leaq 0x1(%rax), %rcx
movq %rcx, 0x18(%rbx)
movb %r12b, (%rax)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x3881(%rip), %rdi      # 0xa490
leaq 0x383c(%rip), %rsi      # 0xa452
leaq 0x38a0(%rip), %rcx      # 0xa4bd
movl $0x29d, %edx            # imm = 0x29D
callq 0x3120