// File: /workspace/github_c_makefile_star2_O0/vtereshkov[P]umka-lang/src/umka_decl.c
// Function: parseInterfaceType
static const Type *parseInterfaceType(Compiler *comp)
{
    lexEat(&comp->lex, TOK_INTERFACE);
    lexEat(&comp->lex, TOK_LBRACE);

    Type *type = typeAdd(&comp->types, &comp->blocks, TYPE_INTERFACE);

    // The interface type is the Umka equivalent of Interface + methods
    typeAddField(&comp->types, type, comp->ptrVoidType, "#self");
    typeAddField(&comp->types, type, comp->ptrVoidType, "#selftype");

    // Method names and signatures, or embedded interfaces
    while (comp->lex.tok.kind == TOK_IDENT)
    {
        Lexer lookaheadLex = comp->lex;
        lexNext(&lookaheadLex);

        if (lookaheadLex.tok.kind == TOK_LPAR)
        {
            // Method name and signature
            IdentName methodName;
            strcpy(methodName, comp->lex.tok.name);
            lexNext(&comp->lex);

            Type *methodType = typeAdd(&comp->types, &comp->blocks, TYPE_FN);
            methodType->sig.isMethod = true;

            typeAddParam(&comp->types, &methodType->sig, comp->ptrVoidType, "#self", (Const){0});
            parseSignature(comp, &methodType->sig);

            const Field *method = typeAddField(&comp->types, type, methodType, methodName);
            methodType->sig.offsetFromSelf = method->offset;
        }
        else
        {
            // Embedded interface
            const Type *embeddedType = parseType(comp, NULL);

            if (embeddedType->kind != TYPE_INTERFACE)
                comp->error.handler(comp->error.context, "Interface type expected");

            for (int i = 2; i < embeddedType->numItems; i++)    // Skip #self and #selftype in embedded interface
            {
                Type *methodType = typeAdd(&comp->types, &comp->blocks, TYPE_FN);
                typeDeepCopy(&comp->storage, methodType, embeddedType->field[i]->type);

                const Field *method = typeAddField(&comp->types, type, methodType, embeddedType->field[i]->name);
                methodType->sig.isMethod = true;
                methodType->sig.offsetFromSelf = method->offset;
            }
        }

        lexEat(&comp->lex, TOK_SEMICOLON);
    }
    lexEat(&comp->lex, TOK_RBRACE);
    return type;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x3c0, %rsp            # imm = 0x3C0
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
movl $0xb, %esi
callq 0x1b150
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
movl $0x3c, %esi
callq 0x1b150
movq -0x8(%rbp), %rdi
addq $0x4e18, %rdi           # imm = 0x4E18
movq -0x8(%rbp), %rsi
addq $0x4220, %rsi           # imm = 0x4220
movl $0x17, %edx
callq 0x21950
movq %rax, -0x10(%rbp)
movq -0x8(%rbp), %rdi
addq $0x4e18, %rdi           # imm = 0x4E18
movq -0x10(%rbp), %rsi
movq -0x8(%rbp), %rax
movq 0x5298(%rax), %rdx
leaq 0x1c9e8a(%rip), %rcx    # 0x1d43d8
callq 0x23070
movq -0x8(%rbp), %rdi
addq $0x4e18, %rdi           # imm = 0x4E18
movq -0x10(%rbp), %rsi
movq -0x8(%rbp), %rax
movq 0x5298(%rax), %rdx
leaq 0x1c9e6a(%rip), %rcx    # 0x1d43de
callq 0x23070
movq -0x8(%rbp), %rax
cmpl $0x45, 0x4bd0(%rax)
jne 0xa7fe
movq -0x8(%rbp), %rsi
addq $0x4ba8, %rsi           # imm = 0x4BA8
leaq -0x280(%rbp), %rdi
movl $0x270, %edx            # imm = 0x270
callq 0x3270
leaq -0x280(%rbp), %rdi
callq 0x1ad90
cmpl $0x38, -0x258(%rbp)
jne 0xa6b8
leaq -0x380(%rbp), %rdi
movq -0x8(%rbp), %rsi
addq $0x4ba8, %rsi           # imm = 0x4BA8
addq $0x28, %rsi
addq $0x8, %rsi
callq 0x30a0
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
callq 0x1ad90
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, -0x388(%rbp)
movq -0x388(%rbp), %rax
movb $0x1, 0x30(%rax)
movq -0x8(%rbp), %rdi
addq $0x4e18, %rdi           # imm = 0x4E18
movq -0x388(%rbp), %rsi
addq $0x28, %rsi
movq -0x8(%rbp), %rax
movq 0x5298(%rax), %rdx
movq $0x0, -0x390(%rbp)
movq -0x390(%rbp), %r8
leaq 0x1c9d7e(%rip), %rcx    # 0x1d43d8
callq 0x23790
movq -0x8(%rbp), %rdi
movq -0x388(%rbp), %rsi
addq $0x28, %rsi
callq 0xb940
movq -0x8(%rbp), %rdi
addq $0x4e18, %rdi           # imm = 0x4E18
movq -0x10(%rbp), %rsi
movq -0x388(%rbp), %rdx
leaq -0x380(%rbp), %rcx
callq 0x23070
movq %rax, -0x398(%rbp)
movq -0x398(%rbp), %rax
movl 0x110(%rax), %ecx
movq -0x388(%rbp), %rax
movl %ecx, 0x34(%rax)
jmp 0xa7e4
movq -0x8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x9b80
movq %rax, -0x3a0(%rbp)
movq -0x3a0(%rbp), %rax
cmpl $0x17, (%rax)
je 0xa6f9
movq -0x8(%rbp), %rax
movq 0x50f8(%rax), %rcx
movq -0x8(%rbp), %rax
movq 0x5118(%rax), %rdi
leaq 0x1cdc54(%rip), %rsi    # 0x1d8349
movb $0x0, %al
callq *%rcx
movl $0x2, -0x3a4(%rbp)
movl -0x3a4(%rbp), %eax
movq -0x3a0(%rbp), %rcx
cmpl 0x10(%rcx), %eax
jge 0xa7e2
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, -0x3b0(%rbp)
movq -0x8(%rbp), %rdi
addq $0xf0, %rdi
movq -0x3b0(%rbp), %rsi
movq -0x3a0(%rbp), %rax
movq 0x28(%rax), %rax
movslq -0x3a4(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x108(%rax), %rdx
callq 0x21d40
movq -0x8(%rbp), %rdi
addq $0x4e18, %rdi           # imm = 0x4E18
movq -0x10(%rbp), %rsi
movq -0x3b0(%rbp), %rdx
movq -0x3a0(%rbp), %rax
movq 0x28(%rax), %rax
movslq -0x3a4(%rbp), %rcx
movq (%rax,%rcx,8), %rcx
callq 0x23070
movq %rax, -0x3b8(%rbp)
movq -0x3b0(%rbp), %rax
movb $0x1, 0x30(%rax)
movq -0x3b8(%rbp), %rax
movl 0x110(%rax), %ecx
movq -0x3b0(%rbp), %rax
movl %ecx, 0x34(%rax)
movl -0x3a4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3a4(%rbp)
jmp 0xa703
jmp 0xa7e4
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
movl $0x40, %esi
callq 0x1b150
jmp 0xa579
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
movl $0x3d, %esi
callq 0x1b150
movq -0x10(%rbp), %rax
addq $0x3c0, %rsp            # imm = 0x3C0
popq %rbp
retq