// File: fondoger[P]C0-Compiler/src/main.cpp
// Function: main
int main(int argc, char *argv[]) {
    initialize();

    source_filename = argc > 1 ? argv[1] : "hello_world.txt";
    source_stream.open(source_filename);

    //midcode_stream.rdbuf(std::cout.rdbuf());
    std::string midcode_filename = "mid_code.txt";
    std::string mipscode_filename = "mips_code.txt";
    std::filebuf buffer1, buffer2;
    buffer1.open(midcode_filename, std::ios_base::out);
    buffer2.open(mipscode_filename, std::ios_base::out);
    midcode_stream.rdbuf(&buffer1);
    mipscode_stream.rdbuf(&buffer2);

    // debug messages
    debug_stream.rdbuf(std::cout.rdbuf());

    // Do syntax check and generate mid-code
    pProgram();

    bool has_error = printCachedErrors();
    if (has_error)
        exit(1);
        
    std::cout << "compile success!\n";
    std::cout << "mid code at: " << midcode_filename << std::endl;
    // convert mid-code to MIPS code
    convertToMIPS();
    std::cout << "mips code at: " << mipscode_filename << std::endl;
    std::cout << "\nIf you want to execute this mips program, using following command:\n"
        << "    $ java -jar mars.jar nc mips_code.txt" << std::endl;

    source_stream.close();
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2c0, %rsp            # imm = 0x2C0
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
callq 0x23f10
cmpl $0x1, -0x8(%rbp)
jle 0x23b65
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x260(%rbp)
jmp 0x23b75
leaq 0x12164(%rip), %rax     # 0x35cd0
movq %rax, -0x260(%rbp)
jmp 0x23b75
movq -0x260(%rbp), %rsi
leaq 0x24565(%rip), %rdi     # 0x480e8
movq %rdi, -0x270(%rbp)
callq 0x3430
movq -0x270(%rbp), %rsi
leaq 0x2456b(%rip), %rdi     # 0x48108
movl $0x8, %edx
callq 0x32a0
leaq -0x31(%rbp), %rdi
movq %rdi, -0x268(%rbp)
callq 0x3570
movq -0x268(%rbp), %rdx
leaq 0x1211b(%rip), %rsi     # 0x35ce0
leaq -0x30(%rbp), %rdi
callq 0x3440
jmp 0x23bd0
leaq -0x31(%rbp), %rdi
callq 0x3370
leaq -0x69(%rbp), %rdi
movq %rdi, -0x278(%rbp)
callq 0x3570
movq -0x278(%rbp), %rdx
leaq 0x12186(%rip), %rsi     # 0x35d7d
leaq -0x68(%rbp), %rdi
callq 0x3440
jmp 0x23c02
leaq -0x69(%rbp), %rdi
callq 0x3370
leaq -0x160(%rbp), %rdi
callq 0x3330
jmp 0x23c19
leaq -0x250(%rbp), %rdi
callq 0x3330
jmp 0x23c27
leaq -0x160(%rbp), %rdi
leaq -0x30(%rbp), %rsi
movl $0x10, %edx
callq 0x35d0
jmp 0x23c3e
leaq -0x250(%rbp), %rdi
leaq -0x68(%rbp), %rsi
movl $0x10, %edx
callq 0x35d0
jmp 0x23c55
leaq 0x246b4(%rip), %rdi     # 0x48310
movq 0x246ad(%rip), %rax     # 0x48310
movq -0x18(%rax), %rax
addq %rax, %rdi
leaq -0x160(%rbp), %rsi
callq 0x3590
jmp 0x23c78
leaq 0x247a1(%rip), %rdi     # 0x48420
movq 0x2479a(%rip), %rax     # 0x48420
movq -0x18(%rax), %rax
addq %rax, %rdi
leaq -0x250(%rbp), %rsi
callq 0x3590
jmp 0x23c9b
leaq 0x24aae(%rip), %rax     # 0x48750
movq 0x24aa7(%rip), %rcx     # 0x48750
movq -0x18(%rcx), %rcx
addq %rcx, %rax
movq %rax, -0x288(%rbp)
movq 0x2130a(%rip), %rdi     # 0x44fc8
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x3160
movq %rax, -0x280(%rbp)
jmp 0x23cd6
movq -0x280(%rbp), %rsi
movq -0x288(%rbp), %rdi
callq 0x3590
jmp 0x23ceb
callq 0x1a300
jmp 0x23cf2
callq 0x17fa0
movb %al, -0x289(%rbp)
jmp 0x23cff
movb -0x289(%rbp), %al
andb $0x1, %al
movb %al, -0x251(%rbp)
testb $0x1, -0x251(%rbp)
je 0x23d93
movl $0x1, %edi
callq 0x33c0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x31(%rbp), %rdi
callq 0x3370
jmp 0x23ef9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x69(%rbp), %rdi
callq 0x3370
jmp 0x23ef0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x23ee7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x23edb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x250(%rbp), %rdi
callq 0x34c0
jmp 0x23edb
movq 0x2122e(%rip), %rdi     # 0x44fc8
leaq 0x11f4c(%rip), %rsi     # 0x35ced
callq 0x3300
jmp 0x23da8
movq 0x21219(%rip), %rdi     # 0x44fc8
leaq 0x11f49(%rip), %rsi     # 0x35cff
callq 0x3300
movq %rax, -0x298(%rbp)
jmp 0x23dc4
movq -0x298(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x32c0
movq %rax, -0x2a0(%rbp)
jmp 0x23ddd
movq -0x2a0(%rbp), %rdi
movq 0x211bd(%rip), %rsi     # 0x44fa8
callq 0x3360
jmp 0x23df2
callq 0x29150
jmp 0x23df9
movq 0x211c8(%rip), %rdi     # 0x44fc8
leaq 0x11f06(%rip), %rsi     # 0x35d0d
callq 0x3300
movq %rax, -0x2a8(%rbp)
jmp 0x23e15
movq -0x2a8(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x32c0
movq %rax, -0x2b0(%rbp)
jmp 0x23e2e
movq -0x2b0(%rbp), %rdi
movq 0x2116c(%rip), %rsi     # 0x44fa8
callq 0x3360
jmp 0x23e43
movq 0x2117e(%rip), %rdi     # 0x44fc8
leaq 0x11ecb(%rip), %rsi     # 0x35d1c
callq 0x3300
movq %rax, -0x2b8(%rbp)
jmp 0x23e5f
movq -0x2b8(%rbp), %rdi
leaq 0x11ef4(%rip), %rsi     # 0x35d61
callq 0x3300
movq %rax, -0x2c0(%rbp)
jmp 0x23e7b
movq -0x2c0(%rbp), %rdi
movq 0x2111f(%rip), %rsi     # 0x44fa8
callq 0x3360
jmp 0x23e90
leaq 0x24271(%rip), %rdi     # 0x48108
callq 0x3090
jmp 0x23e9e
movl $0x0, -0x4(%rbp)
leaq -0x250(%rbp), %rdi
callq 0x34c0
leaq -0x160(%rbp), %rdi
callq 0x34c0
leaq -0x68(%rbp), %rdi
callq 0x35e8
leaq -0x30(%rbp), %rdi
callq 0x35e8
movl -0x4(%rbp), %eax
addq $0x2c0, %rsp            # imm = 0x2C0
popq %rbp
retq
leaq -0x160(%rbp), %rdi
callq 0x34c0
leaq -0x68(%rbp), %rdi
callq 0x35e8
leaq -0x30(%rbp), %rdi
callq 0x35e8
movq -0x40(%rbp), %rdi
callq 0x3560
nopw %cs:(%rax,%rax)