// File: philpoore[P]Math/./src/Parser.cpp
// Function: Parser::parseStatement()
AstStmt* Parser::parseStatement() {
    consumeWhiteSpace();
    AstExpr* expr = nullptr;

    Token t = peek();
    // Assignment statement
    if (t.type == TOKEN_IF) {
        expr = (AstExpr*)parseIf();
    } else if (t.type == TOKEN_IDENT) {
        if (peekNonWhitespace(1).type == TOKEN_EQ) {
            // parse assignment statement
            Token t_ident = expect(TOKEN_IDENT);
            consumeWhiteSpace();

            expect(TOKEN_EQ);
            AstAssign* ast = new AstAssign();
            ast->name = t_ident.source;
            ast->expr = parseExpr();
            expr = (AstExpr*)ast;
        }
    } else if (peek().type == TOKEN_LCURLY) {
        // Block statement
        consume();
        expr = (AstExpr*)parseBlock();
        expect(TOKEN_RCURLY, "Unmatched curly brace, missing closing bracket.");
    }

    // default to parsing expressions.
    if (expr == nullptr) {
        expr = parseExpr();
    }

    if (expr == nullptr) {
        return nullptr;
    }

    consumeWhiteSpace();
    if (expr->type != AST_TYPE_BLOCK && expr->type != AST_TYPE_IF &&
        peek().type != TOKEN_EOF) {
        expect(TOKEN_SEMI, "Missing semi colon");
    }

    AstStmt* stmt = new AstStmt();
    stmt->expr = expr;
    return stmt;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x300, %rsp            # imm = 0x300
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rdi
movq %rdi, -0x298(%rbp)
callq 0x8dc0
movq -0x298(%rbp), %rsi
movq $0x0, -0x18(%rbp)
leaq -0x48(%rbp), %rdi
xorl %edx, %edx
callq 0x88d0
cmpl $0x10e, -0x48(%rbp)     # imm = 0x10E
jne 0x9008
movq -0x298(%rbp), %rdi
callq 0x95e0
movq %rax, -0x2a0(%rbp)
jmp 0x8fe7
movq -0x2a0(%rbp), %rax
movq %rax, -0x18(%rbp)
jmp 0x93b0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x95cd
cmpl $0x101, -0x48(%rbp)     # imm = 0x101
jne 0x927e
movq -0x298(%rbp), %rsi
leaq -0x88(%rbp), %rdi
movl $0x1, %edx
callq 0x8920
jmp 0x902f
movl -0x88(%rbp), %eax
movl %eax, -0x2a4(%rbp)
leaq -0x88(%rbp), %rdi
callq 0xcb70
movl -0x2a4(%rbp), %eax
cmpl $0x103, %eax            # imm = 0x103
jne 0x9279
leaq -0xd9(%rbp), %rdi
movq %rdi, -0x2b0(%rbp)
callq 0x4500
movq -0x2b0(%rbp), %rdx
leaq 0xd47a(%rip), %rsi      # 0x164f3
leaq -0xd8(%rbp), %rdi
callq 0xbcf0
jmp 0x9087
movq -0x298(%rbp), %rsi
leaq -0xb8(%rbp), %rdi
movl $0x101, %edx            # imm = 0x101
leaq -0xd8(%rbp), %rcx
callq 0x8ab0
jmp 0x90a8
leaq -0xd8(%rbp), %rdi
callq 0x4200
leaq -0xd9(%rbp), %rdi
callq 0x4340
movq -0x298(%rbp), %rdi
callq 0x8dc0
jmp 0x90ce
leaq -0x131(%rbp), %rdi
movq %rdi, -0x2b8(%rbp)
callq 0x4500
movq -0x2b8(%rbp), %rdx
leaq 0xd404(%rip), %rsi      # 0x164f3
leaq -0x130(%rbp), %rdi
callq 0xbcf0
jmp 0x90fd
movq -0x298(%rbp), %rsi
leaq -0x110(%rbp), %rdi
movl $0x103, %edx            # imm = 0x103
leaq -0x130(%rbp), %rcx
callq 0x8ab0
jmp 0x911e
leaq -0x110(%rbp), %rdi
callq 0xcb70
leaq -0x130(%rbp), %rdi
callq 0x4200
leaq -0x131(%rbp), %rdi
callq 0x4340
movl $0x30, %edi
callq 0x42f0
movq %rax, -0x2c0(%rbp)
jmp 0x9155
movq -0x2c0(%rbp), %rdi
callq 0xcf70
jmp 0x9163
movq -0x2c0(%rbp), %rax
movq %rax, -0x140(%rbp)
leaq -0xb0(%rbp), %rsi
movq -0x140(%rbp), %rdi
addq $0x8, %rdi
callq 0x4050
jmp 0x918a
movq -0x298(%rbp), %rdi
movl $0xffffd8f1, %esi       # imm = 0xFFFFD8F1
callq 0x9c30
movq %rax, -0x2c8(%rbp)
jmp 0x91a4
movq -0x2c8(%rbp), %rcx
movq -0x140(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x140(%rbp), %rax
movq %rax, -0x18(%rbp)
leaq -0xb8(%rbp), %rdi
callq 0xcb70
jmp 0x9279
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x91f8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0xd8(%rbp), %rdi
callq 0x4200
leaq -0xd9(%rbp), %rdi
callq 0x4340
jmp 0x95cd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x9268
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x923d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x130(%rbp), %rdi
callq 0x4200
leaq -0x131(%rbp), %rdi
callq 0x4340
jmp 0x9268
movq -0x2c0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
movl $0x30, %esi
callq 0x4300
leaq -0xb8(%rbp), %rdi
callq 0xcb70
jmp 0x95cd
jmp 0x93ae
movq -0x298(%rbp), %rsi
leaq -0x170(%rbp), %rdi
xorl %edx, %edx
callq 0x88d0
jmp 0x9295
movl -0x170(%rbp), %eax
movl %eax, -0x2cc(%rbp)
leaq -0x170(%rbp), %rdi
callq 0xcb70
movl -0x2cc(%rbp), %eax
cmpl $0x10c, %eax            # imm = 0x10C
jne 0x93ac
movq -0x298(%rbp), %rsi
leaq -0x1a0(%rbp), %rdi
callq 0x8a60
jmp 0x92d3
leaq -0x1a0(%rbp), %rdi
callq 0xcb70
movq -0x298(%rbp), %rdi
callq 0xa020
movq %rax, -0x2d8(%rbp)
jmp 0x92f4
movq -0x2d8(%rbp), %rax
movq %rax, -0x18(%rbp)
leaq -0x1f1(%rbp), %rdi
movq %rdi, -0x2e0(%rbp)
callq 0x4500
movq -0x2e0(%rbp), %rdx
leaq 0xd09d(%rip), %rsi      # 0x163bd
leaq -0x1f0(%rbp), %rdi
callq 0xbcf0
jmp 0x932e
movq -0x298(%rbp), %rsi
leaq -0x1d0(%rbp), %rdi
movl $0x10d, %edx            # imm = 0x10D
leaq -0x1f0(%rbp), %rcx
callq 0x8ab0
jmp 0x934f
leaq -0x1d0(%rbp), %rdi
callq 0xcb70
leaq -0x1f0(%rbp), %rdi
callq 0x4200
leaq -0x1f1(%rbp), %rdi
callq 0x4340
jmp 0x93ac
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x939b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x1f0(%rbp), %rdi
callq 0x4200
leaq -0x1f1(%rbp), %rdi
callq 0x4340
jmp 0x95cd
jmp 0x93ae
jmp 0x93b0
cmpq $0x0, -0x18(%rbp)
jne 0x93dc
movq -0x298(%rbp), %rdi
movl $0xffffd8f1, %esi       # imm = 0xFFFFD8F1
callq 0x9c30
movq %rax, -0x2e8(%rbp)
jmp 0x93d1
movq -0x2e8(%rbp), %rax
movq %rax, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
jne 0x93fa
movq $0x0, -0x8(%rbp)
movl $0x1, -0x1f8(%rbp)
jmp 0x95b7
movq -0x298(%rbp), %rdi
callq 0x8dc0
jmp 0x9408
movq -0x18(%rbp), %rax
movl (%rax), %ecx
movb $0x0, -0x229(%rbp)
xorl %eax, %eax
cmpl $0x8, %ecx
movb %al, -0x2e9(%rbp)
je 0x9464
movq -0x18(%rbp), %rcx
xorl %eax, %eax
cmpl $0x9, (%rcx)
movb %al, -0x2e9(%rbp)
je 0x9464
movq -0x298(%rbp), %rsi
leaq -0x228(%rbp), %rdi
xorl %edx, %edx
callq 0x88d0
jmp 0x944a
movb $0x1, -0x229(%rbp)
cmpl $0x112, -0x228(%rbp)    # imm = 0x112
setne %al
movb %al, -0x2e9(%rbp)
movb -0x2e9(%rbp), %al
movb %al, -0x2ea(%rbp)
testb $0x1, -0x229(%rbp)
jne 0x947b
jmp 0x9487
leaq -0x228(%rbp), %rdi
callq 0xcb70
movb -0x2ea(%rbp), %al
testb $0x1, %al
jne 0x9496
jmp 0x9543
leaq -0x281(%rbp), %rdi
movq %rdi, -0x2f8(%rbp)
callq 0x4500
movq -0x2f8(%rbp), %rdx
leaq 0xcf36(%rip), %rsi      # 0x163ed
leaq -0x280(%rbp), %rdi
callq 0xbcf0
jmp 0x94c5
movq -0x298(%rbp), %rsi
leaq -0x260(%rbp), %rdi
movl $0x110, %edx            # imm = 0x110
leaq -0x280(%rbp), %rcx
callq 0x8ab0
jmp 0x94e6
leaq -0x260(%rbp), %rdi
callq 0xcb70
leaq -0x280(%rbp), %rdi
callq 0x4200
leaq -0x281(%rbp), %rdi
callq 0x4340
jmp 0x9543
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x9532
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x280(%rbp), %rdi
callq 0x4200
leaq -0x281(%rbp), %rdi
callq 0x4340
jmp 0x95cd
movl $0x10, %edi
callq 0x42f0
movq %rax, -0x300(%rbp)
jmp 0x9556
movq -0x300(%rbp), %rdi
callq 0xcfa0
jmp 0x9564
movq -0x300(%rbp), %rax
movq %rax, -0x290(%rbp)
movq -0x18(%rbp), %rcx
movq -0x290(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x290(%rbp), %rax
movq %rax, -0x8(%rbp)
movl $0x1, -0x1f8(%rbp)
jmp 0x95b7
movq -0x300(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
movl $0x10, %esi
callq 0x4300
jmp 0x95cd
leaq -0x48(%rbp), %rdi
callq 0xcb70
movq -0x8(%rbp), %rax
addq $0x300, %rsp            # imm = 0x300
popq %rbp
retq
leaq -0x48(%rbp), %rdi
callq 0xcb70
movq -0x50(%rbp), %rdi
callq 0x44f0
nop