// File: /workspace/github_c_makefile_star2_O0/vtereshkov[P]umka-lang/src/umka_decl.c
// Function: parseSignature
static void parseSignature(Compiler *comp, Signature *sig)
{
    // Dummy hidden parameter that allows any function to be converted to a closure
    if (!sig->isMethod)
        typeAddParam(&comp->types, sig, comp->anyType, "#upvalues", (Const){0});

    // Formal parameter list
    lexEat(&comp->lex, TOK_LPAR);
    int numDefaultParams = 0;

    if (comp->lex.tok.kind == TOK_IDENT)
    {
        bool variadicParamListFound = false;
        while (1)
        {
            if (variadicParamListFound)
                comp->error.handler(comp->error.context, "Variadic parameter list should be the last parameter");

            IdentName paramNames[MAX_PARAMS];
            bool paramExported[MAX_PARAMS];
            const Type *paramType = NULL;
            int numParams = 0;
            parseTypedIdentList(comp, paramNames, paramExported, MAX_PARAMS, &numParams, &paramType, true);

            variadicParamListFound = paramType->isVariadicParamList;

            // ["=" expr]
            Const defaultConstant = {0};
            if (comp->lex.tok.kind == TOK_EQ)
            {
                if (numParams != 1)
                    comp->error.handler(comp->error.context, "Parameter list cannot have common default value");

                if (paramType->isVariadicParamList)
                    comp->error.handler(comp->error.context, "Variadic parameter list cannot have default value");

                lexNext(&comp->lex);

                const Type *defaultType = paramType;
                parseExpr(comp, &defaultType, &defaultConstant);
                doAssertImplicitTypeConv(comp, paramType, &defaultType, &defaultConstant);

                numDefaultParams++;
            }
            else
            {
                if (numDefaultParams != 0)
                    comp->error.handler(comp->error.context, "Parameters with default values should be the last ones");
            }

            for (int i = 0; i < numParams; i++)
            {
                if (paramExported[i])
                    comp->error.handler(comp->error.context, "Parameter %s cannot be exported", paramNames[i]);

                typeAddParam(&comp->types, sig, paramType, paramNames[i], defaultConstant);
            }

            if (comp->lex.tok.kind != TOK_COMMA)
                break;
            lexNext(&comp->lex);
        }
    }
    lexEat(&comp->lex, TOK_RPAR);
    sig->numDefaultParams = numDefaultParams;

    // Result type
    if (comp->lex.tok.kind == TOK_COLON)
    {
        lexNext(&comp->lex);
        if (comp->lex.tok.kind == TOK_LPAR)
        {
            // Result type list (syntactic sugar - actually a structure type)
            Type *listType = typeAdd(&comp->types, &comp->blocks, TYPE_STRUCT);
            listType->isExprList = true;

            lexNext(&comp->lex);

            while (1)
            {
                const Type *fieldType = parseType(comp, NULL);
                typeAddField(&comp->types, listType, fieldType, NULL);

                if (comp->lex.tok.kind != TOK_COMMA)
                    break;
                lexNext(&comp->lex);
            }
            lexEat(&comp->lex, TOK_RPAR);

            if (listType->numItems == 1)
                sig->resultType = listType->field[0]->type;
            else
                sig->resultType = listType;
        }
        else
            // Single result type
            sig->resultType = parseType(comp, NULL);
    }
    else
        sig->resultType = comp->voidType;

    // Structured result parameter
    if (typeStructured(sig->resultType))
        typeAddParam(&comp->types, sig, typeAddPtrTo(&comp->types, &comp->blocks, sig->resultType), "#result", (Const){0});
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1090, %rsp           # imm = 0x1090
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x10(%rbp), %rax
testb $0x1, 0x8(%rax)
jne 0xb98f
movq -0x8(%rbp), %rdi
addq $0x4e18, %rdi           # imm = 0x4E18
movq -0x10(%rbp), %rsi
movq -0x8(%rbp), %rax
movq 0x52a8(%rax), %rdx
movq $0x0, -0x18(%rbp)
movq -0x18(%rbp), %r8
leaq 0x1c8a5e(%rip), %rcx    # 0x1d43e8
callq 0x23790
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
movl $0x38, %esi
callq 0x1b150
movl $0x0, -0x1c(%rbp)
movq -0x8(%rbp), %rax
cmpl $0x45, 0x4bd0(%rax)
jne 0xbc13
movb $0x0, -0x1d(%rbp)
testb $0x1, -0x1d(%rbp)
je 0xb9e7
movq -0x8(%rbp), %rax
movq 0x50f8(%rax), %rcx
movq -0x8(%rbp), %rax
movq 0x5118(%rax), %rdi
leaq 0x1cc97e(%rip), %rsi    # 0x1d8361
movb $0x0, %al
callq *%rcx
movq $0x0, -0x1038(%rbp)
movl $0x0, -0x103c(%rbp)
movq -0x8(%rbp), %rdi
leaq -0x1020(%rbp), %rsi
leaq -0x1030(%rbp), %rdx
movl $0x10, %ecx
leaq -0x103c(%rbp), %r8
leaq -0x1038(%rbp), %r9
movl $0x1, (%rsp)
callq 0xb7f0
movq -0x1038(%rbp), %rax
movb 0x15(%rax), %al
andb $0x1, %al
movb %al, -0x1d(%rbp)
leaq -0x1048(%rbp), %rdi
xorl %esi, %esi
movl $0x8, %edx
callq 0x3190
movq -0x8(%rbp), %rax
cmpl $0x31, 0x4bd0(%rax)
jne 0xbb16
cmpl $0x1, -0x103c(%rbp)
je 0xba8a
movq -0x8(%rbp), %rax
movq 0x50f8(%rax), %rcx
movq -0x8(%rbp), %rax
movq 0x5118(%rax), %rdi
leaq 0x1cc910(%rip), %rsi    # 0x1d8396
movb $0x0, %al
callq *%rcx
movq -0x1038(%rbp), %rax
testb $0x1, 0x15(%rax)
je 0xbab8
movq -0x8(%rbp), %rax
movq 0x50f8(%rax), %rcx
movq -0x8(%rbp), %rax
movq 0x5118(%rax), %rdi
leaq 0x1cc912(%rip), %rsi    # 0x1d83c6
movb $0x0, %al
callq *%rcx
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
callq 0x1ad90
movq -0x1038(%rbp), %rax
movq %rax, -0x1050(%rbp)
movq -0x8(%rbp), %rdi
leaq -0x1050(%rbp), %rsi
leaq -0x1048(%rbp), %rdx
callq 0xe8c0
movq -0x8(%rbp), %rdi
movq -0x1038(%rbp), %rsi
leaq -0x1050(%rbp), %rdx
leaq -0x1048(%rbp), %rcx
callq 0xd6e0
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0xbb3f
cmpl $0x0, -0x1c(%rbp)
je 0xbb3d
movq -0x8(%rbp), %rax
movq 0x50f8(%rax), %rcx
movq -0x8(%rbp), %rax
movq 0x5118(%rax), %rdi
leaq 0x1cc8bf(%rip), %rsi    # 0x1d83f8
movb $0x0, %al
callq *%rcx
jmp 0xbb3f
movl $0x0, -0x1054(%rbp)
movl -0x1054(%rbp), %eax
cmpl -0x103c(%rbp), %eax
jge 0xbbed
movslq -0x1054(%rbp), %rax
testb $0x1, -0x1030(%rbp,%rax)
je 0xbba2
movq -0x8(%rbp), %rax
movq 0x50f8(%rax), %rcx
movq -0x8(%rbp), %rax
movq 0x5118(%rax), %rdi
movslq -0x1054(%rbp), %rax
leaq -0x1020(%rbp), %rdx
shlq $0x8, %rax
addq %rax, %rdx
leaq 0x1cc891(%rip), %rsi    # 0x1d842f
movb $0x0, %al
callq *%rcx
movq -0x8(%rbp), %rdi
addq $0x4e18, %rdi           # imm = 0x4E18
movq -0x10(%rbp), %rsi
movq -0x1038(%rbp), %rdx
movslq -0x1054(%rbp), %rax
leaq -0x1020(%rbp), %rcx
shlq $0x8, %rax
addq %rax, %rcx
movq -0x1048(%rbp), %r8
callq 0x23790
movl -0x1054(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1054(%rbp)
jmp 0xbb49
movq -0x8(%rbp), %rax
cmpl $0x3f, 0x4bd0(%rax)
je 0xbbfc
jmp 0xbc11
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
callq 0x1ad90
jmp 0xb9c0
jmp 0xbc13
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
movl $0x39, %esi
callq 0x1b150
movl -0x1c(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x4(%rax)
movq -0x8(%rbp), %rax
cmpl $0x41, 0x4bd0(%rax)
jne 0xbd72
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
callq 0x1ad90
movq -0x8(%rbp), %rax
cmpl $0x38, 0x4bd0(%rax)
jne 0xbd55
movq -0x8(%rbp), %rdi
addq $0x4e18, %rdi           # imm = 0x4E18
movq -0x8(%rbp), %rsi
addq $0x4220, %rsi           # imm = 0x4220
movl $0x16, %edx
callq 0x21950
movq %rax, -0x1060(%rbp)
movq -0x1060(%rbp), %rax
movb $0x1, 0x14(%rax)
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
callq 0x1ad90
movq -0x8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x9b80
movq %rax, -0x1068(%rbp)
movq -0x8(%rbp), %rdi
addq $0x4e18, %rdi           # imm = 0x4E18
movq -0x1060(%rbp), %rsi
movq -0x1068(%rbp), %rdx
xorl %eax, %eax
movl %eax, %ecx
callq 0x23070
movq -0x8(%rbp), %rax
cmpl $0x3f, 0x4bd0(%rax)
je 0xbceb
jmp 0xbcfd
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
callq 0x1ad90
jmp 0xbca6
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
movl $0x39, %esi
callq 0x1b150
movq -0x1060(%rbp), %rax
cmpl $0x1, 0x10(%rax)
jne 0xbd41
movq -0x1060(%rbp), %rax
movq 0x28(%rax), %rax
movq (%rax), %rax
movq 0x108(%rax), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x90(%rax)
jmp 0xbd53
movq -0x1060(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x90(%rax)
jmp 0xbd70
movq -0x8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x9b80
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x90(%rax)
jmp 0xbd88
movq -0x8(%rbp), %rax
movq 0x5218(%rax), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x90(%rax)
movq -0x10(%rbp), %rax
movq 0x90(%rax), %rdi
callq 0xbe20
testb $0x1, %al
jne 0xbd9e
jmp 0xbe0f
movq -0x8(%rbp), %rax
addq $0x4e18, %rax           # imm = 0x4E18
movq %rax, -0x1080(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x1078(%rbp)
movq -0x8(%rbp), %rdi
addq $0x4e18, %rdi           # imm = 0x4E18
movq -0x8(%rbp), %rsi
addq $0x4220, %rsi           # imm = 0x4220
movq -0x10(%rbp), %rax
movq 0x90(%rax), %rdx
callq 0x21fa0
movq -0x1080(%rbp), %rdi
movq -0x1078(%rbp), %rsi
movq %rax, %rdx
movq $0x0, -0x1070(%rbp)
movq -0x1070(%rbp), %r8
leaq 0x1cc645(%rip), %rcx    # 0x1d844f
callq 0x23790
addq $0x1090, %rsp           # imm = 0x1090
popq %rbp
retq
nopl (%rax,%rax)