// File: /workspace/github_cpp_makefile_star2_O2/pointwiseproduct[P]untyped_lambda/untyped_lambda.cpp
// Function: main
int main(int argc, char *argv[]){
    if(argc <= 1){
        launch_interpreter();
        return 0;
    }

    program_switchs.insert("-b");
    for(int i = 2; i < argc; ++i){
        std::string str(argv[i]);
        if(str == "-o"){
            auto iter = program_switchs.find("-b");
            if(iter != program_switchs.end()){
                program_switchs.erase(iter);
            }
        }else if(str == "-b"){
            auto iter = program_switchs.find("-o");
            if(iter != program_switchs.end()){
                program_switchs.erase(iter);
            }
        }
        program_switchs.insert(str);
    }

    if(program_switchs.find("-h") != program_switchs.end() || program_switchs.find("--help") != program_switchs.end()){
        std::cout << "untyped lambda calcus ver 1.0.0" << std::endl;
        std::cout << "usage:" << std::endl;
        std::cout << "  untyped_lambda ifile_path.txt {option}" << std::endl;
        std::cout << std::endl;
        std::cout << "option:" << std::endl;
        // �w���v���b�Z�[�W���\�������D
        std::cout << "  --help:" << std::endl;
        std::cout << "      -h: show this message." << std::endl;
        // �e���̕]���O�̒l���\�������D
        std::cout << "      -b: show before evaluation of fomulas. [default]" << std::endl;
        // �e���̕]�����ʂ̂ݕ\�������D
        std::cout << "      -o: show only evaluation results." << std::endl;
        // ���̕]�����ƂɈꎞ���~�����D
        std::cout << "      -s: step evaluation." << std::endl << std::endl;

        return 0;
    }

    try{
        const fs::path ifile_path(argv[1]);
        check_file_exist(ifile_path);
        std::vector<char> str = open_file(ifile_path);
        auto a = tokenize_phase1::tokenize(str);
        auto b = tokenize_phase2::tokenize(a);
        if(!parsing_phase::lines(b.begin())){
            throw parsing_failed();
        }

        bool program_swtich_s = program_switchs.find("-s") != program_switchs.end();
        bool program_swtich_b = program_switchs.find("-b") != program_switchs.end();
        for(auto &i : internal_data::lines){
            std::unique_ptr<internal_data::expr> q((i->copy()));
            if(program_swtich_b || program_swtich_s){
                std::cout << i->to_str() << std::endl;
                if(program_swtich_s){
                    waiting();
                }
                internal_data::global_variable_replace(q);
                std::cout << q->to_str() << std::endl;
                if(program_swtich_s){
                    waiting();
                }
            }
            while(true){
                try{
                    int nest_level = 0;
                    bool mod = false;
                    //internal_data::eval2(q, true, mod, true);
                    if(internal_data::lo_most_reduction(q)){
                        throw internal_data::step_out();
                    }
                }catch(internal_data::step_out){
                    if(program_swtich_s){
                        std::cout << q->to_str() << "." << std::endl;
                        waiting();
                    }
                    continue;
                }
                break;
            }
            if(program_swtich_b || program_swtich_s){
                std::cout << "-> ";
            }
            std::cout << q->to_str() << "." << std::endl;
        }
    }catch(app_exception e){
        std::cerr << e.what() << std::endl;
    }

    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movq %rsi, 0x18(%rsp)
cmpl $0x1, %edi
jg 0x5040
callq 0x4bdf
jmp 0x52d6
movl %edi, %ebp
leaq 0x40b0(%rip), %rsi      # 0x90f9
leaq 0x40(%rsp), %rdi
leaq 0x20(%rsp), %rdx
callq 0x30f0
leaq 0x91c9(%rip), %rdi      # 0xe228
leaq 0x40(%rsp), %rsi
callq 0x81a8
leaq 0x40(%rsp), %r14
movq %r14, %rdi
callq 0x3130
movl %ebp, %ebx
pushq $0x2
popq %r12
leaq 0x20(%rsp), %r15
leaq 0x91a0(%rip), %rbp      # 0xe228
cmpq %r12, %rbx
je 0x516a
movq 0x18(%rsp), %rax
movq (%rax,%r12,8), %rsi
movq %r14, %rdi
movq %r15, %rdx
callq 0x30f0
movq %r14, %rdi
leaq 0x404d(%rip), %rsi      # 0x90fc
callq 0x5bb0
testb %al, %al
je 0x50fb
movq %r15, %rdi
leaq 0x4037(%rip), %rsi      # 0x90f9
leaq 0x60(%rsp), %rdx
callq 0x30f0
movq %rbp, %rdi
movq %r15, %rsi
callq 0x8340
movq %rax, %r13
movq %r15, %rdi
callq 0x3130
leaq 0x9147(%rip), %rax      # 0xe230
cmpq %rax, %r13
je 0x514f
movq %rbp, %rdi
movq %r13, %rsi
callq 0x83b6
jmp 0x514f
movq %r14, %rdi
leaq 0x3ff4(%rip), %rsi      # 0x90f9
callq 0x5bb0
testb %al, %al
je 0x514f
movq %r15, %rdi
leaq 0x3fe4(%rip), %rsi      # 0x90fc
leaq 0x60(%rsp), %rdx
callq 0x30f0
movq %rbp, %rdi
movq %r15, %rsi
callq 0x8340
movq %rax, %r13
movq %r15, %rdi
callq 0x3130
leaq 0x90f1(%rip), %rax      # 0xe230
cmpq %rax, %r13
je 0x514f
movq %rbp, %rdi
movq %r13, %rsi
callq 0x83b6
movq %rbp, %rdi
movq %r14, %rsi
callq 0x8404
movq %r14, %rdi
callq 0x3130
incq %r12
jmp 0x5088
leaq 0x3f8e(%rip), %rsi      # 0x90ff
leaq 0x40(%rsp), %rdi
leaq 0x60(%rsp), %rdx
callq 0x30f0
leaq 0x90a1(%rip), %rdi      # 0xe228
leaq 0x40(%rsp), %rsi
callq 0x8340
leaq 0x9098(%rip), %r12      # 0xe230
cmpq %r12, %rax
je 0x51a9
leaq 0x40(%rsp), %rdi
callq 0x3130
jmp 0x51f0
leaq 0x3f52(%rip), %rsi      # 0x9102
leaq 0x20(%rsp), %rdi
leaq 0x78(%rsp), %rdx
callq 0x30f0
leaq 0x9062(%rip), %rdi      # 0xe228
leaq 0x20(%rsp), %rsi
callq 0x8340
movq %rax, %r14
leaq 0x20(%rsp), %rdi
callq 0x3130
leaq 0x40(%rsp), %rdi
callq 0x3130
cmpq %r12, %r14
je 0x52ea
movq 0x8dd1(%rip), %rbx      # 0xdfc8
leaq 0x3f0b(%rip), %rsi      # 0x9109
movq %rbx, %rdi
callq 0x3210
movq %rax, %rdi
callq 0x3140
leaq 0x3f14(%rip), %rsi      # 0x9129
movq %rbx, %rdi
callq 0x3210
movq %rax, %rdi
callq 0x3140
leaq 0x3f04(%rip), %rsi      # 0x9130
movq %rbx, %rdi
callq 0x3210
movq %rax, %rdi
callq 0x3140
movq %rbx, %rdi
callq 0x3140
leaq 0x3f0e(%rip), %rsi      # 0x9159
movq %rbx, %rdi
callq 0x3210
movq %rax, %rdi
callq 0x3140
leaq 0x3eff(%rip), %rsi      # 0x9161
movq %rbx, %rdi
callq 0x3210
movq %rax, %rdi
callq 0x3140
leaq 0x3ef2(%rip), %rsi      # 0x916b
movq %rbx, %rdi
callq 0x3210
movq %rax, %rdi
callq 0x3140
leaq 0x3ef8(%rip), %rsi      # 0x9188
movq %rbx, %rdi
callq 0x3210
movq %rax, %rdi
callq 0x3140
leaq 0x3f18(%rip), %rsi      # 0x91bf
movq %rbx, %rdi
callq 0x3210
movq %rax, %rdi
callq 0x3140
leaq 0x3f29(%rip), %rsi      # 0x91e7
movq %rbx, %rdi
callq 0x3210
movq %rax, %rdi
callq 0x3140
movq %rax, %rdi
callq 0x3140
xorl %eax, %eax
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x18(%rsp), %rax
movq 0x8(%rax), %rsi
leaq 0x40(%rsp), %rdi
callq 0x5c66
leaq 0x40(%rsp), %rdi
callq 0x361c
leaq 0x60(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x36a5
leaq 0x78(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0x3863
leaq 0x90(%rsp), %rdi
leaq 0x78(%rsp), %rsi
callq 0x3b10
movq 0x90(%rsp), %rdi
callq 0x4ba7
testb %al, %al
je 0x55ae
leaq 0x3eaf(%rip), %rsi      # 0x9202
leaq 0x20(%rsp), %rdi
leaq 0x10(%rsp), %rdx
callq 0x30f0
leaq 0x8ebf(%rip), %rdi      # 0xe228
leaq 0x20(%rsp), %rsi
callq 0x8340
movq %rax, 0x18(%rsp)
leaq 0x20(%rsp), %rdi
callq 0x3130
leaq 0x3d70(%rip), %rsi      # 0x90f9
leaq 0x20(%rsp), %rdi
leaq 0x10(%rsp), %rdx
callq 0x30f0
leaq 0x8e89(%rip), %rdi      # 0xe228
leaq 0x20(%rsp), %rsi
callq 0x8340
movq %rax, %rbx
movq 0x18(%rsp), %r15
xorq %r12, %r15
xorq %r12, %rbx
leaq 0x20(%rsp), %r12
movq %r12, %rdi
callq 0x3130
movq 0x8ebd(%rip), %rbp      # 0xe288
movq 0x8ebe(%rip), %r14      # 0xe290
orq %r15, %rbx
setne %bl
movq 0x8be9(%rip), %r13      # 0xdfc8
cmpq %r14, %rbp
je 0x557e
movq (%rbp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq %rax, 0x10(%rsp)
testb %bl, %bl
je 0x5480
movq (%rbp), %rsi
movq (%rsi), %rax
movq %r12, %rdi
callq *0x20(%rax)
movq %r13, %rdi
movq %r12, %rsi
callq 0x31f0
movq %rax, %rdi
callq 0x3140
movq %r12, %rdi
callq 0x3130
leaq 0x8e02(%rip), %rax      # 0xe230
cmpq %rax, 0x18(%rsp)
je 0x543a
callq 0x32f0
leaq 0x10(%rsp), %rdi
callq 0x3d52
movq 0x10(%rsp), %rsi
movq (%rsi), %rax
movq %r12, %rdi
callq *0x20(%rax)
movq %r13, %rdi
movq %r12, %rsi
callq 0x31f0
movq %rax, %rdi
callq 0x3140
movq %r12, %rdi
callq 0x3130
leaq 0x8dbc(%rip), %rax      # 0xe230
cmpq %rax, 0x18(%rsp)
je 0x5480
callq 0x32f0
leaq 0x10(%rsp), %rdi
callq 0x3dec
testb %al, %al
je 0x551e
pushq $0x1
popq %rdi
callq 0x3150
movq %rax, %rdi
leaq 0x8694(%rip), %rsi      # 0xdb38
xorl %edx, %edx
callq 0x3360
jmp 0x55d7
movq %rax, %r15
movq %rdx, 0x8(%rsp)
cmpl $0x2, %edx
jne 0x56d3
movq %r15, %rdi
callq 0x3100
leaq 0x8d60(%rip), %rax      # 0xe230
cmpq %rax, 0x18(%rsp)
je 0x5514
movq 0x10(%rsp), %rsi
movq (%rsi), %rax
movq %r12, %rdi
callq *0x20(%rax)
movq %r13, %rdi
movq %r12, %rsi
callq 0x31f0
movq %rax, %rdi
leaq 0x3d93(%rip), %rsi      # 0x928d
callq 0x3210
movq %rax, %rdi
callq 0x3140
movq %r12, %rdi
callq 0x3130
callq 0x32f0
callq 0x3350
jmp 0x5480
testb %bl, %bl
je 0x5531
movq %r13, %rdi
leaq 0x3cd9(%rip), %rsi      # 0x9205
callq 0x3210
movq 0x10(%rsp), %r15
movq (%r15), %rax
movq %r12, %rdi
movq %r15, %rsi
callq *0x20(%rax)
movq %r13, %rdi
movq %r12, %rsi
callq 0x31f0
movq %rax, %rdi
leaq 0x3d36(%rip), %rsi      # 0x928d
callq 0x3210
movq %rax, %rdi
callq 0x3140
movq %r12, %rdi
callq 0x3130
movq (%r15), %rax
movq %r15, %rdi
callq *0x38(%rax)
addq $0x8, %rbp
jmp 0x53df
leaq 0x90(%rsp), %rdi
callq 0x7536
leaq 0x78(%rsp), %rdi
callq 0x73da
leaq 0x60(%rsp), %rdi
callq 0x737e
leaq 0x40(%rsp), %rdi
callq 0x3130
jmp 0x52d6
pushq $0x10
popq %rdi
callq 0x3150
movq %rax, %rbx
movq %rax, %rdi
callq 0x5bf0
leaq 0x8558(%rip), %rsi      # 0xdb20
movq 0x89f1(%rip), %rdx      # 0xdfc0
movq %rbx, %rdi
callq 0x3360
jmp 0x56a3
movq %rdx, 0x8(%rsp)
movq %rax, %r15
leaq 0x20(%rsp), %rdi
callq 0x3130
jmp 0x55f8
movq %rdx, 0x8(%rsp)
movq %rax, %r15
callq 0x3350
jmp 0x56d3
jmp 0x5693
movq %rdx, 0x8(%rsp)
movq %rax, %r15
movq %rbx, %rdi
callq 0x31b0
jmp 0x56e3
jmp 0x5620
jmp 0x5693
movq %rdx, 0x8(%rsp)
movq %rax, %r15
leaq 0x20(%rsp), %rdi
callq 0x3130
jmp 0x56e3
jmp 0x5693
jmp 0x5693
movq %rdx, 0x8(%rsp)
movq %rax, %r15
jmp 0x56f0
movq %rdx, 0x8(%rsp)
movq %rax, %r15
jmp 0x56fa
jmp 0x5657
movq %rdx, 0x8(%rsp)
movq %rax, %r15
jmp 0x5704
movq %rdx, 0x8(%rsp)
movq %rax, %r15
jmp 0x570e
jmp 0x5788
jmp 0x5799
jmp 0x5799
jmp 0x57a8
jmp 0x5799
jmp 0x57a8
jmp 0x56a3
jmp 0x56a3
movq %rdx, 0x8(%rsp)
movq %rax, %r15
jmp 0x56e3
jmp 0x56c1
jmp 0x56c1
jmp 0x56a3
movq %rdx, 0x8(%rsp)
movq %rax, %r15
jmp 0x56d3
jmp 0x5799
jmp 0x5788
jmp 0x5799
jmp 0x5799
movq %rdx, 0x8(%rsp)
movq %rax, %r15
leaq 0x20(%rsp), %rdi
callq 0x3130
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x56e3
movq (%rdi), %rax
callq *0x38(%rax)
leaq 0x90(%rsp), %rdi
callq 0x7536
leaq 0x78(%rsp), %rdi
callq 0x73da
leaq 0x60(%rsp), %rdi
callq 0x737e
leaq 0x40(%rsp), %rdi
callq 0x3130
cmpl $0x1, 0x8(%rsp)
jne 0x57ab
movq %r15, %rdi
callq 0x3270
leaq 0x40(%rsp), %rbx
movq %rbx, %rdi
movq %rax, %rsi
callq 0x5c50
movq %r15, %rdi
callq 0x3100
movq %rbx, %rdi
callq 0x32c0
movq 0x88a8(%rip), %rdi      # 0xdff0
movq %rax, %rsi
callq 0x3210
movq %rax, %rdi
callq 0x3140
leaq 0x40(%rsp), %rdi
callq 0x33d8
callq 0x3350
jmp 0x52d6
movq %rax, %r15
leaq 0x40(%rsp), %rdi
callq 0x33d8
callq 0x3350
jmp 0x57ab
movq %rax, %rdi
callq 0x57b3
movq %rax, %r15
leaq 0x20(%rsp), %rdi
callq 0x3130
jmp 0x579c
jmp 0x5799
movq %rax, %r15
leaq 0x40(%rsp), %rdi
callq 0x3130
jmp 0x57ab
movq %rax, %r15
movq %r15, %rdi
callq 0x3370