// File: /workspace/github_c_makefile_star2_O0/vtereshkov[P]umka-lang/src/umka_stmt.c
// Function: parseForStmt
static void parseForStmt(Compiler *comp)
{
    lexEat(&comp->lex, TOK_FOR);

    // Additional scope embracing shortVarDecl in forHeader/forEachHeader and statement body
    blocksEnter(&comp->blocks);

    // 'break'/'continue' prologs
    Gotos breaks, *outerBreaks = comp->gen.breaks;
    comp->gen.breaks = &breaks;
    genGotosProlog(&comp->gen, comp->gen.breaks, blocksCurrent(&comp->blocks));

    Gotos continues, *outerContinues = comp->gen.continues;
    comp->gen.continues = &continues;
    genGotosProlog(&comp->gen, comp->gen.continues, blocksCurrent(&comp->blocks));

    ForPostStmt deferredPostStmt = {0};

    Lexer lookaheadLex = comp->lex;
    lexNext(&lookaheadLex);

    if (!doShortVarDeclLookahead(comp) && (lookaheadLex.tok.kind == TOK_COMMA || lookaheadLex.tok.kind == TOK_IN))
        parseForInHeader(comp, &deferredPostStmt);
    else
        parseForHeader(comp, &deferredPostStmt);

    // block
    parseBlock(comp);

    // 'continue' epilog
    genGotosEpilog(&comp->gen, comp->gen.continues);
    comp->gen.continues = outerContinues;

    // simpleStmt, if deferred
    if (deferredPostStmt.isDeferred)
    {
        if (deferredPostStmt.indexIdent)
        {
            doPushVarPtr(comp, deferredPostStmt.indexIdent);
            genUnary(&comp->gen, deferredPostStmt.op, deferredPostStmt.indexIdent->type->kind);            
        }
        genWhileEpilog(&comp->gen);
    }
    else
    {
        genForEpilog(&comp->gen);        
    }

    // 'break' epilog
    genGotosEpilog(&comp->gen, comp->gen.breaks);
    comp->gen.breaks = outerBreaks;

    // Additional scope embracing shortVarDecl in forHeader/forInHeader and statement body
    doGarbageCollection(comp);
    identWarnIfUnusedAll(&comp->idents, blocksCurrent(&comp->blocks));
    blocksLeave(&comp->blocks);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x600, %rsp            # imm = 0x600
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
addq $0x4ba8, %rdi           # imm = 0x4BA8
movl $0x9, %esi
callq 0x1b150
movq -0x8(%rbp), %rdi
addq $0x4220, %rdi           # imm = 0x4220
callq 0x5e60
movq -0x8(%rbp), %rax
movq 0x5018(%rax), %rax
movq %rax, -0x1b0(%rbp)
movq -0x8(%rbp), %rax
leaq -0x1a8(%rbp), %rcx
movq %rcx, 0x5018(%rax)
movq -0x8(%rbp), %rax
addq $0x4e70, %rax           # imm = 0x4E70
movq %rax, -0x5f8(%rbp)
movq -0x8(%rbp), %rax
movq 0x5018(%rax), %rax
movq %rax, -0x5f0(%rbp)
movq -0x8(%rbp), %rdi
addq $0x4220, %rdi           # imm = 0x4220
callq 0x6020
movq -0x5f8(%rbp), %rdi
movq -0x5f0(%rbp), %rsi
movl %eax, %edx
callq 0x18cb0
movq -0x8(%rbp), %rax
movq 0x5020(%rax), %rax
movq %rax, -0x358(%rbp)
movq -0x8(%rbp), %rax
leaq -0x350(%rbp), %rcx
movq %rcx, 0x5020(%rax)
movq -0x8(%rbp), %rax
addq $0x4e70, %rax           # imm = 0x4E70
movq %rax, -0x5e8(%rbp)
movq -0x8(%rbp), %rax
movq 0x5020(%rax), %rax
movq %rax, -0x5e0(%rbp)
movq -0x8(%rbp), %rdi
addq $0x4220, %rdi           # imm = 0x4220
callq 0x6020
movq -0x5e8(%rbp), %rdi
movq -0x5e0(%rbp), %rsi
movl %eax, %edx
callq 0x18cb0
leaq -0x368(%rbp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x3190
movq -0x8(%rbp), %rsi
addq $0x4ba8, %rsi           # imm = 0x4BA8
leaq -0x5d8(%rbp), %rdi
movl $0x270, %edx            # imm = 0x270
callq 0x3270
leaq -0x5d8(%rbp), %rdi
callq 0x1ad90
movq -0x8(%rbp), %rdi
callq 0x1f910
testb $0x1, %al
jne 0x1f3a8
cmpl $0x3f, -0x5b0(%rbp)
je 0x1f396
cmpl $0xd, -0x5b0(%rbp)
jne 0x1f3a8
movq -0x8(%rbp), %rdi
leaq -0x368(%rbp), %rsi
callq 0x208d0
jmp 0x1f3b8
movq -0x8(%rbp), %rdi
leaq -0x368(%rbp), %rsi
callq 0x21470
movq -0x8(%rbp), %rdi
callq 0x1ee30
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movq -0x8(%rbp), %rax
movq 0x5020(%rax), %rsi
callq 0x18d60
movq -0x358(%rbp), %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x5020(%rax)
testb $0x1, -0x35c(%rbp)
je 0x1f449
cmpq $0x0, -0x368(%rbp)
je 0x1f437
movq -0x8(%rbp), %rdi
movq -0x368(%rbp), %rsi
callq 0xd010
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movl -0x360(%rbp), %esi
movq -0x368(%rbp), %rax
movq 0x108(%rax), %rax
movl (%rax), %edx
callq 0x17620
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
callq 0x188e0
jmp 0x1f459
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
callq 0x18a00
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movq -0x8(%rbp), %rax
movq 0x5018(%rax), %rsi
callq 0x18d60
movq -0x1b0(%rbp), %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x5018(%rax)
movq -0x8(%rbp), %rdi
callq 0x1d3a0
movq -0x8(%rbp), %rax
addq $0x4e38, %rax           # imm = 0x4E38
movq %rax, -0x600(%rbp)
movq -0x8(%rbp), %rdi
addq $0x4220, %rdi           # imm = 0x4220
callq 0x6020
movq -0x600(%rbp), %rdi
movl %eax, %esi
callq 0x1a7e0
movq -0x8(%rbp), %rdi
addq $0x4220, %rdi           # imm = 0x4220
callq 0x5fa0
addq $0x600, %rsp            # imm = 0x600
popq %rbp
retq
nopw (%rax,%rax)