// File: /workspace/github_cpp_makefile_star2_O2/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 %rbp
pushq %r14
pushq %rbx
subq $0x2d0, %rsp            # imm = 0x2D0
movq %rsi, %rbx
movl %edi, %ebp
xorl %edi, %edi
callq 0x92a0
movl %eax, %edi
callq 0x92c0
cmpl $0x2, %ebp
jne 0x13922
movq 0x8(%rbx), %rsi
leaq 0xc8(%rsp), %r14
pushq $0x8
popq %rdx
movq %r14, %rdi
callq 0x94f0
movq (%r14), %rax
movq -0x18(%rax), %rax
testb $0x5, 0xe8(%rsp,%rax)
je 0x13945
movq 0x486ae(%rip), %rdi     # 0x5bfa8
leaq 0x255f7(%rip), %rsi     # 0x38ef8
callq 0x92d0
movq 0x8(%rbx), %rsi
movq %rax, %rdi
callq 0x92d0
movq %rax, %rdi
callq 0x9140
pushq $-0x1
popq %rbx
jmp 0x13b76
movq 0x4867f(%rip), %rdi     # 0x5bfa8
leaq 0x255b3(%rip), %rsi     # 0x38ee3
callq 0x92d0
movq %rax, %rdi
callq 0x9140
pushq $-0x1
popq %rbx
jmp 0x13b83
movq 0x1b0(%rsp,%rax), %rsi
leaq 0x50(%rsp), %rax
movq %rax, -0x10(%rax)
leaq 0x40(%rsp), %rdi
pushq $-0x1
popq %rdx
xorl %ecx, %ecx
movl %edx, %r8d
callq 0x13c9a
movq 0x48639(%rip), %rdi     # 0x5bfa8
leaq 0x25595(%rip), %rsi     # 0x38f0b
callq 0x92d0
movq %rax, %rdi
callq 0x91d0
leaq 0x70(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x1aa1d
cmpb $0x1, 0xa0(%rsp)
jne 0x13a9f
movq 0x48601(%rip), %rdi     # 0x5bfa8
leaq 0x25569(%rip), %rsi     # 0x38f17
callq 0x92d0
movq %rax, %rdi
callq 0x9140
movq 0x485e6(%rip), %rdi     # 0x5bfa8
leaq 0x25556(%rip), %rsi     # 0x38f1f
callq 0x92d0
movq %rax, %rdi
callq 0x9140
movq 0x70(%rsp), %rsi
leaq 0x10(%rsp), %rdi
callq 0x222d4
cmpb $0x0, 0x30(%rsp)
je 0x13b0e
movq 0x70(%rsp), %rdi
callq 0x35cde
testb %al, %al
je 0x13b3b
movq 0x4859f(%rip), %rdi     # 0x5bfa8
leaq 0x25507(%rip), %rsi     # 0x38f17
callq 0x92d0
movq %rax, %rdi
callq 0x9140
movq 0x48584(%rip), %rdi     # 0x5bfa8
leaq 0x25528(%rip), %rsi     # 0x38f53
callq 0x92d0
movq %rax, %rbx
leaq 0x60(%rsp), %r14
leaq 0x70(%rsp), %rsi
movq %r14, %rdi
callq 0xbde0
movq %rsp, %rdi
movq %r14, %rsi
callq 0xb90d
movq (%rsp), %rsi
leaq 0xa8(%rsp), %rdi
callq 0xdaae
leaq 0xa8(%rsp), %rsi
movq %rbx, %rdi
callq 0x9290
leaq 0xa8(%rsp), %rdi
callq 0x9130
movq %rbx, %rdi
callq 0x9140
leaq 0x8(%rsp), %rdi
callq 0xa248
leaq 0x68(%rsp), %rdi
callq 0xa248
jmp 0x13b56
leaq 0x10(%rsp), %rdi
leaq 0x70(%rsp), %rsi
callq 0x13c1a
movq 0x484f3(%rip), %rdi     # 0x5bfa8
leaq 0x254c1(%rip), %rsi     # 0x38f7d
callq 0x92d0
movq 0x18(%rsp), %rsi
movq %rax, %rdi
callq 0x91c0
leaq 0x25473(%rip), %rsi     # 0x38f48
movq %rax, %rdi
callq 0x92d0
leaq 0x20(%rsp), %rbx
movq %rax, %rdi
movq %rbx, %rsi
callq 0x9290
movq %rax, %rdi
callq 0x9140
movq 0x18(%rsp), %rsi
leaq 0x40(%rsp), %rdi
callq 0x137a8
movq %rbx, %rdi
callq 0x9130
jmp 0x13b60
movq 0x48493(%rip), %rdi     # 0x5bfa8
leaq 0x25415(%rip), %rsi     # 0x38f31
callq 0x92d0
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x13c2e
movq %rbx, %rdi
movq %rax, %rsi
callq 0x9290
jmp 0x13b4e
movq 0x48466(%rip), %rdi     # 0x5bfa8
leaq 0x25403(%rip), %rsi     # 0x38f4c
callq 0x92d0
movq %rax, %rdi
callq 0x9140
leaq 0x10(%rsp), %rdi
callq 0x13c86
leaq 0x70(%rsp), %rdi
callq 0x13e4a
leaq 0x40(%rsp), %rdi
callq 0x9130
xorl %ebx, %ebx
leaq 0xc8(%rsp), %rdi
callq 0x90a0
movl %ebx, %eax
addq $0x2d0, %rsp            # imm = 0x2D0
popq %rbx
popq %r14
popq %rbp
retq
movq %rax, %rbx
leaq 0xa8(%rsp), %rdi
callq 0x9130
jmp 0x13bab
movq %rax, %rbx
jmp 0x13bb5
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
callq 0xa248
leaq 0x68(%rsp), %rdi
callq 0xa248
jmp 0x13bc8
jmp 0x13bd4
jmp 0x13c01
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x13c86
jmp 0x13beb
movq %rax, %rbx
jmp 0x13bf5
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x9130
jmp 0x13beb
movq %rax, %rbx
leaq 0x70(%rsp), %rdi
callq 0x13e4a
leaq 0x40(%rsp), %rdi
callq 0x9130
jmp 0x13c04
movq %rax, %rbx
leaq 0xc8(%rsp), %rdi
callq 0x90a0
movq %rbx, %rdi
callq 0x94d0
nop