// File: /workspace/github_c_makefile_star2_O0/vtereshkov[P]umka-lang/src/umka_stmt.c
// Function: parseListDeclAssignmentStmt
static void parseListDeclAssignmentStmt(Compiler *comp, IdentName *names, const bool *exported, int num, bool constExpr)
{
    const Type *rightListType = NULL;
    Const rightListConstantBuf, *rightListConstant = constExpr ? &rightListConstantBuf : NULL;
    parseExprList(comp, &rightListType, rightListConstant);

    const int numExpr = typeExprListStruct(rightListType) ? rightListType->numItems : 1;
    if (numExpr != num)
        comp->error.handler(comp->error.context, "%d expressions expected but %d found", num, numExpr);

    bool newVarFound = false;

    for (int i = 0; i < num; i++)
    {
        const Type *rightType = rightListType->field[i]->type;

        bool redecl = false;
        const Ident *ident = identFind(&comp->idents, &comp->modules, &comp->blocks, comp->blocks.module, names[i], NULL, false);
        if (ident && ident->kind == IDENT_VAR && ident->block == comp->blocks.item[comp->blocks.top].block)
        {
            // Redeclaration in the same block
            redecl = true;
            identSetUsed(ident);
        }
        else
        {
            // New variable
            newVarFound = true;
            ident = identAllocVar(&comp->idents, &comp->types, &comp->modules, &comp->blocks, names[i], rightType, exported[i]);
        }

        if (constExpr)              // Initialize global variable
        {
            Const rightConstantBuf = {.ptrVal = (char *)rightListConstant->ptrVal + rightListType->field[i]->offset};
            constDeref(&comp->consts, &rightConstantBuf, rightType->kind);

            if (redecl)
                doAssertImplicitTypeConv(comp, ident->type, &rightType, &rightConstantBuf);

            constAssign(&comp->consts, ident->ptr, &rightConstantBuf, ident->type->kind, typeSize(&comp->types, ident->type));
        }
        else                        // Assign to variable
        {
            genDup(&comp->gen);                                             // Duplicate expression list pointer
            genGetFieldPtr(&comp->gen, rightListType->field[i]->offset);    // Get expression pointer
            genDeref(&comp->gen, rightType->kind);                          // Get expression value

            if (redecl)
            {
                doAssertImplicitTypeConv(comp, ident->type, &rightType, NULL);

                doPushVarPtr(comp, ident);
                genSwapChangeRefCntAssign(&comp->gen, ident->type);                                 // Assign expression to variable - both left-hand and right-hand side reference counts modified
            }
            else
            {
                genChangeRefCnt(&comp->gen, TOK_PLUSPLUS, rightType);                               // Increase right-hand side reference count
                doPushVarPtr(comp, ident);
                genSwapAssign(&comp->gen, ident->type->kind, typeSize(&comp->types, ident->type));  // Assign expression to variable
            }
        }
    }

    if (!constExpr)
        genPop(&comp->gen);                                                 // Remove expression list pointer

    if (!newVarFound)
        comp->error.handler(comp->error.context, "No new variables declared");
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movb %r8b, %al
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
andb $0x1, %al
movb %al, -0x1d(%rbp)
movq $0x0, -0x28(%rbp)
testb $0x1, -0x1d(%rbp)
je 0x1dffa
leaq -0x30(%rbp), %rax
movq %rax, -0x70(%rbp)
jmp 0x1e002
xorl %eax, %eax
movq %rax, -0x70(%rbp)
jmp 0x1e002
movq -0x70(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rdx
leaq -0x28(%rbp), %rsi
callq 0xeea0
movq -0x28(%rbp), %rdi
callq 0x1da10
testb $0x1, %al
jne 0x1e02a
jmp 0x1e036
movq -0x28(%rbp), %rax
movl 0x10(%rax), %eax
movl %eax, -0x74(%rbp)
jmp 0x1e040
movl $0x1, %eax
movl %eax, -0x74(%rbp)
jmp 0x1e040
movl -0x74(%rbp), %eax
movl %eax, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
cmpl -0x1c(%rbp), %eax
je 0x1e076
movq -0x8(%rbp), %rax
movq 0x50f8(%rax), %r8
movq -0x8(%rbp), %rax
movq 0x5118(%rax), %rdi
movl -0x1c(%rbp), %edx
movl -0x3c(%rbp), %ecx
leaq 0x1bba24(%rip), %rsi    # 0x1d9a95
movb $0x0, %al
callq *%r8
movb $0x0, -0x3d(%rbp)
movl $0x0, -0x44(%rbp)
movl -0x44(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jge 0x1e39f
movq -0x28(%rbp), %rax
movq 0x28(%rax), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x108(%rax), %rax
movq %rax, -0x50(%rbp)
movb $0x0, -0x51(%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
movq -0x8(%rbp), %rax
movl 0x4b88(%rax), %ecx
movq -0x10(%rbp), %r8
movslq -0x44(%rbp), %rax
shlq $0x8, %rax
addq %rax, %r8
xorl %eax, %eax
movl %eax, %r9d
xorl %eax, %eax
movl $0x0, (%rsp)
callq 0x19580
movq %rax, -0x60(%rbp)
cmpq $0x0, -0x60(%rbp)
je 0x1e147
movq -0x60(%rbp), %rax
cmpl $0x1, (%rax)
jne 0x1e147
movq -0x60(%rbp), %rax
movl 0x114(%rax), %eax
movq -0x8(%rbp), %rcx
addq $0x4220, %rcx           # imm = 0x4220
movq -0x8(%rbp), %rdx
movslq 0x4b84(%rdx), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
cmpl (%rcx), %eax
jne 0x1e147
movb $0x1, -0x51(%rbp)
movq -0x60(%rbp), %rdi
callq 0x1ed60
jmp 0x1e1a7
movb $0x1, -0x3d(%rbp)
movq -0x8(%rbp), %rdi
addq $0x4e38, %rdi           # imm = 0x4E38
movq -0x8(%rbp), %rsi
addq $0x4e18, %rsi           # imm = 0x4E18
movq -0x8(%rbp), %rdx
addq $0x100, %rdx            # imm = 0x100
movq -0x8(%rbp), %rcx
addq $0x4220, %rcx           # imm = 0x4220
movq -0x10(%rbp), %r8
movslq -0x44(%rbp), %rax
shlq $0x8, %rax
addq %rax, %r8
movq -0x50(%rbp), %r9
movq -0x18(%rbp), %rax
movslq -0x44(%rbp), %r10
movb (%rax,%r10), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, (%rsp)
callq 0x1a450
movq %rax, -0x60(%rbp)
testb $0x1, -0x1d(%rbp)
je 0x1e27c
movq -0x38(%rbp), %rax
movq (%rax), %rax
movq -0x28(%rbp), %rcx
movq 0x28(%rcx), %rcx
movslq -0x44(%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 -0x50(%rbp), %rax
movl (%rax), %edx
leaq -0x68(%rbp), %rsi
callq 0x86b0
testb $0x1, -0x51(%rbp)
je 0x1e212
movq -0x8(%rbp), %rdi
movq -0x60(%rbp), %rax
movq 0x108(%rax), %rsi
leaq -0x50(%rbp), %rdx
leaq -0x68(%rbp), %rcx
callq 0xd6e0
movq -0x8(%rbp), %rax
addq $0x4e68, %rax           # imm = 0x4E68
movq %rax, -0x88(%rbp)
movq -0x60(%rbp), %rax
movq 0x120(%rax), %rax
movq %rax, -0x80(%rbp)
movq -0x60(%rbp), %rax
movq 0x108(%rax), %rax
movl (%rax), %eax
movl %eax, -0x78(%rbp)
movq -0x8(%rbp), %rdi
addq $0x4e18, %rdi           # imm = 0x4E18
movq -0x60(%rbp), %rax
movq 0x108(%rax), %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 0x1e38f
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
callq 0x16eb0
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movq -0x28(%rbp), %rax
movq 0x28(%rax), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movl 0x110(%rax), %esi
callq 0x17bb0
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movq -0x50(%rbp), %rax
movl (%rax), %esi
callq 0x16fa0
testb $0x1, -0x51(%rbp)
je 0x1e314
movq -0x8(%rbp), %rdi
movq -0x60(%rbp), %rax
movq 0x108(%rax), %rsi
leaq -0x50(%rbp), %rdx
xorl %eax, %eax
movl %eax, %ecx
callq 0xd6e0
movq -0x8(%rbp), %rdi
movq -0x60(%rbp), %rsi
callq 0xd010
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movq -0x60(%rbp), %rax
movq 0x108(%rax), %rsi
callq 0x17500
jmp 0x1e38d
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movq -0x50(%rbp), %rdx
movl $0x2c, %esi
callq 0x17270
movq -0x8(%rbp), %rdi
movq -0x60(%rbp), %rsi
callq 0xd010
movq -0x8(%rbp), %rax
addq $0x4e70, %rax           # imm = 0x4E70
movq %rax, -0x98(%rbp)
movq -0x60(%rbp), %rax
movq 0x108(%rax), %rax
movl (%rax), %eax
movl %eax, -0x8c(%rbp)
movq -0x8(%rbp), %rdi
addq $0x4e18, %rdi           # imm = 0x4E18
movq -0x60(%rbp), %rax
movq 0x108(%rax), %rsi
callq 0x21fe0
movq -0x98(%rbp), %rdi
movl -0x8c(%rbp), %esi
movl %eax, %edx
callq 0x17120
jmp 0x1e38f
jmp 0x1e391
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x1e081
testb $0x1, -0x1d(%rbp)
jne 0x1e3b5
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
callq 0x16d30
testb $0x1, -0x3d(%rbp)
jne 0x1e3dc
movq -0x8(%rbp), %rax
movq 0x50f8(%rax), %rcx
movq -0x8(%rbp), %rax
movq 0x5118(%rax), %rdi
leaq 0x1bb705(%rip), %rsi    # 0x1d9add
movb $0x0, %al
callq *%rcx
addq $0xa0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)