// File: /workspace/github_cpp_makefile_star2_O1/pfnet-research[P]pml/src/main.cpp
// Function: main
int main(int argc, const char* argv[]) {
    std::srand((unsigned int)time(NULL));
#ifdef PML_TEST_BUILD
    test::run(argc, argv);
    return 0;
#endif

    using namespace ast;
    if (argc != 2) {
        std::cout << "[filename] required!" << std::endl;
        return -1;
    }

    std::ifstream input{argv[1]};
    if (input.fail()) {
        std::cout << "file open error : " << argv[1] << std::endl;
        return -1;
    }

    std::istreambuf_iterator<char> it{input}, last;
    std::string input_str{it, last};
    // TODO: be more elegant
    std::cout << "parsing .. " << std::flush;
    parser::parse(input_str).case_of(
        ok >> [](ptr<ast::expr_t> const& expr){
            std::cout << "passed!" << std::endl;
            std::cout << "type checking .. " << std::endl;
            auto const& simty_result = simty::simple_typing(*expr);
            if (simty_result.is_error()) {
                std::cout << "failed at simple typing : " << simty_result.error() << std::endl;
                return;
            }
            if (!typechecker::typecheck(*expr)) {
                std::cout << "failed" << std::endl;
                return;
            }
            std::cout << "passed!" << std::endl;
            std::cout << "=> " << evaluator::eval(expr) << std::endl;
        },
        error >> [&](parser::error_t err) {
            std::cout <<
                "fail error at " << err.pos << " : " <<
                err.message << std::endl;
            output_parse_error(input_str, err.pos);
        }
    );
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x2d0, %rsp            # imm = 0x2D0
movq %rsi, %r14
movl %edi, %ebx
xorl %edi, %edi
callq 0x9290
movl %eax, %edi
callq 0x92b0
cmpl $0x2, %ebx
jne 0x197bf
movq 0x8(%r14), %rsi
leaq 0xc8(%rsp), %rbx
movq %rbx, %rdi
movl $0x8, %edx
callq 0x9500
movq (%rbx), %rax
movq -0x18(%rax), %rax
testb $0x5, 0xe8(%rsp,%rax)
je 0x1980b
movq 0x49839(%rip), %rbx     # 0x62fb8
leaq 0x2e452(%rip), %rsi     # 0x47bd8
movl $0x12, %edx
movq %rbx, %rdi
callq 0x9350
movq 0x8(%r14), %r14
testq %r14, %r14
je 0x199cc
movq %r14, %rdi
callq 0x9120
movq 0x49809(%rip), %rdi     # 0x62fb8
movq %r14, %rsi
movq %rax, %rdx
callq 0x9350
jmp 0x199e3
movq 0x497f2(%rip), %rbx     # 0x62fb8
leaq 0x2e3f6(%rip), %rsi     # 0x47bc3
movl $0x14, %edx
movq %rbx, %rdi
callq 0x9350
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x92c0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x9030
movq %rax, %rdi
callq 0x91c0
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
jmp 0x19bbe
movq 0x1b0(%rsp,%rax), %rsi
leaq 0x50(%rsp), %r14
movq %r14, -0x10(%r14)
leaq 0x40(%rsp), %rdi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
xorl %ecx, %ecx
movl $0xffffffff, %r8d       # imm = 0xFFFFFFFF
callq 0x19dc6
movq 0x4977e(%rip), %rdi     # 0x62fb8
leaq 0x2e3aa(%rip), %rsi     # 0x47beb
movl $0xb, %edx
callq 0x9350
movq 0x49766(%rip), %rdi     # 0x62fb8
callq 0x91c0
leaq 0x90(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x246c1
cmpb $0x1, 0xc0(%rsp)
jne 0x19a18
movq 0x4973a(%rip), %rbx     # 0x62fb8
leaq 0x2e372(%rip), %rsi     # 0x47bf7
movl $0x7, %edx
movq %rbx, %rdi
callq 0x9350
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x92c0
movsbl %al, %esi
movq 0x49708(%rip), %rdi     # 0x62fb8
callq 0x9030
movq %rax, %rdi
callq 0x91c0
movq 0x496f4(%rip), %rbx     # 0x62fb8
leaq 0x2e334(%rip), %rsi     # 0x47bff
movl $0x11, %edx
movq %rbx, %rdi
callq 0x9350
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x92c0
movsbl %al, %esi
movq 0x496c2(%rip), %rdi     # 0x62fb8
callq 0x9030
movq %rax, %rdi
callq 0x91c0
movq 0x90(%rsp), %rsi
movq %rsp, %rdi
callq 0x2bc40
cmpb $0x0, 0x20(%rsp)
je 0x19af5
movq 0x90(%rsp), %rdi
callq 0x44d9a
testb %al, %al
je 0x19b41
movq 0x4967e(%rip), %rbx     # 0x62fb8
leaq 0x2e2b6(%rip), %rsi     # 0x47bf7
movl $0x7, %edx
movq %rbx, %rdi
callq 0x9350
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x92c0
movsbl %al, %esi
movq 0x4964c(%rip), %rdi     # 0x62fb8
callq 0x9030
movq %rax, %rdi
callq 0x91c0
movq 0x49638(%rip), %rdi     # 0x62fb8
leaq 0x2e2ac(%rip), %rsi     # 0x47c33
movl $0x3, %edx
callq 0x9350
movq 0x90(%rsp), %rcx
movq 0x98(%rsp), %rax
movq %rcx, 0x30(%rsp)
movq %rax, 0x38(%rsp)
testq %rax, %rax
je 0x19bd1
movq 0x495f5(%rip), %rcx     # 0x62fb0
cmpb $0x0, (%rcx)
je 0x19bcd
incl 0x8(%rax)
jmp 0x19bd1
movq (%rbx), %rax
movq -0x18(%rax), %rax
leaq (%rbx,%rax), %rdi
movl 0x20(%rbx,%rax), %esi
orl $0x1, %esi
callq 0x94a0
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x92c0
movsbl %al, %esi
movq 0x495b7(%rip), %rdi     # 0x62fb8
callq 0x9030
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
movq %rax, %rdi
callq 0x91c0
jmp 0x19bb1
movups 0x90(%rsp), %xmm0
leaq 0x10(%rsp), %rdi
movaps %xmm0, -0x10(%rdi)
leaq 0x20(%rsp), %r15
movq %r15, -0x10(%r15)
movq 0xa0(%rsp), %rsi
movq 0xa8(%rsp), %rdx
addq %rsi, %rdx
callq 0xad30
movq 0x49567(%rip), %rdi     # 0x62fb8
leaq 0x2e205(%rip), %rsi     # 0x47c5d
movl $0xe, %edx
callq 0x9350
movq 0x8(%rsp), %rsi
movq 0x4954a(%rip), %rdi     # 0x62fb8
callq 0x91b0
movq %rax, %rbx
leaq 0x2e1ab(%rip), %rsi     # 0x47c28
movl $0x3, %edx
movq %rax, %rdi
callq 0x9350
movq 0x10(%rsp), %rsi
movq 0x18(%rsp), %rdx
movq %rbx, %rdi
callq 0x9350
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x92c0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x9030
movq %rax, %rdi
callq 0x91c0
movq 0x8(%rsp), %rsi
leaq 0x40(%rsp), %rdi
callq 0x19584
movq 0x10(%rsp), %rdi
cmpq %r15, %rdi
je 0x19b8b
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x92e0
jmp 0x19b8b
movq 0x494bc(%rip), %rdi     # 0x62fb8
leaq 0x2e10e(%rip), %rsi     # 0x47c11
movl $0x1a, %edx
callq 0x9350
movq %rsp, %rdi
callq 0x19d3c
movq (%rax), %rsi
movq 0x8(%rax), %rdx
movq 0x49495(%rip), %rdi     # 0x62fb8
callq 0x9350
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x92c0
jmp 0x19b70
movq 0x49470(%rip), %rbx     # 0x62fb8
leaq 0x2e0dd(%rip), %rsi     # 0x47c2c
movl $0x6, %edx
movq %rbx, %rdi
callq 0x9350
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x92c0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x9030
movq %rax, %rdi
callq 0x91c0
movq %rsp, %rdi
callq 0x19d96
leaq 0x90(%rsp), %rdi
callq 0x1a10e
movq 0x40(%rsp), %rdi
cmpq %r14, %rdi
je 0x19baf
movq 0x50(%rsp), %rsi
incq %rsi
callq 0x92e0
xorl %ebx, %ebx
leaq 0xc8(%rsp), %rdi
callq 0x9090
movl %ebx, %eax
addq $0x2d0, %rsp            # imm = 0x2D0
popq %rbx
popq %r14
popq %r15
retq
lock
incl 0x8(%rax)
leaq 0x60(%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0xc8e6
movq 0x60(%rsp), %rsi
leaq 0x70(%rsp), %rdi
callq 0xeab5
movq 0x70(%rsp), %rsi
movq 0x78(%rsp), %rdx
movq 0x493b8(%rip), %rbx     # 0x62fb8
movq %rbx, %rdi
callq 0x9350
leaq 0x80(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x19c29
movq 0x80(%rsp), %rsi
incq %rsi
callq 0x92e0
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x92c0
movsbl %al, %esi
movq 0x49371(%rip), %rdi     # 0x62fb8
callq 0x9030
movq %rax, %rdi
callq 0x91c0
movq 0x68(%rsp), %rdi
testq %rdi, %rdi
je 0x19c63
callq 0xaa12
movq 0x38(%rsp), %rdi
testq %rdi, %rdi
je 0x19b83
callq 0xaa12
jmp 0x19b83
movq %rax, %rbx
leaq 0x80(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x19ca9
movq 0x80(%rsp), %rsi
incq %rsi
callq 0x92e0
jmp 0x19ca9
movq %rax, %rbx
jmp 0x19cb8
movq %rax, %rbx
movq 0x68(%rsp), %rdi
testq %rdi, %rdi
je 0x19cb8
callq 0xaa12
movq 0x38(%rsp), %rdi
testq %rdi, %rdi
je 0x19cd5
callq 0xaa12
jmp 0x19cd5
jmp 0x19ccd
jmp 0x19d24
movq %rax, %rbx
jmp 0x19d0b
movq %rax, %rbx
movq %rsp, %rdi
callq 0x19d96
jmp 0x19cfe
movq %rax, %rbx
movq 0x10(%rsp), %rdi
cmpq %r15, %rdi
je 0x19cfe
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x92e0
jmp 0x19cfe
movq %rax, %rbx
leaq 0x90(%rsp), %rdi
callq 0x1a10e
movq 0x40(%rsp), %rdi
cmpq %r14, %rdi
je 0x19d27
movq 0x50(%rsp), %rsi
incq %rsi
callq 0x92e0
jmp 0x19d27
movq %rax, %rbx
leaq 0xc8(%rsp), %rdi
callq 0x9090
movq %rbx, %rdi
callq 0x94e0