// File: /workspace/github_c_makefile_star2_O0/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 %rbp
movq %rsp, %rbp
subq $0x8f0, %rsp            # imm = 0x8F0
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0x0, -0x14(%rbp)
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
leaq -0x830(%rbp), %rdx
callq 0x1280
movb $0x0, %al
callq 0x1cc0
movq %rax, -0x838(%rbp)
movq -0x838(%rbp), %rdi
leaq -0x830(%rbp), %rsi
callq 0x1d30
cmpl $0x0, -0x30(%rbp)
jne 0x198c
leaq -0x830(%rbp), %rdi
addq $0x400, %rdi            # imm = 0x400
movq -0x838(%rbp), %rsi
callq 0x1840
movq -0x838(%rbp), %rdi
callq 0x2a00
movl $0x0, -0x4(%rbp)
jmp 0x1bc5
movb $0x0, %al
callq 0x3630
movq %rax, -0x840(%rbp)
movq -0x840(%rbp), %rdi
movq -0x838(%rbp), %rsi
callq 0x36a0
movq -0x840(%rbp), %rdi
leaq -0x858(%rbp), %rsi
callq 0x36c0
movl %eax, -0x14(%rbp)
cmpl $0x0, -0x14(%rbp)
je 0x1a0c
movq -0x840(%rbp), %rsi
leaq -0x8b8(%rbp), %rdi
callq 0x3930
leaq -0x8b8(%rbp), %rdi
callq 0x3d80
movq -0x838(%rbp), %rdi
callq 0x2a00
movq -0x840(%rbp), %rdi
callq 0x3900
movl $0x1, -0x4(%rbp)
jmp 0x1bc5
cmpl $0x1, -0x30(%rbp)
jne 0x1a5c
leaq -0x830(%rbp), %rdi
addq $0x400, %rdi            # imm = 0x400
movq -0x858(%rbp), %rsi
callq 0x1880
movq -0x838(%rbp), %rdi
callq 0x2a00
movq -0x840(%rbp), %rdi
callq 0x3900
movq -0x858(%rbp), %rdi
callq 0x87f0
movl $0x0, -0x4(%rbp)
jmp 0x1bc5
movq -0x838(%rbp), %rdi
callq 0x2a00
movq -0x840(%rbp), %rdi
callq 0x3900
movb $0x0, %al
callq 0xda00
movq %rax, -0x848(%rbp)
movq -0x848(%rbp), %rdi
movq -0x858(%rbp), %rsi
callq 0xda70
movq -0x848(%rbp), %rdi
leaq -0x860(%rbp), %rsi
callq 0xdac0
movl %eax, -0x14(%rbp)
cmpl $0x0, -0x14(%rbp)
je 0x1af4
movq -0x848(%rbp), %rsi
leaq -0x8e8(%rbp), %rdi
callq 0xe5a0
leaq -0x8e8(%rbp), %rdi
callq 0xe5d0
movq -0x858(%rbp), %rdi
callq 0x87f0
movq -0x848(%rbp), %rdi
callq 0xde20
movl $0x2, -0x4(%rbp)
jmp 0x1bc5
movq -0x858(%rbp), %rdi
callq 0x87f0
cmpl $0x2, -0x30(%rbp)
jne 0x1b44
leaq -0x830(%rbp), %rdi
addq $0x400, %rdi            # imm = 0x400
movq -0x860(%rbp), %rsi
callq 0x18c0
movq -0x848(%rbp), %rdi
callq 0xde20
movq -0x860(%rbp), %rdi
callq 0xddc0
movl $0x0, -0x4(%rbp)
jmp 0x1bc5
movq -0x848(%rbp), %rdi
callq 0xde20
movb $0x0, %al
callq 0x13fd0
movq %rax, -0x850(%rbp)
movq -0x850(%rbp), %rdi
movq -0x860(%rbp), %rsi
movq -0x28(%rbp), %rdx
movq -0x20(%rbp), %rcx
cmpl $0x4, -0x30(%rbp)
sete %al
andb $0x1, %al
movzbl %al, %r8d
callq 0x14040
movq -0x850(%rbp), %rdi
callq 0x14300
movl %eax, -0x14(%rbp)
movq -0x860(%rbp), %rdi
callq 0xddc0
movq -0x850(%rbp), %rdi
callq 0x15cf0
movl -0x14(%rbp), %esi
leaq 0x164be(%rip), %rdi     # 0x18075
movb $0x0, %al
callq 0x1090
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x8f0, %rsp            # imm = 0x8F0
popq %rbp
retq
nopw %cs:(%rax,%rax)
nopl (%rax,%rax)