// File: fondoger[P]C0-Compiler/src/grammar.cpp
// Function: pProgram()
void pProgram()
{
    readSymbol();
    pConstDefinitions(GLOBAL);
    while (true) {
        test(Symset({INTSY, CHARSY, VOIDSY}), Symset({}));
        DataType dtype = (g_sym == INTSY ? DT_INT:
                g_sym == CHARSY ? DT_CHAR : DT_VOID);
        readSymbol();
        if (g_sym == MAINSY) {
            if (dtype != DT_VOID) {
                error(ERR_WRONG_TYPE_OF_MAIN);
            }
            pMainFunctionDefinition();
            // this loop ends only when we found main
            // function's definitions
            break;
        }
        test(Symset({IDENTSY}), Symset({INTSY, CHARSY, VOIDSY}));
        if (g_sym != IDENTSY)
            continue;
        std::string id = g_id;
        readSymbol();
        test(Symset({COMMA, SEMICOLON, LBRACK, LBRACE, LPARENT}), Symset({}));
        if (g_sym == COMMA || g_sym == SEMICOLON || g_sym == LBRACK) {
            // must be variable definition
            pGlobalVariableDefinitionItem(dtype, id);
        } else {
            // must be function definition
            pFunctionDefinition(dtype, id);
            tabClear(LOCAL);    // clear local symbol table
        }
    }
    extraCodeChecking();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x170, %rsp            # imm = 0x170
callq 0x2e050
xorl %edi, %edi
callq 0x1a690
movl $0x2, -0x24(%rbp)
movl $0x3, -0x20(%rbp)
movl $0x4, -0x1c(%rbp)
leaq -0x24(%rbp), %rax
movq %rax, -0x18(%rbp)
movq $0x3, -0x10(%rbp)
movq -0x18(%rbp), %rsi
movq -0x10(%rbp), %rdx
leaq -0x8(%rbp), %rdi
callq 0x227f0
leaq -0x40(%rbp), %rdi
callq 0x228b0
movq -0x40(%rbp), %rsi
movq -0x38(%rbp), %rdx
leaq -0x30(%rbp), %rdi
callq 0x227f0
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x18170
leaq 0x31335(%rip), %rax     # 0x4b6b0
cmpl $0x2, (%rax)
jne 0x1a38d
movl $0x1, %eax
movl %eax, -0x15c(%rbp)
jmp 0x1a3a9
leaq 0x3131c(%rip), %rax     # 0x4b6b0
movl (%rax), %edx
xorl %eax, %eax
movl $0x2, %ecx
cmpl $0x3, %edx
cmovel %ecx, %eax
movl %eax, -0x15c(%rbp)
movl -0x15c(%rbp), %eax
movl %eax, -0x44(%rbp)
callq 0x2e050
leaq 0x312f2(%rip), %rax     # 0x4b6b0
cmpl $0xf, (%rax)
jne 0x1a450
cmpl $0x0, -0x44(%rbp)
je 0x1a446
leaq -0x69(%rbp), %rdi
movq %rdi, -0x168(%rbp)
callq 0x3570
movq -0x168(%rbp), %rdx
leaq 0x1afe9(%rip), %rsi     # 0x353d4
leaq -0x68(%rbp), %rdi
callq 0x3440
jmp 0x1a3f6
leaq -0x68(%rbp), %rdi
callq 0x18620
jmp 0x1a401
leaq -0x68(%rbp), %rdi
callq 0x35e8
leaq -0x69(%rbp), %rdi
callq 0x3370
jmp 0x1a446
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x1a438
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x35e8
leaq -0x69(%rbp), %rdi
callq 0x3370
jmp 0x1a67f
callq 0x1a6c0
jmp 0x1a671
movl $0x0, -0x9c(%rbp)
leaq -0x9c(%rbp), %rax
movq %rax, -0x98(%rbp)
movq $0x1, -0x90(%rbp)
movq -0x98(%rbp), %rsi
movq -0x90(%rbp), %rdx
leaq -0x88(%rbp), %rdi
callq 0x227f0
movl $0x2, -0xc4(%rbp)
movl $0x3, -0xc0(%rbp)
movl $0x4, -0xbc(%rbp)
leaq -0xc4(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq $0x3, -0xb0(%rbp)
movq -0xb8(%rbp), %rsi
movq -0xb0(%rbp), %rdx
leaq -0xa8(%rbp), %rdi
callq 0x227f0
movq -0x88(%rbp), %rdi
movq -0xa8(%rbp), %rsi
callq 0x18170
leaq 0x311b8(%rip), %rax     # 0x4b6b0
cmpl $0x0, (%rax)
je 0x1a502
jmp 0x1a317
leaq 0x311af(%rip), %rsi     # 0x4b6b8
leaq -0xe8(%rbp), %rdi
callq 0x3140
callq 0x2e050
jmp 0x1a51c
movups 0x1ae35(%rip), %xmm0    # 0x35358
movaps %xmm0, -0x120(%rbp)
movl $0x1d, -0x110(%rbp)
leaq -0x120(%rbp), %rax
movq %rax, -0x100(%rbp)
movq $0x5, -0xf8(%rbp)
movq -0x100(%rbp), %rsi
movq -0xf8(%rbp), %rdx
leaq -0xf0(%rbp), %rdi
callq 0x227f0
jmp 0x1a569
leaq -0x138(%rbp), %rdi
callq 0x228b0
movq -0x138(%rbp), %rsi
movq -0x130(%rbp), %rdx
leaq -0x128(%rbp), %rdi
callq 0x227f0
jmp 0x1a591
movq -0xf0(%rbp), %rdi
movq -0x128(%rbp), %rsi
callq 0x18170
jmp 0x1a5a6
leaq 0x31103(%rip), %rax     # 0x4b6b0
cmpl $0x24, (%rax)
je 0x1a5ca
leaq 0x310f7(%rip), %rax     # 0x4b6b0
cmpl $0x26, (%rax)
je 0x1a5ca
leaq 0x310eb(%rip), %rax     # 0x4b6b0
cmpl $0x1f, (%rax)
jne 0x1a632
movl -0x44(%rbp), %eax
movl %eax, -0x16c(%rbp)
leaq -0x158(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x3140
jmp 0x1a5e8
movl -0x16c(%rbp), %edi
leaq -0x158(%rbp), %rsi
callq 0x1ac20
jmp 0x1a5fc
leaq -0x158(%rbp), %rdi
callq 0x35e8
jmp 0x1a652
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x1a663
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x158(%rbp), %rdi
callq 0x35e8
jmp 0x1a663
leaq -0x44(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x1b410
jmp 0x1a644
movl $0x1, %edi
callq 0x2f570
jmp 0x1a650
jmp 0x1a652
leaq -0xe8(%rbp), %rdi
callq 0x35e8
jmp 0x1a317
leaq -0xe8(%rbp), %rdi
callq 0x35e8
jmp 0x1a67f
callq 0x2e850
addq $0x170, %rsp            # imm = 0x170
popq %rbp
retq
movq -0x78(%rbp), %rdi
callq 0x3560
nopl (%rax,%rax)