// File: /workspace/github_c_makefile_star2_O0/vtereshkov[P]umka-lang/src/umka_stmt.c
// Function: parseListAssignmentStmt
static void parseListAssignmentStmt(Compiler *comp, const Type *type, Const *varPtrConstList)
{
    Type *derefLeftListType = typeAdd(&comp->types, &comp->blocks, TYPE_STRUCT);
    derefLeftListType->isExprList = true;

    for (int i = 0; i < type->numItems; i++)
    {
        const Type *leftType = type->field[i]->type;
        if (!typeStructured(leftType))
        {
            if (leftType->kind != TYPE_PTR || leftType->base->kind == TYPE_VOID)
                comp->error.handler(comp->error.context, "Left side cannot be assigned to");
            leftType = leftType->base;
        }
        typeAddField(&comp->types, derefLeftListType, leftType, NULL);
    }

    const Type *rightListType = derefLeftListType;
    Const rightListConstantBuf, *rightListConstant = varPtrConstList ? &rightListConstantBuf : NULL;
    parseExprList(comp, &rightListType, rightListConstant);

    const int numExpr = typeExprListStruct(rightListType) ? rightListType->numItems : 1;
    if (numExpr != type->numItems)
        comp->error.handler(comp->error.context, "%d expressions expected but %d found", type->numItems, numExpr);

    for (int i = type->numItems - 1; i >= 0; i--)
    {
        const Type *leftType = derefLeftListType->field[i]->type;
        const Type *rightType = rightListType->field[i]->type;

        if (varPtrConstList)                                // Initialize global variables
        {
            Const rightConstantBuf = {.ptrVal = (char *)rightListConstant->ptrVal + rightListType->field[i]->offset};
            constDeref(&comp->consts, &rightConstantBuf, rightType->kind);

            doAssertImplicitTypeConv(comp, leftType, &rightType, &rightConstantBuf);

            constAssign(&comp->consts, varPtrConstList[i].ptrVal, &rightConstantBuf, leftType->kind, typeSize(&comp->types, leftType));
        }
        else                                                // Assign to variable
        {
            genDup(&comp->gen);                                             // Duplicate expression list pointer
            genPopReg(&comp->gen, REG_EXPR_LIST);                           // Save expression list pointer
            genGetFieldPtr(&comp->gen, rightListType->field[i]->offset);    // Get expression pointer
            genDeref(&comp->gen, rightType->kind);                          // Get expression value

            doAssertImplicitTypeConv(comp, leftType, &rightType, NULL);

            genChangeRefCntAssign(&comp->gen, leftType);                    // Assign expression to variable
            genPushReg(&comp->gen, REG_EXPR_LIST);                          // Restore expression list pointer
        }
    }

    if (!varPtrConstList)
        genPop(&comp->gen);                                                 // Remove expression list pointer
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
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, -0x20(%rbp)
movq -0x20(%rbp), %rax
movb $0x1, 0x14(%rax)
movl $0x0, -0x24(%rbp)
movl -0x24(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x10(%rcx), %eax
jge 0x1db3f
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x108(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rdi
callq 0x1ecf0
testb $0x1, %al
jne 0x1db15
movq -0x30(%rbp), %rax
cmpl $0x10, (%rax)
jne 0x1dae8
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
cmpl $0x2, (%rax)
jne 0x1db09
movq -0x8(%rbp), %rax
movq 0x50f8(%rax), %rcx
movq -0x8(%rbp), %rax
movq 0x5118(%rax), %rdi
leaq 0x1bbf70(%rip), %rsi    # 0x1d9a75
movb $0x0, %al
callq *%rcx
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rdi
addq $0x4e18, %rdi           # imm = 0x4E18
movq -0x20(%rbp), %rsi
movq -0x30(%rbp), %rdx
xorl %eax, %eax
movl %eax, %ecx
callq 0x23070
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x1da9a
movq -0x20(%rbp), %rax
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x18(%rbp)
je 0x1db58
leaq -0x40(%rbp), %rax
movq %rax, -0x70(%rbp)
jmp 0x1db60
xorl %eax, %eax
movq %rax, -0x70(%rbp)
jmp 0x1db60
movq -0x70(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x8(%rbp), %rdi
movq -0x48(%rbp), %rdx
leaq -0x38(%rbp), %rsi
callq 0xeea0
movq -0x38(%rbp), %rdi
callq 0x1da10
testb $0x1, %al
jne 0x1db88
jmp 0x1db94
movq -0x38(%rbp), %rax
movl 0x10(%rax), %eax
movl %eax, -0x74(%rbp)
jmp 0x1db9e
movl $0x1, %eax
movl %eax, -0x74(%rbp)
jmp 0x1db9e
movl -0x74(%rbp), %eax
movl %eax, -0x4c(%rbp)
movl -0x4c(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x10(%rcx), %eax
je 0x1dbdc
movq -0x8(%rbp), %rax
movq 0x50f8(%rax), %r8
movq -0x8(%rbp), %rax
movq 0x5118(%rax), %rdi
movq -0x10(%rbp), %rax
movl 0x10(%rax), %edx
movl -0x4c(%rbp), %ecx
leaq 0x1bbebe(%rip), %rsi    # 0x1d9a95
movb $0x0, %al
callq *%r8
movq -0x10(%rbp), %rax
movl 0x10(%rax), %eax
subl $0x1, %eax
movl %eax, -0x50(%rbp)
cmpl $0x0, -0x50(%rbp)
jl 0x1dd94
movq -0x20(%rbp), %rax
movq 0x28(%rax), %rax
movslq -0x50(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x108(%rax), %rax
movq %rax, -0x58(%rbp)
movq -0x38(%rbp), %rax
movq 0x28(%rax), %rax
movslq -0x50(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x108(%rax), %rax
movq %rax, -0x60(%rbp)
cmpq $0x0, -0x18(%rbp)
je 0x1dce5
movq -0x48(%rbp), %rax
movq (%rax), %rax
movq -0x38(%rbp), %rcx
movq 0x28(%rcx), %rcx
movslq -0x50(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
movslq 0x110(%rcx), %rcx
addq %rcx, %rax
movq %rax, -0x68(%rbp)
movq -0x8(%rbp), %rdi
addq $0x4e68, %rdi           # imm = 0x4E68
movq -0x60(%rbp), %rax
movl (%rax), %edx
leaq -0x68(%rbp), %rsi
callq 0x86b0
movq -0x8(%rbp), %rdi
movq -0x58(%rbp), %rsi
leaq -0x60(%rbp), %rdx
leaq -0x68(%rbp), %rcx
callq 0xd6e0
movq -0x8(%rbp), %rax
addq $0x4e68, %rax           # imm = 0x4E68
movq %rax, -0x88(%rbp)
movq -0x18(%rbp), %rax
movslq -0x50(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x80(%rbp)
movq -0x58(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x78(%rbp)
movq -0x8(%rbp), %rdi
addq $0x4e18, %rdi           # imm = 0x4E18
movq -0x58(%rbp), %rsi
callq 0x21fe0
movq -0x88(%rbp), %rdi
movq -0x80(%rbp), %rsi
movl -0x78(%rbp), %ecx
movl %eax, %r8d
leaq -0x68(%rbp), %rdx
callq 0x88c0
jmp 0x1dd84
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
callq 0x16eb0
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movl $0x4, %esi
callq 0x16df0
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movq -0x38(%rbp), %rax
movq 0x28(%rax), %rax
movslq -0x50(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movl 0x110(%rax), %esi
callq 0x17bb0
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movq -0x60(%rbp), %rax
movl (%rax), %esi
callq 0x16fa0
movq -0x8(%rbp), %rdi
movq -0x58(%rbp), %rsi
leaq -0x60(%rbp), %rdx
xorl %eax, %eax
movl %eax, %ecx
callq 0xd6e0
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movq -0x58(%rbp), %rsi
callq 0x17470
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movl $0x4, %esi
callq 0x16b60
jmp 0x1dd86
movl -0x50(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x50(%rbp)
jmp 0x1dbe9
cmpq $0x0, -0x18(%rbp)
jne 0x1ddab
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
callq 0x16d30
addq $0x90, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)