// File: /workspace/github_c_makefile_star2_O1/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 0x3e8c
xorl %ebx, %ebx
xorl %eax, %eax
callq 0x4440
movq %rax, %r14
movq %rax, %rdi
movq %r15, %rsi
callq 0x445c
cmpl $0x0, 0x800(%r15)
je 0x4245
xorl %eax, %eax
callq 0x561c
movq %rax, %rbx
movq %rax, %rdi
movq %r14, %rsi
callq 0x5638
movq %rsp, %rsi
movq %rbx, %rdi
callq 0x563c
testl %eax, %eax
je 0x4262
leaq 0x10(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rsi
callq 0x5a04
movq %r15, %rdi
callq 0x1549
movq %r14, %rdi
callq 0x4dee
movq %rbx, %rdi
callq 0x59ff
movl $0x1, %ebx
jmp 0x43b1
leaq 0x468(%rsp), %rdi
movq %r14, %rsi
callq 0x4125
movq %r14, %rdi
callq 0x4dee
jmp 0x43b1
cmpl $0x1, 0x868(%rsp)
jne 0x429d
leaq 0x468(%rsp), %rdi
movq (%rsp), %rsi
callq 0x4155
movq %r14, %rdi
callq 0x4dee
movq %rbx, %rdi
callq 0x59ff
movq (%rsp), %rdi
callq 0x8215
xorl %ebx, %ebx
jmp 0x43b1
movq %r14, %rdi
callq 0x4dee
movq %rbx, %rdi
callq 0x59ff
xorl %eax, %eax
callq 0xaee9
movq %rax, %rbx
movq (%rsp), %rsi
movq %rax, %rdi
callq 0xaf05
leaq 0x8(%rsp), %rsi
movq %rbx, %rdi
callq 0xaf1a
testl %eax, %eax
je 0x4307
leaq 0x10(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0xbd03
movq %r14, %rdi
callq 0x2570
movq (%rsp), %rdi
callq 0x8215
movq %rbx, %rdi
callq 0xb904
movl $0x2, %ebx
jmp 0x43b1
movq (%rsp), %rdi
callq 0x8215
cmpl $0x2, 0x868(%rsp)
jne 0x4343
leaq 0x468(%rsp), %rdi
movq 0x8(%rsp), %rsi
callq 0x4185
movq %rbx, %rdi
callq 0xb904
movq 0x8(%rsp), %rdi
callq 0xb8d3
jmp 0x4296
movq %rbx, %rdi
callq 0xb904
xorl %ebx, %ebx
xorl %eax, %eax
callq 0xd730
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 0xd74c
movq %r14, %rdi
callq 0xd8b2
movq %rax, %r15
movq 0x8(%rsp), %rdi
callq 0xb8d3
movq %r14, %rdi
callq 0xe2d3
leaq 0xacee(%rip), %rdi      # 0xf095
movl %r15d, %esi
xorl %eax, %eax
callq 0x10a0
movl %ebx, %eax
addq $0x880, %rsp            # imm = 0x880
popq %rbx
popq %r14
popq %r15
retq