// File: protonpopsicle[P]lang/src/compiler/main.cpp
// Function: main
int main(int argc, char *argv[]) {
    if (argv[1] == 0) {
        fprintf(stderr, "missing argument 1: filename\n");
        return(0);
    }
    
    /*
    * Load source file
    */
    char *source = argv[1];
    FILE *fp = fopen(source, "r");
    if (fp == 0) {
        fprintf(stderr, "error opening file\n");
        return(0);
    }
    
    /*
    * Initialize compiler
    */
    Lexer *lexer = new Lexer(fp);
    ZoneMgr *zoneMgr = new ZoneMgr();
    ByteCoder *byteCoder = new ByteCoder(zoneMgr);
    Parser *parser = new Parser(lexer, zoneMgr, byteCoder);
    
    /*
    * Run compiler
    */
    try {
        parser->program();
    }
    catch (Error err) {
        fprintf(stderr, "near line %i: %s\n", lexer->line, err.msg.c_str());
    }
    
    /*
    * Print bytecode
    */
    std::string fname(source);
    size_t pos = fname.find_last_of(".");
    if (pos != -1) {
        fname = fname.substr(0, pos);
    }
    fname += ".lang";
    
    fp = fopen(fname.c_str(), "w");
    byteCoder->write(fp);
    fclose(fp);
    
    /*
    * Cleanup
    */
    delete lexer;
    delete zoneMgr;
    delete byteCoder;
    delete parser;
    
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x130, %rsp            # imm = 0x130
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x8(%rax)
jne 0xcb98
movq 0x8465(%rip), %rax      # 0x14fe0
movq (%rax), %rdi
leaq 0x16e0(%rip), %rsi      # 0xe265
movb $0x0, %al
callq 0x2300
movl $0x0, -0x4(%rbp)
jmp 0xcfe1
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rdi
leaq 0x15c5(%rip), %rsi      # 0xe174
callq 0x22b0
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
jne 0xcbe3
movq 0x841a(%rip), %rax      # 0x14fe0
movq (%rax), %rdi
leaq 0x16b3(%rip), %rsi      # 0xe283
movb $0x0, %al
callq 0x2300
movl $0x0, -0x4(%rbp)
jmp 0xcfe1
movl $0x40, %edi
callq 0x2220
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xc8(%rbp)
movq -0x20(%rbp), %rsi
callq 0x6ec0
jmp 0xcc05
movq -0xc8(%rbp), %rax
movq %rax, -0x28(%rbp)
movl $0x60, %edi
callq 0x2220
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xd0(%rbp)
callq 0x9e10
jmp 0xcc2e
movq -0xd0(%rbp), %rax
movq %rax, -0x40(%rbp)
movl $0x70, %edi
callq 0x2220
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xd8(%rbp)
movq -0x40(%rbp), %rsi
callq 0x24f0
jmp 0xcc5b
movq -0xd8(%rbp), %rax
movq %rax, -0x48(%rbp)
movl $0x40, %edi
callq 0x2220
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xe0(%rbp)
movq -0x28(%rbp), %rsi
movq -0x40(%rbp), %rdx
movq -0x48(%rbp), %rcx
callq 0x8dd0
jmp 0xcc90
movq -0xe0(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rdi
callq 0x8f30
jmp 0xcca6
jmp 0xcdcc
movq -0xc8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
movl $0x40, %esi
callq 0x2230
jmp 0xcfed
movq -0xd0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
movl $0x60, %esi
callq 0x2230
jmp 0xcfed
movq -0xd8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
movl $0x70, %esi
callq 0x2230
jmp 0xcfed
movq -0xe0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
movl $0x40, %esi
callq 0x2230
jmp 0xcfed
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
movl -0x34(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0xcfed
movq -0x30(%rbp), %rdi
movq %rdi, -0xe8(%rbp)
callq 0x22e0
movq %rax, %rsi
leaq -0x70(%rbp), %rdi
callq 0xd000
jmp 0xcd6d
movq -0xe8(%rbp), %rdi
callq 0x20e0
movq 0x8260(%rip), %rax      # 0x14fe0
movq (%rax), %rax
movq %rax, -0xf8(%rbp)
movq -0x28(%rbp), %rax
movl 0x3c(%rax), %eax
movl %eax, -0xec(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x20f0
movq -0xf8(%rbp), %rdi
movl -0xec(%rbp), %edx
movq %rax, %rcx
leaq 0x14e0(%rip), %rsi      # 0xe297
movb $0x0, %al
callq 0x2300
leaq -0x70(%rbp), %rdi
callq 0x3930
callq 0x2360
movq -0x18(%rbp), %rax
movq %rax, -0x108(%rbp)
leaq -0x91(%rbp), %rdi
movq %rdi, -0x100(%rbp)
callq 0x23a0
movq -0x108(%rbp), %rsi
movq -0x100(%rbp), %rdx
leaq -0x90(%rbp), %rdi
callq 0x3880
jmp 0xce06
leaq -0x91(%rbp), %rdi
callq 0x2270
leaq -0x90(%rbp), %rdi
leaq 0x1489(%rip), %rsi      # 0xe2a9
movq $-0x1, %rdx
callq 0x21f0
movq %rax, -0xa0(%rbp)
cmpq $-0x1, -0xa0(%rbp)
je 0xceb8
movq -0xa0(%rbp), %rcx
xorl %eax, %eax
movl %eax, %edx
leaq -0xc0(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x2240
jmp 0xce5d
leaq -0x90(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x22c0
leaq -0xc0(%rbp), %rdi
callq 0x2160
jmp 0xceb8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x91(%rbp), %rdi
callq 0x2270
jmp 0xcfed
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x2160
jmp 0xcfed
leaq 0x13ec(%rip), %rsi      # 0xe2ab
leaq -0x90(%rbp), %rdi
callq 0x2200
jmp 0xcecd
leaq -0x90(%rbp), %rdi
callq 0x20f0
movq %rax, %rdi
leaq 0x13ce(%rip), %rsi      # 0xe2b1
callq 0x22b0
movq %rax, -0x110(%rbp)
jmp 0xcef1
movq -0x110(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x48(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x3460
jmp 0xcf0b
movq -0x20(%rbp), %rdi
callq 0x2210
jmp 0xcf16
movq -0x28(%rbp), %rax
movq %rax, -0x118(%rbp)
cmpq $0x0, %rax
je 0xcf44
movq -0x118(%rbp), %rdi
callq 0xd030
movq -0x118(%rbp), %rdi
movl $0x40, %esi
callq 0x2230
movq -0x40(%rbp), %rax
movq %rax, -0x120(%rbp)
cmpq $0x0, %rax
je 0xcf72
movq -0x120(%rbp), %rdi
callq 0xd050
movq -0x120(%rbp), %rdi
movl $0x60, %esi
callq 0x2230
movq -0x48(%rbp), %rax
movq %rax, -0x128(%rbp)
cmpq $0x0, %rax
je 0xcfa0
movq -0x128(%rbp), %rdi
callq 0xd080
movq -0x128(%rbp), %rdi
movl $0x70, %esi
callq 0x2230
movq -0x50(%rbp), %rax
movq %rax, -0x130(%rbp)
cmpq $0x0, %rax
je 0xcfce
movq -0x130(%rbp), %rdi
callq 0xd0d0
movq -0x130(%rbp), %rdi
movl $0x40, %esi
callq 0x2230
movl $0x0, -0x4(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x2160
movl -0x4(%rbp), %eax
addq $0x130, %rsp            # imm = 0x130
popq %rbp
retq
movq -0x30(%rbp), %rdi
callq 0x2390
movq %rax, %rdi
callq 0x4360
nop