// File: /workspace/github_cpp_makefile_star2_O3/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 0x1958e
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 0x195da
movq 0x48a6a(%rip), %rbx     # 0x61fb8
leaq 0x2e683(%rip), %rsi     # 0x47bd8
movl $0x12, %edx
movq %rbx, %rdi
callq 0x9350
movq 0x8(%r14), %r14
testq %r14, %r14
je 0x1979b
movq %r14, %rdi
callq 0x9120
movq 0x48a3a(%rip), %rdi     # 0x61fb8
movq %r14, %rsi
movq %rax, %rdx
callq 0x9350
jmp 0x197b2
movq 0x48a23(%rip), %rbx     # 0x61fb8
leaq 0x2e627(%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 0x1998d
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 0x19b96
movq 0x489af(%rip), %rdi     # 0x61fb8
leaq 0x2e5db(%rip), %rsi     # 0x47beb
movl $0xb, %edx
callq 0x9350
movq 0x48997(%rip), %rdi     # 0x61fb8
callq 0x91c0
leaq 0x90(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x2458a
cmpb $0x1, 0xc0(%rsp)
jne 0x197e7
movq 0x4896b(%rip), %rbx     # 0x61fb8
leaq 0x2e5a3(%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 0x48939(%rip), %rdi     # 0x61fb8
callq 0x9030
movq %rax, %rdi
callq 0x91c0
movq 0x48925(%rip), %rbx     # 0x61fb8
leaq 0x2e565(%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 0x488f3(%rip), %rdi     # 0x61fb8
callq 0x9030
movq %rax, %rdi
callq 0x91c0
movq 0x90(%rsp), %rsi
movq %rsp, %rdi
callq 0x2ba98
cmpb $0x0, 0x20(%rsp)
je 0x198c4
movq 0x90(%rsp), %rdi
callq 0x4434a
testb %al, %al
je 0x19910
movq 0x488af(%rip), %rbx     # 0x61fb8
leaq 0x2e4e7(%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 0x4887d(%rip), %rdi     # 0x61fb8
callq 0x9030
movq %rax, %rdi
callq 0x91c0
movq 0x48869(%rip), %rdi     # 0x61fb8
leaq 0x2e4dd(%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 0x199a0
movq 0x48826(%rip), %rcx     # 0x61fb0
cmpb $0x0, (%rcx)
je 0x1999c
incl 0x8(%rax)
jmp 0x199a0
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 0x487e8(%rip), %rdi     # 0x61fb8
callq 0x9030
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
movq %rax, %rdi
callq 0x91c0
jmp 0x19980
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 0xac68
movq 0x48798(%rip), %rdi     # 0x61fb8
leaq 0x2e436(%rip), %rsi     # 0x47c5d
movl $0xe, %edx
callq 0x9350
movq 0x8(%rsp), %rsi
movq 0x4877b(%rip), %rdi     # 0x61fb8
callq 0x91b0
movq %rax, %rbx
leaq 0x2e3dc(%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 0x1934c
movq 0x10(%rsp), %rdi
cmpq %r15, %rdi
je 0x1995a
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x92e0
jmp 0x1995a
movq 0x486ed(%rip), %rdi     # 0x61fb8
leaq 0x2e33f(%rip), %rsi     # 0x47c11
movl $0x1a, %edx
callq 0x9350
movq %rsp, %rdi
callq 0x19b0c
movq (%rax), %rsi
movq 0x8(%rax), %rdx
movq 0x486c6(%rip), %rdi     # 0x61fb8
callq 0x9350
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x92c0
jmp 0x1993f
movq 0x486a1(%rip), %rbx     # 0x61fb8
leaq 0x2e30e(%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 0x19b66
leaq 0x90(%rsp), %rdi
callq 0x19f1e
movq 0x40(%rsp), %rdi
cmpq %r14, %rdi
je 0x1997e
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 0xc81d
movq 0x60(%rsp), %rsi
leaq 0x70(%rsp), %rdi
callq 0xe95c
movq 0x70(%rsp), %rsi
movq 0x78(%rsp), %rdx
movq 0x485e9(%rip), %rbx     # 0x61fb8
movq %rbx, %rdi
callq 0x9350
leaq 0x80(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x199f8
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 0x485a2(%rip), %rdi     # 0x61fb8
callq 0x9030
movq %rax, %rdi
callq 0x91c0
movq 0x68(%rsp), %rdi
testq %rdi, %rdi
je 0x19a32
callq 0xa946
movq 0x38(%rsp), %rdi
testq %rdi, %rdi
je 0x19952
callq 0xa946
jmp 0x19952
movq %rax, %rbx
leaq 0x80(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x19a78
movq 0x80(%rsp), %rsi
incq %rsi
callq 0x92e0
jmp 0x19a78
movq %rax, %rbx
jmp 0x19a87
movq %rax, %rbx
movq 0x68(%rsp), %rdi
testq %rdi, %rdi
je 0x19a87
callq 0xa946
movq 0x38(%rsp), %rdi
testq %rdi, %rdi
je 0x19aa4
callq 0xa946
jmp 0x19aa4
jmp 0x19a9c
jmp 0x19af3
movq %rax, %rbx
jmp 0x19ada
movq %rax, %rbx
movq %rsp, %rdi
callq 0x19b66
jmp 0x19acd
movq %rax, %rbx
movq 0x10(%rsp), %rdi
cmpq %r15, %rdi
je 0x19acd
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x92e0
jmp 0x19acd
movq %rax, %rbx
leaq 0x90(%rsp), %rdi
callq 0x19f1e
movq 0x40(%rsp), %rdi
cmpq %r14, %rdi
je 0x19af6
movq 0x50(%rsp), %rsi
incq %rsi
callq 0x92e0
jmp 0x19af6
movq %rax, %rbx
leaq 0xc8(%rsp), %rdi
callq 0x9090
movq %rbx, %rdi
callq 0x94e0
nop