// File: /workspace/github_c_makefile_star2_O3/masyagin1998[P]GCI/src/interpreter.c
// Function: main
int main(int argc, char**argv)
{
    int r = 0;
    
    struct INTERPRETER_PARAMS params;
    lexer_type_t  lexer;
    parser_type_t parser;
    bytecode_generator_type_t bc_gen;
    virtual_machine_type_t vm;

    struct UNIT_AST*unit;
    bytecode_type_t bc;

    parse_args(argc, argv, &params);

    lexer = create_lexer();
    lexer_conf_from_file(lexer, params.in);

    if (params.mode == INTERPRETER_LEX) {
        print_lexer_result(params.out, lexer);
        lexer_free(lexer);
        return 0;
    }

    parser = create_parser();
    parser_conf(parser, lexer);
    r = parser_parse(parser, &unit);
    if (r != PARSER_OK) {
        struct PARSER_ERROR err = parser_get_error(parser);
        print_parser_error(&err);
        lexer_free(lexer);
        parser_free(parser);
        return 1;
    }

    if (params.mode == INTERPRETER_PARSE) {
        print_parser_result(params.out, unit);
        lexer_free(lexer);
        parser_free(parser);
        unit_ast_free(unit);
        return 0;
    }

    lexer_free(lexer);
    parser_free(parser);

    bc_gen = create_bytecode_generator();
    bytecode_generator_conf(bc_gen, unit);
    
    r = bytecode_generator_generate(bc_gen, &bc);
    if (r != BYTECODE_GENERATOR_OK) {
        struct BYTECODE_ERROR err = bytecode_generator_get_error(bc_gen);
        print_bytecode_error(&err);
        unit_ast_free(unit);
        bytecode_generator_free(bc_gen);
        return 2;
    }

    unit_ast_free(unit);

    if (params.mode == INTERPRETER_BC) {
        print_bytecode_result(params.out, bc);
        bytecode_generator_free(bc_gen);
        bytecode_free(bc);
        return 0;
    }
    
    bytecode_generator_free(bc_gen);

    vm = create_virtual_machine();
    virtual_machine_conf(vm, bc, params.stacksize, params.heapsize, params.mode == INTERPRETER_TRACE);
    r = virtual_machine_run(vm);
    bytecode_free(bc);
    virtual_machine_free(vm);

    printf("result: %d\n", r);

    return 0;
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x880, %rsp            # imm = 0x880
leaq 0x68(%rsp), %r15
movq %r15, %rdx
callq 0x3eac
xorl %ebx, %ebx
xorl %eax, %eax
callq 0x4464
movq %rax, %r14
movq %rax, %rdi
movq %r15, %rsi
callq 0x4480
cmpl $0x0, 0x800(%r15)
je 0x4266
xorl %eax, %eax
callq 0x55e0
movq %rax, %rbx
movq %rax, %rdi
movq %r14, %rsi
callq 0x55fc
movq %rsp, %rsi
movq %rbx, %rdi
callq 0x5600
testl %eax, %eax
je 0x4283
leaq 0x10(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rsi
callq 0x59af
movq %r15, %rdi
callq 0x1567
movq %r14, %rdi
callq 0x4df3
movq %rbx, %rdi
callq 0x59aa
movl $0x1, %ebx
jmp 0x43d2
leaq 0x468(%rsp), %rdi
movq %r14, %rsi
callq 0x4146
movq %r14, %rdi
callq 0x4df3
jmp 0x43d2
cmpl $0x1, 0x868(%rsp)
jne 0x42be
leaq 0x468(%rsp), %rdi
movq (%rsp), %rsi
callq 0x4176
movq %r14, %rdi
callq 0x4df3
movq %rbx, %rdi
callq 0x59aa
movq (%rsp), %rdi
callq 0x7e9d
xorl %ebx, %ebx
jmp 0x43d2
movq %r14, %rdi
callq 0x4df3
movq %rbx, %rdi
callq 0x59aa
xorl %eax, %eax
callq 0xaaf0
movq %rax, %rbx
movq (%rsp), %rsi
movq %rax, %rdi
callq 0xab0c
leaq 0x8(%rsp), %rsi
movq %rbx, %rdi
callq 0xab21
testl %eax, %eax
je 0x4328
leaq 0x10(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0xb93e
movq %r14, %rdi
callq 0x258e
movq (%rsp), %rdi
callq 0x7e9d
movq %rbx, %rdi
callq 0xb547
movl $0x2, %ebx
jmp 0x43d2
movq (%rsp), %rdi
callq 0x7e9d
cmpl $0x2, 0x868(%rsp)
jne 0x4364
leaq 0x468(%rsp), %rdi
movq 0x8(%rsp), %rsi
callq 0x41a6
movq %rbx, %rdi
callq 0xb547
movq 0x8(%rsp), %rdi
callq 0xb522
jmp 0x42b7
movq %rbx, %rdi
callq 0xb547
xorl %ebx, %ebx
xorl %eax, %eax
callq 0xd418
movq %rax, %r14
movq 0x8(%rsp), %rsi
movq 0x870(%rsp), %rdx
movq 0x878(%rsp), %rcx
xorl %r8d, %r8d
cmpl $0x4, 0x868(%rsp)
sete %r8b
movq %rax, %rdi
callq 0xd434
movq %r14, %rdi
callq 0xd59a
movq %rax, %r15
movq 0x8(%rsp), %rdi
callq 0xb522
movq %r14, %rdi
callq 0xdf60
leaq 0xacca(%rip), %rdi      # 0xf092
movl %r15d, %esi
xorl %eax, %eax
callq 0x10a0
movl %ebx, %eax
addq $0x880, %rsp            # imm = 0x880
popq %rbx
popq %r14
popq %r15
retq
nopl (%rax)