// File: /workspace/github_c_makefile_star2_O0/vtereshkov[P]umka-lang/src/umka_stmt.c
// Function: parseSingleAssignmentStmt
static void parseSingleAssignmentStmt(Compiler *comp, const Type *type, Const *varPtrConst)
{
    if (!typeStructured(type))
    {
        if (type->kind != TYPE_PTR || type->base->kind == TYPE_VOID)
            comp->error.handler(comp->error.context, "Left side cannot be assigned to");
        type = type->base;
    }

    const Type *rightType = type;
    Const rightConstantBuf, *rightConstant = varPtrConst ? &rightConstantBuf : NULL;

    parseExpr(comp, &rightType, rightConstant);

    if (typeExprListStruct(rightType))
        comp->error.handler(comp->error.context, "1 expression expected but %d found", rightType->numItems);

    doAssertImplicitTypeConv(comp, type, &rightType, rightConstant);

    if (varPtrConst)                                // Initialize global variable
        constAssign(&comp->consts, varPtrConst->ptrVal, rightConstant, type->kind, typeSize(&comp->types, type));
    else                                            // Assign to variable
    {
        if (doTryRemoveCopyResultToTempVar(comp))
        {
            // Optimization: if the right-hand side is a function call, assume its reference count to be already increased before return
            // The left-hand side will hold this additional reference, so we can remove the temporary "reference holder" variable
            genChangeLeftRefCntAssign(&comp->gen, type);

        }
        else
        {
            // General case: update reference counts for both sides
            genChangeRefCntAssign(&comp->gen, type);
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x10(%rbp), %rdi
callq 0x1ecf0
testb $0x1, %al
jne 0x1de24
movq -0x10(%rbp), %rax
cmpl $0x10, (%rax)
jne 0x1ddf7
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
cmpl $0x2, (%rax)
jne 0x1de18
movq -0x8(%rbp), %rax
movq 0x50f8(%rax), %rcx
movq -0x8(%rbp), %rax
movq 0x5118(%rax), %rdi
leaq 0x1bbc61(%rip), %rsi    # 0x1d9a75
movb $0x0, %al
callq *%rcx
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x18(%rbp)
je 0x1de3d
leaq -0x28(%rbp), %rax
movq %rax, -0x38(%rbp)
jmp 0x1de45
xorl %eax, %eax
movq %rax, -0x38(%rbp)
jmp 0x1de45
movq -0x38(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rdx
leaq -0x20(%rbp), %rsi
callq 0xe8c0
movq -0x20(%rbp), %rdi
callq 0x1da10
testb $0x1, %al
jne 0x1de6d
jmp 0x1de95
movq -0x8(%rbp), %rax
movq 0x50f8(%rax), %rcx
movq -0x8(%rbp), %rax
movq 0x5118(%rax), %rdi
movq -0x20(%rbp), %rax
movl 0x10(%rax), %edx
leaq 0x1bbc29(%rip), %rsi    # 0x1d9aba
movb $0x0, %al
callq *%rcx
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x30(%rbp), %rcx
leaq -0x20(%rbp), %rdx
callq 0xd6e0
cmpq $0x0, -0x18(%rbp)
je 0x1df08
movq -0x8(%rbp), %rax
addq $0x4e68, %rax           # imm = 0x4E68
movq %rax, -0x58(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x10(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x3c(%rbp)
movq -0x8(%rbp), %rdi
addq $0x4e18, %rdi           # imm = 0x4E18
movq -0x10(%rbp), %rsi
callq 0x21fe0
movq -0x58(%rbp), %rdi
movq -0x50(%rbp), %rsi
movq -0x48(%rbp), %rdx
movl -0x3c(%rbp), %ecx
movl %eax, %r8d
callq 0x88c0
jmp 0x1df43
movq -0x8(%rbp), %rdi
callq 0xd0f0
testb $0x1, %al
jne 0x1df17
jmp 0x1df2d
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movq -0x10(%rbp), %rsi
callq 0x17590
jmp 0x1df41
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movq -0x10(%rbp), %rsi
callq 0x17470
jmp 0x1df43
addq $0x60, %rsp
popq %rbp
retq
nopl (%rax)