// File: KJTang[P]SimpleCompiler/main.cpp
// Function: main
int main(int argc, char *args[]) {
    if (argc != 2) {
        std::cout<<"code file not given"<<std::endl;
        return 0;
    }
    std::ifstream fin(args[1]);
    std::string str((std::istreambuf_iterator<char>(fin)), std::istreambuf_iterator<char>());

    Lexer lexer(str);
    lexer.lex();
    // lexer.debug();

    Parser parser(lexer.getTokens());
    parser.parse();
    // parser.debug();

    Assembler assembler(parser.getAsmCode());
    assembler.assemble();
    // assembler.debug();

    VirtualMachine vm(assembler.getBinCode());
    vm.execute();
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x5c0, %rsp            # imm = 0x5C0
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpl $0x2, -0x8(%rbp)
je 0x383d
movq 0x247ba(%rip), %rdi     # 0x27fd0
leaq 0x177e7(%rip), %rsi     # 0x1b004
callq 0x3280
movq %rax, %rdi
movq 0x2478c(%rip), %rsi     # 0x27fb8
callq 0x32e0
movl $0x0, -0x4(%rbp)
jmp 0x3aea
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
leaq -0x218(%rbp), %rdi
movq %rdi, -0x5a8(%rbp)
movl $0x8, %edx
callq 0x34a0
movq -0x5a8(%rbp), %rsi
leaq -0x248(%rbp), %rdi
callq 0x3b10
leaq -0x258(%rbp), %rdi
callq 0x3b70
leaq -0x259(%rbp), %rdi
movq %rdi, -0x5a0(%rbp)
callq 0x3480
movq -0x5a0(%rbp), %r9
movq -0x248(%rbp), %rsi
movl -0x240(%rbp), %edx
movq -0x258(%rbp), %rcx
movl -0x250(%rbp), %r8d
leaq -0x238(%rbp), %rdi
callq 0x3ba0
jmp 0x38bf
leaq -0x259(%rbp), %rdi
callq 0x3300
leaq -0x2b0(%rbp), %rdi
leaq -0x238(%rbp), %rsi
xorl %edx, %edx
callq 0x3c30
jmp 0x38e2
leaq -0x2b0(%rbp), %rdi
callq 0xa890
jmp 0x38f0
leaq -0x380(%rbp), %rdi
leaq -0x2b0(%rbp), %rsi
callq 0x3c70
jmp 0x3905
leaq -0x368(%rbp), %rdi
leaq -0x380(%rbp), %rsi
callq 0x3ca0
jmp 0x391a
leaq -0x380(%rbp), %rdi
callq 0x3e50
leaq -0x368(%rbp), %rdi
callq 0xec70
jmp 0x3934
leaq -0x368(%rbp), %rdi
callq 0x3eb0
movq %rax, -0x5b0(%rbp)
jmp 0x3949
movq -0x5b0(%rbp), %rsi
leaq -0x4a0(%rbp), %rdi
callq 0x3ed0
jmp 0x395e
leaq -0x4a0(%rbp), %rdi
callq 0x14170
jmp 0x396c
leaq -0x4a0(%rbp), %rdi
callq 0x4b20
movq %rax, -0x5b8(%rbp)
jmp 0x3981
movq -0x5b8(%rbp), %rsi
leaq -0x598(%rbp), %rdi
callq 0x18190
jmp 0x3996
leaq -0x598(%rbp), %rdi
callq 0x18570
jmp 0x39a4
movl $0x0, -0x4(%rbp)
leaq -0x598(%rbp), %rdi
callq 0x4b40
leaq -0x4a0(%rbp), %rdi
callq 0x4ba0
leaq -0x368(%rbp), %rdi
callq 0x4c20
leaq -0x2b0(%rbp), %rdi
callq 0x4ce0
leaq -0x238(%rbp), %rdi
callq 0x34f8
leaq -0x218(%rbp), %rdi
callq 0x30c0
jmp 0x3aea
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x268(%rbp)
movl %eax, -0x26c(%rbp)
leaq -0x259(%rbp), %rdi
callq 0x3300
jmp 0x3adc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x268(%rbp)
movl %eax, -0x26c(%rbp)
jmp 0x3ad0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x268(%rbp)
movl %eax, -0x26c(%rbp)
jmp 0x3ac4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x268(%rbp)
movl %eax, -0x26c(%rbp)
leaq -0x380(%rbp), %rdi
callq 0x3e50
jmp 0x3ac4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x268(%rbp)
movl %eax, -0x26c(%rbp)
jmp 0x3ab8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x268(%rbp)
movl %eax, -0x26c(%rbp)
jmp 0x3aac
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x268(%rbp)
movl %eax, -0x26c(%rbp)
leaq -0x598(%rbp), %rdi
callq 0x4b40
leaq -0x4a0(%rbp), %rdi
callq 0x4ba0
leaq -0x368(%rbp), %rdi
callq 0x4c20
leaq -0x2b0(%rbp), %rdi
callq 0x4ce0
leaq -0x238(%rbp), %rdi
callq 0x34f8
leaq -0x218(%rbp), %rdi
callq 0x30c0
jmp 0x3af6
movl -0x4(%rbp), %eax
addq $0x5c0, %rsp            # imm = 0x5C0
popq %rbp
retq
movq -0x268(%rbp), %rdi
callq 0x3470
nopw %cs:(%rax,%rax)
nopl (%rax)