// File: /workspace/github_c_makefile_star2_O0/gregtour[P]minimal-compiler/preprocess.c
// Function: ProcessCodeBlock
void ProcessCodeBlock(SYNTAX_BLOCK* block, int (*computation)(FSTMT*, void*), void* frameData)
{
    FSTMT_LIST* fstmtList = NULL;
    FSTMT*          fstmt = NULL;

    if (block == NULL) { return; }

    Assert(block);
    Assert(block->children && block->numChildren >= 0);

    // derive statement block type
    if (block->production == PROD_BLOCK_FSTMT)
    {
        // <block> ::= <fstmt> [PROD_BLOCK_FSTMT]
        Assert(block->children[0]->token == SYMBOL_FSTMT);
        fstmt = (FSTMT*)block->children[0];

    } else if (block->production == PROD_BLOCK) {
        // <block> ::= { <fstmt*> } [PROD_BLOCK]
        Assert(block->children[1]->token == SYMBOL_FSTMT_STAR);
        fstmtList = (FSTMT_LIST*)block->children[1];

        //if (fstmtList->children[0]->token == SYMBOL_FSTMT)
        if (fstmtList->production == PROD_FSTMT_STAR_FSTMT)
        {
            // <fstmt*> ::= <fstmt> <fstmt*> [PROD_FSTMT_STAR_FSTMT]
            fstmt = (FSTMT*)fstmtList->children[0];
        } else {
            // <fstmt*> ::= <epsilon> [PROD_FSTMT_STAR]
            fstmt = NULL;
        }
    } else {
        // ????
        Assert(0);
    }

    // process statements
    if (fstmt)
    {
        do {
            // iterate to next statement
            if (fstmtList) 
            { 
                Assert(fstmtList->production == PROD_FSTMT_STAR_FSTMT);

                fstmt = (FSTMT*)fstmtList->children[0];
                fstmtList = fstmtList->children[1];
                if (fstmtList->production == PROD_FSTMT_STAR)
                    { fstmtList = NULL; }
            }

            // perform calculations
            if (computation(fstmt, frameData) != 0)
            {
                // returning non-zero halts the iteration
                break;
            }

        } while (fstmtList);
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq $0x0, -0x20(%rbp)
movq $0x0, -0x28(%rbp)
cmpq $0x0, -0x8(%rbp)
jne 0x8c40
jmp 0x8d01
movq -0x8(%rbp), %rax
cmpl $0xf, 0x4(%rax)
jne 0x8c5b
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq (%rax), %rax
movq %rax, -0x28(%rbp)
jmp 0x8c9e
movq -0x8(%rbp), %rax
cmpl $0x10, 0x4(%rax)
jne 0x8c9a
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x8(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpl $0x13, 0x4(%rax)
jne 0x8c90
movq -0x20(%rbp), %rax
movq 0x28(%rax), %rax
movq (%rax), %rax
movq %rax, -0x28(%rbp)
jmp 0x8c98
movq $0x0, -0x28(%rbp)
jmp 0x8c9c
jmp 0x8c9c
jmp 0x8c9e
cmpq $0x0, -0x28(%rbp)
je 0x8d01
jmp 0x8ca7
cmpq $0x0, -0x20(%rbp)
je 0x8ce1
movq -0x20(%rbp), %rax
movq 0x28(%rax), %rax
movq (%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x20(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x8(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpl $0x14, 0x4(%rax)
jne 0x8cdf
movq $0x0, -0x20(%rbp)
jmp 0x8ce1
movq -0x10(%rbp), %rax
movq -0x28(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq *%rax
cmpl $0x0, %eax
je 0x8cf6
jmp 0x8cff
jmp 0x8cf8
cmpq $0x0, -0x20(%rbp)
jne 0x8ca7
jmp 0x8d01
addq $0x30, %rsp
popq %rbp
retq
nopw (%rax,%rax)