// File: Eronana[P]strawberry/src/main.cpp
// Function: main
int main(int argc,char *argv[])
{
    if(argc==1)
    {
        printf("Usage: %s filename [options]\n",argv[0]);
        printf("\t -s compile script to assembly\n");
        printf("\t -x compile script to binary\n");
        printf("\t -c compile assembly to binary\n");
        printf("\t -o set output filename\n");
        return 0;
    }
    char *in=argv[1];
    const char *out=NULL;
    if(CodeData::check(in))
    {
        out=in;
    }
    else
    {
        int opt;
        if((opt=GETOPT("o")))out=argv[opt+1];
        bool s=GETOPT("s"),x=GETOPT("x"),c=GETOPT("c"),d=GETOPT("d");

        if(c)
        {
            SETOUT("out.bin")
            if(assemble(in,out))return 0;
            return 1;
        }
        if(d)
        {
            SETOUT("out.asm")
            if(disassemble(in,out))return 0;
            return 1;
        }
        Lexer lexer;
        if(!lexer.load(in))
        {
            fprintf(stderr,"cannot open %s\n",in);
            return 1;
        }
        if(s)SETOUT("out.asm")
        else if(x) SETOUT("out.bin")
        else SETOUT(tmpname())
        Parser parser(lexer);
        AST_PTR ast;
        const char *asm_out;
        try
        {
            ast=parser.parse();
            astMethodInit();
            ast->fill(nullptr);
            ast->check(nullptr);

            if(!x)asm_out=out;
            else asm_out=tmpname();
            FILE *fp=fopen(asm_out,"w");
            AST::fp=fp;
            ast->codeGen(nullptr);
            fclose(fp);
            if(s)return 0;
            int result=assemble(asm_out,out)?0:1;
            if(x||result)
            {
                remove(asm_out);
                return result;
            }
        }
        catch(Exception &e)
        {
            e.print(stderr);
            if(x)remove(asm_out);
            if(in!=out)remove(out);
            return 1;
        }

    }
    VirtualMachine vm;
    if(!vm.load(out))printf("cannot load %s\n",out);
    else if(in!=out)remove(out);;
    vm.run();
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x610, %rsp            # imm = 0x610
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpl $0x1, -0x8(%rbp)
jne 0x88d8
movq -0x10(%rbp), %rax
movq (%rax), %rsi
leaq 0x4f777(%rip), %rdi     # 0x58004
movb $0x0, %al
callq 0x7060
leaq 0x4f787(%rip), %rdi     # 0x58022
movb $0x0, %al
callq 0x7060
leaq 0x4f79a(%rip), %rdi     # 0x58043
movb $0x0, %al
callq 0x7060
leaq 0x4f7ab(%rip), %rdi     # 0x58062
movb $0x0, %al
callq 0x7060
leaq 0x4f7be(%rip), %rdi     # 0x58083
movb $0x0, %al
callq 0x7060
movl $0x0, -0x4(%rbp)
jmp 0x8e5b
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x18(%rbp)
movq $0x0, -0x20(%rbp)
movq -0x18(%rbp), %rdi
callq 0x50f30
testb $0x1, %al
jne 0x88fb
jmp 0x8908
movq -0x18(%rbp), %rax
movq %rax, -0x20(%rbp)
jmp 0x8db7
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
leaq 0x50194(%rip), %rdx     # 0x58aaa
callq 0x87c0
movl %eax, -0x24(%rbp)
cmpl $0x0, %eax
je 0x8938
movq -0x10(%rbp), %rax
movl -0x24(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x20(%rbp)
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
leaq 0x50bfe(%rip), %rdx     # 0x59544
callq 0x87c0
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, -0x25(%rbp)
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
leaq 0x4f739(%rip), %rdx     # 0x5809d
callq 0x87c0
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, -0x26(%rbp)
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
leaq 0x4f842(%rip), %rdx     # 0x581c4
callq 0x87c0
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, -0x27(%rbp)
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
leaq 0x50b9a(%rip), %rdx     # 0x5953a
callq 0x87c0
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, -0x28(%rbp)
testb $0x1, -0x27(%rbp)
je 0x89f3
cmpq $0x0, -0x20(%rbp)
jne 0x89c8
leaq 0x4f6db(%rip), %rax     # 0x5809f
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x436d0
testb $0x1, %al
jne 0x89db
jmp 0x89e7
movl $0x0, -0x4(%rbp)
jmp 0x8e5b
movl $0x1, -0x4(%rbp)
jmp 0x8e5b
testb $0x1, -0x28(%rbp)
je 0x8a36
cmpq $0x0, -0x20(%rbp)
jne 0x8a0b
leaq 0x4f6a0(%rip), %rax     # 0x580a7
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x4dba0
testb $0x1, %al
jne 0x8a1e
jmp 0x8a2a
movl $0x0, -0x4(%rbp)
jmp 0x8e5b
movl $0x1, -0x4(%rbp)
jmp 0x8e5b
leaq -0x58(%rbp), %rdi
movq %rdi, -0x5d8(%rbp)
callq 0x8e80
movq -0x5d8(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x4ebe0
movb %al, -0x5c9(%rbp)
jmp 0x8a5e
movb -0x5c9(%rbp), %al
testb $0x1, %al
jne 0x8aaa
jmp 0x8a6a
movq 0x81567(%rip), %rax     # 0x89fd8
movq (%rax), %rdi
movq -0x18(%rbp), %rdx
leaq 0x4f630(%rip), %rsi     # 0x580af
movb $0x0, %al
callq 0x74c0
movl $0x1, -0x4(%rbp)
movl $0x1, -0x68(%rbp)
jmp 0x8d78
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x8da9
testb $0x1, -0x25(%rbp)
je 0x8ac4
cmpq $0x0, -0x20(%rbp)
jne 0x8ac2
leaq 0x4f5e9(%rip), %rax     # 0x580a7
movq %rax, -0x20(%rbp)
jmp 0x8b02
testb $0x1, -0x26(%rbp)
je 0x8ade
cmpq $0x0, -0x20(%rbp)
jne 0x8adc
leaq 0x4f5c7(%rip), %rax     # 0x5809f
movq %rax, -0x20(%rbp)
jmp 0x8b00
cmpq $0x0, -0x20(%rbp)
jne 0x8afe
callq 0x8840
movq %rax, -0x5e0(%rbp)
jmp 0x8af3
movq -0x5e0(%rbp), %rax
movq %rax, -0x20(%rbp)
jmp 0x8b00
jmp 0x8b02
leaq -0x90(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x30d30
jmp 0x8b14
leaq -0x98(%rbp), %rdi
callq 0x8eb0
leaq -0xa8(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x30d70
jmp 0x8b35
leaq -0x98(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
movq %rsi, -0x5e8(%rbp)
callq 0x8ee0
movq -0x5e8(%rbp), %rdi
callq 0x8f10
callq 0x19f10
jmp 0x8b62
leaq -0x98(%rbp), %rdi
callq 0x8f60
movq %rax, %rdi
movq (%rdi), %rax
movq 0x8(%rax), %rax
xorl %ecx, %ecx
movl %ecx, %esi
callq *%rax
jmp 0x8b80
leaq -0x98(%rbp), %rdi
callq 0x8f60
movq %rax, %rdi
movq (%rdi), %rax
movq 0x10(%rax), %rax
xorl %ecx, %ecx
movl %ecx, %esi
callq *%rax
jmp 0x8b9e
testb $0x1, -0x26(%rbp)
jne 0x8c10
movq -0x20(%rbp), %rax
movq %rax, -0xa0(%rbp)
jmp 0x8c2c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
movl -0x64(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x8d91
movq -0x60(%rbp), %rdi
callq 0x7110
movq %rax, -0xc0(%rbp)
movq -0xc0(%rbp), %rdi
movq 0x813ed(%rip), %rax     # 0x89fd8
movq (%rax), %rsi
callq 0xacf0
jmp 0x8bf5
testb $0x1, -0x26(%rbp)
je 0x8d1f
movq -0xa0(%rbp), %rdi
callq 0x7610
jmp 0x8d1f
callq 0x8840
movq %rax, -0x5f0(%rbp)
jmp 0x8c1e
movq -0x5f0(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq -0xa0(%rbp), %rdi
leaq 0x4f598(%rip), %rsi     # 0x581d2
callq 0x73b0
movq %rax, -0x5f8(%rbp)
jmp 0x8c48
movq -0x5f8(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0xb0(%rbp), %rcx
leaq 0x81c84(%rip), %rax     # 0x8a8e8
movq %rcx, (%rax)
leaq -0x98(%rbp), %rdi
callq 0x8f60
movq %rax, %rdi
movq (%rdi), %rax
movq 0x18(%rax), %rax
xorl %ecx, %ecx
movl %ecx, %esi
callq *%rax
jmp 0x8c85
movq -0xb0(%rbp), %rdi
callq 0x72b0
jmp 0x8c93
testb $0x1, -0x25(%rbp)
je 0x8cac
movl $0x0, -0x4(%rbp)
movl $0x1, -0x68(%rbp)
jmp 0x8d60
movq -0xa0(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x436d0
movb %al, -0x5f9(%rbp)
jmp 0x8cc4
movb -0x5f9(%rbp), %dl
movl $0x1, %eax
xorl %ecx, %ecx
testb $0x1, %dl
cmovnel %ecx, %eax
movl %eax, -0xb4(%rbp)
testb $0x1, -0x26(%rbp)
jne 0x8cec
cmpl $0x0, -0xb4(%rbp)
je 0x8d0a
movq -0xa0(%rbp), %rdi
callq 0x7610
movl -0xb4(%rbp), %eax
movl %eax, -0x4(%rbp)
movl $0x1, -0x68(%rbp)
jmp 0x8d60
jmp 0x8d59
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
callq 0x7570
jmp 0x8d57
movq -0x18(%rbp), %rax
cmpq -0x20(%rbp), %rax
je 0x8d32
movq -0x20(%rbp), %rdi
callq 0x7610
movl $0x1, -0x4(%rbp)
movl $0x1, -0x68(%rbp)
callq 0x7570
jmp 0x8d47
jmp 0x8d60
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x8d91
jmp 0x8d91
movl $0x0, -0x68(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x8f10
leaq -0x90(%rbp), %rdi
callq 0x8f90
leaq -0x58(%rbp), %rdi
callq 0x4ec40
movl -0x68(%rbp), %eax
testl %eax, %eax
je 0x8d8f
jmp 0x8d8a
jmp 0x8e5b
jmp 0x8db7
leaq -0x98(%rbp), %rdi
callq 0x8f10
leaq -0x90(%rbp), %rdi
callq 0x8f90
leaq -0x58(%rbp), %rdi
callq 0x4ec40
jmp 0x8e67
leaq -0x5c8(%rbp), %rdi
movq %rdi, -0x608(%rbp)
callq 0xd980
movq -0x608(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0xf2f0
movb %al, -0x5fa(%rbp)
jmp 0x8de2
movb -0x5fa(%rbp), %al
testb $0x1, %al
jne 0x8e1e
jmp 0x8dee
movq -0x20(%rbp), %rsi
leaq 0x4f2c6(%rip), %rdi     # 0x580bf
xorl %eax, %eax
callq 0x7060
jmp 0x8e02
jmp 0x8e33
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x5c8(%rbp), %rdi
callq 0x8fb0
jmp 0x8e67
movq -0x18(%rbp), %rax
cmpq -0x20(%rbp), %rax
je 0x8e31
movq -0x20(%rbp), %rdi
callq 0x7610
jmp 0x8e33
leaq -0x5c8(%rbp), %rdi
callq 0xf5a0
jmp 0x8e41
movl $0x0, -0x4(%rbp)
movl $0x1, -0x68(%rbp)
leaq -0x5c8(%rbp), %rdi
callq 0x8fb0
movl -0x4(%rbp), %eax
addq $0x610, %rsp            # imm = 0x610
popq %rbp
retq
movq -0x60(%rbp), %rdi
callq 0x75e0
movq %rax, %rdi
callq 0x8f80
nopl (%rax,%rax)