// File: /workspace/github_c_makefile_star2_O0/vtereshkov[P]umka-lang/src/umka_expr.c
// Function: parseFieldSelector
static void parseFieldSelector(Compiler *comp, const Type **type, bool *isVar, bool *isCall)
{
    // Implicit dereferencing: a^.x == a.x
    doTryImplicitDeref(comp, type);

    // Search for a method
    if ((*type)->kind == TYPE_PTR)
        *type = (*type)->base;
    else if (!typeStructured(*type))
        comp->error.handler(comp->error.context, "Addressable value expected");

    lexNext(&comp->lex);
    lexCheck(&comp->lex, TOK_IDENT);

    const Type *rcvType = *type;
    int rcvTypeModule = rcvType->typeIdent ? rcvType->typeIdent->module : -1;

    rcvType = typeAddPtrTo(&comp->types, &comp->blocks, rcvType);

    const Ident *method = identFind(&comp->idents, &comp->modules, &comp->blocks, rcvTypeModule, comp->lex.tok.name, rcvType, true);
    if (method)
    {
        // Method
        lexNext(&comp->lex);

        // Save concrete method's receiver to dedicated register and push method's entry point
        genPopReg(&comp->gen, REG_SELF);
        doPushConst(comp, method->type, &method->constant);

        *type = method->type;
        *isVar = false;
        *isCall = false;
    }
    else
    {
        // Field
        if ((*type)->kind != TYPE_STRUCT && (*type)->kind != TYPE_INTERFACE)
        {
            char typeBuf[DEFAULT_STR_LEN + 1];
            comp->error.handler(comp->error.context, "Method %s is not defined for %s", comp->lex.tok.name, typeSpelling(*type, typeBuf));
        }

        const Field *field = typeAssertFindField(&comp->types, *type, comp->lex.tok.name, NULL);
        lexNext(&comp->lex);

        genGetFieldPtr(&comp->gen, field->offset);

        // Save interface method's receiver to dedicated register and push method's entry point
        if (field->type->kind == TYPE_FN && field->type->sig.isMethod && field->type->sig.offsetFromSelf != 0)
        {
            genDup(&comp->gen);
            genGetFieldPtr(&comp->gen, -field->type->sig.offsetFromSelf);
            genDeref(&comp->gen, TYPE_PTR);
            genPopReg(&comp->gen, REG_SELF);
        }

        if (typeStructured(field->type))
            *type = field->type;
        else
            *type = typeAddPtrTo(&comp->types, &comp->blocks, field->type);

        *isVar = true;
        *isCall = false;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x170, %rsp            # imm = 0x170
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x15490
movq -0x10(%rbp), %rax
movq (%rax), %rax
cmpl $0x10, (%rax)
jne 0x14fd8
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq 0x8(%rax), %rcx
movq -0x10(%rbp), %rax
movq %rcx, (%rax)
jmp 0x1500b
movq -0x10(%rbp), %rax
movq (%rax), %rdi
callq 0xcfa0
testb $0x1, %al
jne 0x15009
movq -0x8(%rbp), %rax
movq 0x50f8(%rax), %rcx
movq -0x8(%rbp), %rax
movq 0x5118(%rax), %rdi
leaq 0x1c3ef2(%rip), %rsi    # 0x1d8ef7
movb $0x0, %al
callq *%rcx
jmp 0x1500b
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
callq 0x1ad90
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
movl $0x45, %esi
callq 0x1b080
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
cmpq $0x0, 0x18(%rax)
je 0x1505c
movq -0x28(%rbp), %rax
movq 0x18(%rax), %rax
movl 0x110(%rax), %eax
movl %eax, -0x14c(%rbp)
jmp 0x15069
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movl %eax, -0x14c(%rbp)
jmp 0x15069
movl -0x14c(%rbp), %eax
movl %eax, -0x2c(%rbp)
movq -0x8(%rbp), %rdi
addq $0x4e18, %rdi           # imm = 0x4E18
movq -0x8(%rbp), %rsi
addq $0x4220, %rsi           # imm = 0x4220
movq -0x28(%rbp), %rdx
callq 0x21fa0
movq %rax, -0x28(%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
movl -0x2c(%rbp), %ecx
movq -0x8(%rbp), %r8
addq $0x4ba8, %r8            # imm = 0x4BA8
addq $0x28, %r8
addq $0x8, %r8
movq -0x28(%rbp), %r9
movl $0x1, (%rsp)
callq 0x19580
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
je 0x15150
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
callq 0x1ad90
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movl $0x1, %esi
callq 0x16df0
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rax
movq 0x108(%rax), %rsi
movq -0x38(%rbp), %rdx
addq $0x120, %rdx            # imm = 0x120
callq 0xce30
movq -0x38(%rbp), %rax
movq 0x108(%rax), %rcx
movq -0x10(%rbp), %rax
movq %rcx, (%rax)
movq -0x18(%rbp), %rax
movb $0x0, (%rax)
movq -0x20(%rbp), %rax
movb $0x0, (%rax)
jmp 0x1534f
movq -0x10(%rbp), %rax
movq (%rax), %rax
cmpl $0x16, (%rax)
je 0x151e0
movq -0x10(%rbp), %rax
movq (%rax), %rax
cmpl $0x17, (%rax)
je 0x151e0
movq -0x8(%rbp), %rax
movq 0x50f8(%rax), %rax
movq %rax, -0x158(%rbp)
movq -0x8(%rbp), %rax
movq 0x5118(%rax), %rax
movq %rax, -0x168(%rbp)
movq -0x8(%rbp), %rax
addq $0x4ba8, %rax           # imm = 0x4BA8
addq $0x28, %rax
addq $0x8, %rax
movq %rax, -0x160(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rdi
leaq -0x140(%rbp), %rsi
callq 0x22070
movq -0x168(%rbp), %rdi
movq -0x160(%rbp), %rdx
movq -0x158(%rbp), %r8
movq %rax, %rcx
leaq 0x1c3d37(%rip), %rsi    # 0x1d8f12
movb $0x0, %al
callq *%r8
movq -0x8(%rbp), %rdi
addq $0x4e18, %rdi           # imm = 0x4E18
movq -0x10(%rbp), %rax
movq (%rax), %rsi
movq -0x8(%rbp), %rdx
addq $0x4ba8, %rdx           # imm = 0x4BA8
addq $0x28, %rdx
addq $0x8, %rdx
xorl %eax, %eax
movl %eax, %ecx
callq 0x23000
movq %rax, -0x148(%rbp)
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
callq 0x1ad90
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movq -0x148(%rbp), %rax
movl 0x110(%rax), %esi
callq 0x17bb0
movq -0x148(%rbp), %rax
movq 0x108(%rax), %rax
cmpl $0x1a, (%rax)
jne 0x152de
movq -0x148(%rbp), %rax
movq 0x108(%rax), %rax
testb $0x1, 0x30(%rax)
je 0x152de
movq -0x148(%rbp), %rax
movq 0x108(%rax), %rax
cmpl $0x0, 0x34(%rax)
je 0x152de
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
callq 0x16eb0
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movq -0x148(%rbp), %rax
movq 0x108(%rax), %rax
xorl %esi, %esi
subl 0x34(%rax), %esi
callq 0x17bb0
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movl $0x10, %esi
callq 0x16fa0
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movl $0x1, %esi
callq 0x16df0
movq -0x148(%rbp), %rax
movq 0x108(%rax), %rdi
callq 0xcfa0
testb $0x1, %al
jne 0x152f7
jmp 0x1530e
movq -0x148(%rbp), %rax
movq 0x108(%rax), %rcx
movq -0x10(%rbp), %rax
movq %rcx, (%rax)
jmp 0x15341
movq -0x8(%rbp), %rdi
addq $0x4e18, %rdi           # imm = 0x4E18
movq -0x8(%rbp), %rsi
addq $0x4220, %rsi           # imm = 0x4220
movq -0x148(%rbp), %rax
movq 0x108(%rax), %rdx
callq 0x21fa0
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, (%rax)
movq -0x18(%rbp), %rax
movb $0x1, (%rax)
movq -0x20(%rbp), %rax
movb $0x0, (%rax)
addq $0x170, %rsp            # imm = 0x170
popq %rbp
retq
nopl (%rax,%rax)