// File: sighingnow[P]compile-pascal/pl0c.cpp
// Function: main
int main(int argc, char **argv) {
    bool opt;
    if (argc == 3 && string(argv[2]) == "-O") {
        opt = true;
    }
    else {
        opt = false;
    }
    auto parse_tool = ParsecT<decltype(pl0_program)>(pl0_program);
    input_t *in = load_case(argv[1]);
    auto res = parse_tool(in);
    if (!res.status) {
        cout << "Errors occurred during parsing." << endl;
        return 0;
    }
    if (!res.strict) {
        cout << "Extra characters in source text." << endl;
    }

    if (!pl0_tac_program(res.actual)) {
        cout << "Errors occurred during semantic analysing." << endl;
    }

    cout << "\n;; <<<<<<<<<<<<<  All Basic Blocks <<<<<<<<<<<<<<<<<<<<<<<<<<<\n" << endl;

    std::vector<BasicBlock> bbs;
    pl0_block(irb.irs, bbs);
    for (auto && bb: bbs) {
        bb.dump();
        if (opt) {
            cout << ";;;;;;;;;;;;;;;;;;;;;DO DAG Pass" << endl;
            bb.DAGPass();
            bb.dump();
        }
    }

    cout << "\n;; <<<<<<<<<<<<<  Assembly (Intel syntax, nasm)   <<<<<<<<<<<<\n" << endl;

    try { // try exception throwed during assembly code generating.
        pl0_x86_gen(string(argv[1]), bbs);
    } catch (std::exception & e) {
        cout << string(";; !!!Exception: ") + string(e.what()) << endl;
    } catch (...) {
        cout << string(";; !!!Exception: ") + "unknown exception." << endl;
    }
    
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2b0, %rsp            # imm = 0x2B0
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl -0x8(%rbp), %ecx
movb $0x0, -0x3a(%rbp)
movb $0x0, -0x4d(%rbp)
xorl %eax, %eax
cmpl $0x3, %ecx
movb %al, -0x202(%rbp)
jne 0xebe27
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x218(%rbp)
leaq -0x39(%rbp), %rdi
movq %rdi, -0x210(%rbp)
callq 0x55d0
movq -0x218(%rbp), %rsi
movq -0x210(%rbp), %rdx
movb $0x1, -0x3a(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x19840
jmp 0xebdfd
movb $0x1, -0x4d(%rbp)
leaq 0x5d16(%rip), %rsi      # 0xf1b1e
leaq -0x38(%rbp), %rdi
callq 0x2a580
movb %al, -0x219(%rbp)
jmp 0xebe19
movb -0x219(%rbp), %al
movb %al, -0x202(%rbp)
jmp 0xebe27
movb -0x202(%rbp), %al
movb %al, -0x21a(%rbp)
testb $0x1, -0x4d(%rbp)
jne 0xebe3b
jmp 0xebe44
leaq -0x38(%rbp), %rdi
callq 0x5200
testb $0x1, -0x3a(%rbp)
jne 0xebe4c
jmp 0xebe55
leaq -0x39(%rbp), %rdi
callq 0x53c0
movb -0x21a(%rbp), %al
testb $0x1, %al
jne 0xebe61
jmp 0xebeaa
movb $0x1, -0x11(%rbp)
jmp 0xebeae
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xebe94
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
testb $0x1, -0x4d(%rbp)
jne 0xebe89
jmp 0xebe92
leaq -0x38(%rbp), %rdi
callq 0x5200
jmp 0xebe94
testb $0x1, -0x3a(%rbp)
jne 0xebe9c
jmp 0xebea5
leaq -0x39(%rbp), %rdi
callq 0x53c0
jmp 0xec539
movb $0x0, -0x11(%rbp)
leaq 0x73bbb(%rip), %rsi     # 0x15fa70
leaq -0x98(%rbp), %rdi
callq 0xec670
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0xebb40
movq %rax, -0x228(%rbp)
jmp 0xebed7
movq -0x228(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq -0xa0(%rbp), %rdx
leaq -0xe0(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0xec6a0
jmp 0xebf01
testb $0x1, -0xe0(%rbp)
jne 0xebf73
movq 0x730c7(%rip), %rdi     # 0x15efd8
leaq 0x5c09(%rip), %rsi      # 0xf1b21
callq 0x5330
movq %rax, -0x230(%rbp)
jmp 0xebf26
movq -0x230(%rbp), %rdi
movq 0x7308c(%rip), %rsi     # 0x15efc0
callq 0x53a0
jmp 0xebf3b
movl $0x0, -0x4(%rbp)
movl $0x1, -0xe4(%rbp)
jmp 0xec4fd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xec52d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xec521
testb $0x1, -0xa8(%rbp)
jne 0xebfaf
movq 0x73055(%rip), %rdi     # 0x15efd8
leaq 0x5bb7(%rip), %rsi      # 0xf1b41
callq 0x5330
movq %rax, -0x238(%rbp)
jmp 0xebf98
movq -0x238(%rbp), %rdi
movq 0x7301a(%rip), %rsi     # 0x15efc0
callq 0x53a0
jmp 0xebfad
jmp 0xebfaf
movq -0xd0(%rbp), %rdi
callq 0xae9a0
movb %al, -0x239(%rbp)
jmp 0xebfc3
movb -0x239(%rbp), %al
testb $0x1, %al
jne 0xec002
jmp 0xebfcf
movq 0x73002(%rip), %rdi     # 0x15efd8
leaq 0x5b85(%rip), %rsi      # 0xf1b62
callq 0x5330
movq %rax, -0x248(%rbp)
jmp 0xebfeb
movq -0x248(%rbp), %rdi
movq 0x72fc7(%rip), %rsi     # 0x15efc0
callq 0x53a0
jmp 0xec000
jmp 0xec002
movq 0x72fcf(%rip), %rdi     # 0x15efd8
leaq 0x5b7d(%rip), %rsi      # 0xf1b8d
callq 0x5330
movq %rax, -0x250(%rbp)
jmp 0xec01e
movq -0x250(%rbp), %rdi
movq 0x72f94(%rip), %rsi     # 0x15efc0
callq 0x53a0
jmp 0xec033
leaq -0x100(%rbp), %rdi
movq %rdi, -0x258(%rbp)
callq 0xec6e0
movq -0x258(%rbp), %rsi
leaq 0x7467c(%rip), %rdi     # 0x1606d0
addq $0x10, %rdi
movl $0x1, %edx
callq 0xcbd00
jmp 0xec064
leaq -0x100(%rbp), %rax
movq %rax, -0x108(%rbp)
movq -0x108(%rbp), %rdi
callq 0xcdfe0
movq %rax, -0x110(%rbp)
movq -0x108(%rbp), %rdi
callq 0xce010
movq %rax, -0x118(%rbp)
leaq -0x110(%rbp), %rdi
leaq -0x118(%rbp), %rsi
callq 0xce040
testb $0x1, %al
jne 0xec0b4
jmp 0xec14e
leaq -0x110(%rbp), %rdi
callq 0xce080
movq %rax, -0x120(%rbp)
movq -0x120(%rbp), %rdi
callq 0xc9550
jmp 0xec0d5
testb $0x1, -0x11(%rbp)
je 0xec13b
movq 0x72ef6(%rip), %rdi     # 0x15efd8
leaq 0x5ae5(%rip), %rsi      # 0xf1bce
callq 0x5330
movq %rax, -0x260(%rbp)
jmp 0xec0f7
movq -0x260(%rbp), %rdi
movq 0x72ebb(%rip), %rsi     # 0x15efc0
callq 0x53a0
jmp 0xec10c
movq -0x120(%rbp), %rdi
callq 0xcbcc0
jmp 0xec11a
movq -0x120(%rbp), %rdi
callq 0xc9550
jmp 0xec128
jmp 0xec13b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xec4ef
jmp 0xec13d
leaq -0x110(%rbp), %rdi
callq 0xce180
jmp 0xec098
movq 0x72e83(%rip), %rdi     # 0x15efd8
leaq 0x5a93(%rip), %rsi      # 0xf1bef
callq 0x5330
movq %rax, -0x268(%rbp)
jmp 0xec16a
movq -0x268(%rbp), %rdi
movq 0x72e48(%rip), %rsi     # 0x15efc0
callq 0x53a0
jmp 0xec17f
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x278(%rbp)
leaq -0x141(%rbp), %rdi
movq %rdi, -0x270(%rbp)
callq 0x55d0
movq -0x278(%rbp), %rsi
movq -0x270(%rbp), %rdx
leaq -0x140(%rbp), %rdi
callq 0x19840
jmp 0xec1bd
leaq -0x140(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0xdef20
jmp 0xec1d2
leaq -0x140(%rbp), %rdi
callq 0x5200
leaq -0x141(%rbp), %rdi
callq 0x53c0
jmp 0xec348
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xec215
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x140(%rbp), %rdi
callq 0x5200
leaq -0x141(%rbp), %rdi
callq 0x53c0
movl -0x4c(%rbp), %eax
movl $0x2, %ecx
cmpl %ecx, %eax
jne 0xec36a
movq -0x48(%rbp), %rdi
callq 0x5140
movq %rax, -0x198(%rbp)
leaq -0x1d9(%rbp), %rdi
movq %rdi, -0x280(%rbp)
callq 0x55d0
movq -0x280(%rbp), %rdx
leaq 0x59ce(%rip), %rsi      # 0xf1c30
leaq -0x1d8(%rbp), %rdi
callq 0x19840
jmp 0xec270
movq -0x198(%rbp), %rdi
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
movq %rax, -0x290(%rbp)
leaq -0x201(%rbp), %rdi
movq %rdi, -0x288(%rbp)
callq 0x55d0
movq -0x290(%rbp), %rsi
movq -0x288(%rbp), %rdx
leaq -0x200(%rbp), %rdi
callq 0x19840
jmp 0xec2b6
leaq -0x1b8(%rbp), %rdi
leaq -0x1d8(%rbp), %rsi
leaq -0x200(%rbp), %rdx
callq 0x1a3d0
jmp 0xec2d2
movq 0x72cff(%rip), %rdi     # 0x15efd8
leaq -0x1b8(%rbp), %rsi
callq 0x52e0
movq %rax, -0x298(%rbp)
jmp 0xec2ee
movq -0x298(%rbp), %rdi
movq 0x72cc4(%rip), %rsi     # 0x15efc0
callq 0x53a0
jmp 0xec303
leaq -0x1b8(%rbp), %rdi
callq 0x5200
leaq -0x200(%rbp), %rdi
callq 0x5200
leaq -0x201(%rbp), %rdi
callq 0x53c0
leaq -0x1d8(%rbp), %rdi
callq 0x5200
leaq -0x1d9(%rbp), %rdi
callq 0x53c0
callq 0x5540
jmp 0xec346
jmp 0xec348
movl $0x0, -0x4(%rbp)
movl $0x1, -0xe4(%rbp)
leaq -0x100(%rbp), %rdi
callq 0xec700
jmp 0xec4fd
movq -0x48(%rbp), %rdi
callq 0x5140
leaq -0x189(%rbp), %rdi
movq %rdi, -0x2a0(%rbp)
callq 0x55d0
movq -0x2a0(%rbp), %rdx
leaq 0x589c(%rip), %rsi      # 0xf1c30
leaq -0x188(%rbp), %rdi
callq 0x19840
jmp 0xec3a2
leaq 0x5899(%rip), %rdx      # 0xf1c42
leaq -0x168(%rbp), %rdi
leaq -0x188(%rbp), %rsi
callq 0x1a380
jmp 0xec3be
movq 0x72c13(%rip), %rdi     # 0x15efd8
leaq -0x168(%rbp), %rsi
callq 0x52e0
movq %rax, -0x2a8(%rbp)
jmp 0xec3da
movq -0x2a8(%rbp), %rdi
movq 0x72bd8(%rip), %rsi     # 0x15efc0
callq 0x53a0
jmp 0xec3ef
leaq -0x168(%rbp), %rdi
callq 0x5200
leaq -0x188(%rbp), %rdi
callq 0x5200
leaq -0x189(%rbp), %rdi
callq 0x53c0
callq 0x5540
jmp 0xec41a
jmp 0xec348
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xec45f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xec453
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x168(%rbp), %rdi
callq 0x5200
leaq -0x188(%rbp), %rdi
callq 0x5200
leaq -0x189(%rbp), %rdi
callq 0x53c0
callq 0x5540
jmp 0xec472
jmp 0xec4ef
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xec4da
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xec4c2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xec4b6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x1b8(%rbp), %rdi
callq 0x5200
leaq -0x200(%rbp), %rdi
callq 0x5200
leaq -0x201(%rbp), %rdi
callq 0x53c0
leaq -0x1d8(%rbp), %rdi
callq 0x5200
leaq -0x1d9(%rbp), %rdi
callq 0x53c0
callq 0x5540
jmp 0xec4ed
jmp 0xec4ef
leaq -0x100(%rbp), %rdi
callq 0xec700
jmp 0xec521
leaq -0xe0(%rbp), %rdi
callq 0xec760
leaq -0x98(%rbp), %rdi
callq 0xec780
movl -0x4(%rbp), %eax
addq $0x2b0, %rsp            # imm = 0x2B0
popq %rbp
retq
leaq -0xe0(%rbp), %rdi
callq 0xec760
leaq -0x98(%rbp), %rdi
callq 0xec780
movq -0x48(%rbp), %rdi
callq 0x55b0
movq %rax, %rdi
callq 0x2ca40
nopw (%rax,%rax)