// File: pfnet-research[P]pml/src/parser.cpp
// Function: parser::equive_expr(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, unsigned long&)
expr_result_t equive_expr(std::string const& input, size_t& pos) {
    auto head_result = additive_expr(input, pos);
    if (head_result.is_error())
        return head_result;
    auto acc = head_result.ok();

    while (true) {
        auto op_token = next_token(input, pos);
        if (op_token.kind != token_t::kind_t::DoubleEq &&
            op_token.kind != token_t::kind_t::Neq &&
            op_token.kind != token_t::kind_t::Leq &&
            op_token.kind != token_t::kind_t::Geq)
            break;
        pos = op_token.pos + op_token.lexime.size();

        auto e_result = additive_expr(input, pos);
        if (e_result.is_error())
            return e_result;
        auto e = e_result.ok();

        switch (op_token.kind) {
        case token_t::kind_t::DoubleEq:
            acc = make<ast::eq_expr_t>(acc, e);
            break;
        case token_t::kind_t::Neq:
            acc = make<ast::neq_expr_t>(acc, e);
            break;
        case token_t::kind_t::Leq:
            acc = make<ast::leq_expr_t>(acc, e);
            break;
        case token_t::kind_t::Geq:
            acc = make<ast::geq_expr_t>(acc, e);
            break;
        default:
            throw std::logic_error{"invalid formula op"};
        }
    }
    return acc;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x150, %rsp            # imm = 0x150
movq %rdi, -0x118(%rbp)
movq %rdi, %rax
movq %rax, -0x110(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
leaq -0x50(%rbp), %rdi
movq %rdi, -0x108(%rbp)
callq 0x3ecd0
movq -0x108(%rbp), %rdi
callq 0x41970
movb %al, -0xf9(%rbp)
jmp 0x3f144
movb -0xf9(%rbp), %al
testb $0x1, %al
jne 0x3f150
jmp 0x3f17f
movq -0x118(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x41990
jmp 0x3f162
movl $0x1, -0x60(%rbp)
jmp 0x3f4f4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x3f50d
leaq -0x50(%rbp), %rdi
callq 0x419e0
movq %rax, -0x120(%rbp)
jmp 0x3f191
movq -0x120(%rbp), %rsi
leaq -0x70(%rbp), %rdi
callq 0x13050
jmp 0x3f1a3
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rax
movq (%rax), %rdx
leaq -0xa0(%rbp), %rdi
callq 0x355b0
jmp 0x3f1bc
cmpl $0x13, -0xa0(%rbp)
je 0x3f1fd
cmpl $0x14, -0xa0(%rbp)
je 0x3f1fd
cmpl $0x16, -0xa0(%rbp)
je 0x3f1fd
cmpl $0x17, -0xa0(%rbp)
je 0x3f1fd
movl $0x3, -0x60(%rbp)
jmp 0x3f472
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x3f4e9
movq -0x98(%rbp), %rax
movq %rax, -0x128(%rbp)
leaq -0x90(%rbp), %rdi
callq 0xa280
movq -0x128(%rbp), %rcx
movq -0x118(%rbp), %rdi
addq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movb $0x0, -0xa1(%rbp)
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
callq 0x3ecd0
jmp 0x3f245
movq -0x118(%rbp), %rdi
callq 0x41970
movb %al, -0x129(%rbp)
jmp 0x3f259
movb -0x129(%rbp), %al
testb $0x1, %al
jne 0x3f265
jmp 0x3f29a
movb $0x1, -0xa1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x3f45b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x3f4b7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x3f4ab
movq -0x118(%rbp), %rdi
callq 0x419e0
movq %rax, -0x138(%rbp)
jmp 0x3f2af
movq -0x138(%rbp), %rsi
leaq -0xb8(%rbp), %rdi
callq 0x13050
movl -0xa0(%rbp), %eax
addl $-0x13, %eax
movl %eax, %ecx
movq %rcx, -0x140(%rbp)
subl $0x4, %eax
ja 0x3f3ea
movq -0x140(%rbp), %rax
leaq 0x5d685(%rip), %rcx     # 0x9c970
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq -0xc8(%rbp), %rdi
leaq -0x70(%rbp), %rsi
leaq -0xb8(%rbp), %rdx
callq 0x3f520
jmp 0x3f30d
leaq -0x70(%rbp), %rdi
leaq -0xc8(%rbp), %rsi
callq 0x421b0
leaq -0xc8(%rbp), %rdi
callq 0x421e0
jmp 0x3f448
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x3f49f
leaq -0xd8(%rbp), %rdi
leaq -0x70(%rbp), %rsi
leaq -0xb8(%rbp), %rdx
callq 0x3f560
jmp 0x3f358
leaq -0x70(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0x42200
leaq -0xd8(%rbp), %rdi
callq 0x42230
jmp 0x3f448
leaq -0xe8(%rbp), %rdi
leaq -0x70(%rbp), %rsi
leaq -0xb8(%rbp), %rdx
callq 0x3f5a0
jmp 0x3f392
leaq -0x70(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x42250
leaq -0xe8(%rbp), %rdi
callq 0x42280
jmp 0x3f448
leaq -0xf8(%rbp), %rdi
leaq -0x70(%rbp), %rsi
leaq -0xb8(%rbp), %rdx
callq 0x3f5e0
jmp 0x3f3cc
leaq -0x70(%rbp), %rdi
leaq -0xf8(%rbp), %rsi
callq 0x422a0
leaq -0xf8(%rbp), %rdi
callq 0x422d0
jmp 0x3f448
movl $0x10, %edi
callq 0xa1d0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x148(%rbp)
leaq 0x5d723(%rip), %rsi     # 0x9cb2b
callq 0xa540
jmp 0x3f40f
movq -0x148(%rbp), %rdi
movq 0xa7bb3(%rip), %rsi     # 0xe6fd0
movq 0xa7b6c(%rip), %rdx     # 0xe6f90
callq 0xa610
jmp 0x3f51f
movq -0x148(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
callq 0xa2c0
jmp 0x3f49f
leaq -0xb8(%rbp), %rdi
callq 0x13080
movl $0x0, -0x60(%rbp)
testb $0x1, -0xa1(%rbp)
jne 0x3f470
movq -0x118(%rbp), %rdi
callq 0x2ffa0
jmp 0x3f472
leaq -0xa0(%rbp), %rdi
callq 0x404f0
movl -0x60(%rbp), %eax
movl %eax, -0x14c(%rbp)
testl %eax, %eax
je 0x3f49a
jmp 0x3f48d
movl -0x14c(%rbp), %eax
subl $0x3, %eax
je 0x3f4c5
jmp 0x3f4de
jmp 0x3f1a1
leaq -0xb8(%rbp), %rdi
callq 0x13080
movq -0x118(%rbp), %rdi
callq 0x2ffa0
leaq -0xa0(%rbp), %rdi
callq 0x404f0
jmp 0x3f4e9
movq -0x118(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x41f90
jmp 0x3f4d7
movl $0x1, -0x60(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x13080
jmp 0x3f4f4
leaq -0x70(%rbp), %rdi
callq 0x13080
jmp 0x3f50d
leaq -0x50(%rbp), %rdi
callq 0x2ffa0
movq -0x110(%rbp), %rax
addq $0x150, %rsp            # imm = 0x150
popq %rbp
retq
leaq -0x50(%rbp), %rdi
callq 0x2ffa0
movq -0x58(%rbp), %rdi
callq 0xa650
nop