// File: /workspace/github_c_makefile_star2_O0/vtereshkov[P]umka-lang/src/umka_decl.c
// Function: parseFnDecl
static void parseFnDecl(Compiler *comp)
{
    if (comp->blocks.top != 0)
        comp->error.handler(comp->error.context, "Nested functions should be declared as variables");

    lexEat(&comp->lex, TOK_FN);
    Type *fnType = typeAdd(&comp->types, &comp->blocks, TYPE_FN);

    if (comp->lex.tok.kind == TOK_LPAR)
        parseRcvSignature(comp, &fnType->sig);

    lexCheck(&comp->lex, TOK_IDENT);
    IdentName name;
    strcpy(name, comp->lex.tok.name);

    // Check for method/field name collision
    if (fnType->sig.isMethod)
    {
        const Type *rcvBaseType = fnType->sig.param[0]->type->base;

        if (rcvBaseType->kind == TYPE_STRUCT && typeFindField(rcvBaseType, name, NULL))
            comp->error.handler(comp->error.context, "Structure already has field %s", name);
    }

    lexNext(&comp->lex);
    bool exported = parseExportMark(comp);

    parseSignature(comp, &fnType->sig);

    Const constant = {.intVal = comp->gen.ip};
    Ident *fn = identAddConst(&comp->idents, &comp->modules, &comp->blocks, name, fnType, exported, constant);

    if (comp->lex.tok.kind == TOK_LBRACE)
        parseFnBlock(comp, fn, NULL);
    else
        parseFnPrototype(comp, fn);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x140, %rsp            # imm = 0x140
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
cmpl $0x0, 0x4b84(%rax)
je 0xadbd
movq -0x8(%rbp), %rax
movq 0x50f8(%rax), %rcx
movq -0x8(%rbp), %rax
movq 0x5118(%rax), %rdi
leaq 0x1cd6ec(%rip), %rsi    # 0x1d84a5
movb $0x0, %al
callq *%rcx
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
movl $0x8, %esi
callq 0x1b150
movq -0x8(%rbp), %rdi
addq $0x4e18, %rdi           # imm = 0x4E18
movq -0x8(%rbp), %rsi
addq $0x4220, %rsi           # imm = 0x4220
movl $0x1a, %edx
callq 0x21950
movq %rax, -0x10(%rbp)
movq -0x8(%rbp), %rax
cmpl $0x38, 0x4bd0(%rax)
jne 0xae14
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x28, %rsi
callq 0xc690
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
movl $0x45, %esi
callq 0x1b080
leaq -0x110(%rbp), %rdi
movq -0x8(%rbp), %rsi
addq $0x4ba8, %rsi           # imm = 0x4BA8
addq $0x28, %rsi
addq $0x8, %rsi
callq 0x30a0
movq -0x10(%rbp), %rax
testb $0x1, 0x30(%rax)
je 0xaebf
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movq 0x108(%rax), %rax
movq 0x8(%rax), %rax
movq %rax, -0x118(%rbp)
movq -0x118(%rbp), %rax
cmpl $0x16, (%rax)
jne 0xaebd
movq -0x118(%rbp), %rdi
leaq -0x110(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0x22ee0
cmpq $0x0, %rax
je 0xaebd
movq -0x8(%rbp), %rax
movq 0x50f8(%rax), %rcx
movq -0x8(%rbp), %rax
movq 0x5118(%rax), %rdi
leaq -0x110(%rbp), %rdx
leaq 0x1cd61d(%rip), %rsi    # 0x1d84d6
movb $0x0, %al
callq *%rcx
jmp 0xaebf
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
callq 0x1ad90
movq -0x8(%rbp), %rdi
callq 0xbe90
andb $0x1, %al
movb %al, -0x119(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x28, %rsi
callq 0xb940
movq -0x8(%rbp), %rax
movslq 0x4e78(%rax), %rax
movq %rax, -0x128(%rbp)
movq -0x8(%rbp), %rdi
addq $0x4e38, %rdi           # imm = 0x4E38
movq -0x8(%rbp), %rsi
addq $0x100, %rsi            # imm = 0x100
movq -0x8(%rbp), %rdx
addq $0x4220, %rdx           # imm = 0x4220
leaq -0x110(%rbp), %rcx
movq -0x10(%rbp), %r8
movb -0x119(%rbp), %r9b
movq -0x128(%rbp), %rax
andb $0x1, %r9b
movzbl %r9b, %r9d
movq %rax, (%rsp)
callq 0x19a90
movq %rax, -0x130(%rbp)
movq -0x8(%rbp), %rax
cmpl $0x3c, 0x4bd0(%rax)
jne 0xaf78
movq -0x8(%rbp), %rdi
movq -0x130(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0x1e5b0
jmp 0xaf88
movq -0x8(%rbp), %rdi
movq -0x130(%rbp), %rsi
callq 0x1ec90
addq $0x140, %rsp            # imm = 0x140
popq %rbp
retq
nopw %cs:(%rax,%rax)