// File: /workspace/github_cpp_makefile_star2_O3/pfnet-research[P]pml/src/translate_to_mdp.cpp
// Function: create_let_case(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, ast::expr_t const&, ast::expr_t const&, environment_t<value_info_t> const&)
mdp_with_info_t create_let_case(
        std::string const& name,
        ast::expr_t const& init,
        ast::expr_t const& body,
        var_env_t const& var_env) {

    // TODO: resolve name conflict case
    // e.g) let a = 1 in let a = 3 in ...

    auto init_ = trans_impl(init, var_env);
    auto new_env = var_env.append(name, make<value_info_t>(init_.value));
    auto body_ = trans_impl(body, new_env);

    // concat accept location of init to init location of body,
    // and subst value of init to variable `name`.
    //
    // [] location=accept-of-init -> 1:(location'=init-of-body)&(name'=value_name-of-init)
    auto concat = make_concat(
            init_.accept, body_.init,
            make<mdp::binop_expr_t>(
                make<mdp::var_expr_t>(name+"'"),
                make<mdp::var_expr_t>(init_.value.name),
                mdp::binop_kind_t::Eq));

    auto result_mdp = mdp::mdp_t::merge(std::move(init_.mdp), std::move(body_.mdp));
    result_mdp.commands.push_back(concat);

    if (init_.value.bound) { // integer
        result_mdp.variables.push_back(mdp::variable_t {
                name, *init_.value.bound, 0
                });
    } else { // boolean
        result_mdp.variables.push_back(mdp::variable_t {
                name, true
                });
    }

    return mdp_with_info_t {
        result_mdp, init_.init, body_.accept,
        body_.value
    };
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x258, %rsp            # imm = 0x258
movq %r8, %r13
movq %rcx, %r12
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x1b8(%rsp), %rdi
movq %rdx, %rsi
movq %r8, %rdx
callq 0x3d82e
leaq 0x228(%rsp), %r15
leaq 0xf8(%rsp), %rdi
movq $0x0, -0x8(%rdi)
leaq 0xf0(%rsp), %rsi
leaq 0x70(%rsp), %rdx
movq %r15, %rcx
callq 0x40aea
leaq 0xd8(%rsp), %rdi
leaq 0xf0(%rsp), %rcx
movq %r13, %rsi
movq %r14, %rdx
callq 0x402d4
movq 0xf8(%rsp), %rdi
testq %rdi, %rdi
je 0x3d2ae
callq 0xa946
leaq 0xf0(%rsp), %rdi
leaq 0xd8(%rsp), %rdx
movq %r12, %rsi
callq 0x3d82e
movl 0x224(%rsp), %ebp
movl 0x158(%rsp), %r12d
leaq 0x80(%rsp), %r13
movq %r13, -0x10(%r13)
movq (%r14), %rsi
movq 0x8(%r14), %rdx
addq %rsi, %rdx
leaq 0x70(%rsp), %rdi
callq 0xac68
leaq 0xdb2f(%rip), %rsi      # 0x4ae2b
leaq 0x70(%rsp), %rdi
callq 0x9540
leaq 0x68(%rsp), %rdi
movq $0x0, -0x8(%rdi)
leaq 0x60(%rsp), %rsi
leaq 0x20(%rsp), %rdx
leaq 0x70(%rsp), %rcx
callq 0x40566
leaq 0x28(%rsp), %rdi
movq $0x0, -0x8(%rdi)
leaq 0x20(%rsp), %rsi
leaq 0xc(%rsp), %rdx
movq %r15, %rcx
callq 0x40d02
leaq 0xc(%rsp), %r9
movl $0x8, (%r9)
leaq 0x18(%rsp), %rdi
movq $0x0, -0x8(%rdi)
leaq 0x10(%rsp), %rsi
leaq 0xb(%rsp), %rdx
leaq 0x60(%rsp), %rcx
leaq 0x20(%rsp), %r8
callq 0x40c14
movaps 0x10(%rsp), %xmm0
leaq 0x30(%rsp), %rcx
movaps %xmm0, (%rcx)
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rsp)
leaq 0x190(%rsp), %rdi
movl %ebp, %esi
movl %r12d, %edx
callq 0x3cb57
movq 0x38(%rsp), %rdi
testq %rdi, %rdi
je 0x3d3ae
callq 0xa946
movq 0x18(%rsp), %rdi
testq %rdi, %rdi
je 0x3d3bd
callq 0xa946
movq 0x28(%rsp), %rdi
testq %rdi, %rdi
je 0x3d3cc
callq 0xa946
movq 0x68(%rsp), %rdi
testq %rdi, %rdi
je 0x3d3db
callq 0xa946
movq 0x70(%rsp), %rdi
cmpq %r13, %rdi
je 0x3d3f5
movq 0x80(%rsp), %rsi
incq %rsi
callq 0x92e0
leaq 0x70(%rsp), %rdi
leaq 0x1b8(%rsp), %rsi
leaq 0xf0(%rsp), %rdx
callq 0x9b6c
leaq 0xc0(%rsp), %rdi
leaq 0x190(%rsp), %rsi
callq 0x40352
cmpb $0x1, 0x250(%rsp)
jne 0x3d473
leaq 0x40(%rsp), %r15
movq %r15, -0x10(%r15)
movq (%r14), %rsi
movq 0x8(%r14), %rdx
addq %rsi, %rdx
leaq 0x30(%rsp), %rdi
callq 0xac68
movq 0x248(%rsp), %rax
leaq 0x30(%rsp), %rsi
movq %rax, 0x24(%rsi)
xorl %eax, %eax
movl %eax, 0x2c(%rsi)
movl %eax, 0x20(%rsi)
leaq 0x90(%rsp), %rdi
callq 0xa5f4
jmp 0x3d4ad
leaq 0x40(%rsp), %r15
movq %r15, -0x10(%r15)
movq (%r14), %rsi
movq 0x8(%r14), %rdx
addq %rsi, %rdx
leaq 0x30(%rsp), %rdi
callq 0xac68
leaq 0x30(%rsp), %rsi
movb $0x1, 0x24(%rsi)
movl $0x1, 0x20(%rsi)
leaq 0x90(%rsp), %rdi
callq 0xa5f4
leaq 0x50(%rsp), %r14
movq %r14, %rdi
callq 0xaa94
movq -0x20(%r14), %rdi
cmpq %r15, %rdi
je 0x3d4d0
movq 0x40(%rsp), %rsi
incq %rsi
callq 0x92e0
leaq 0x10(%rbx), %r15
movq %r15, (%rbx)
movq 0x70(%rsp), %rsi
movq 0x78(%rsp), %rdx
addq %rsi, %rdx
movq %rbx, %rdi
callq 0xac68
leaq 0x20(%rbx), %r13
leaq 0x90(%rsp), %r14
movq %r13, %rdi
movq %r14, %rsi
callq 0x405f6
leaq 0x38(%rbx), %rbp
leaq 0xa8(%rsp), %r12
movq %rbp, %rdi
movq %r12, %rsi
callq 0x40692
leaq 0x50(%rbx), %rdi
leaq 0xc0(%rsp), %rsi
callq 0x4072c
movl 0x220(%rsp), %eax
movl %eax, 0x68(%rbx)
movl 0x15c(%rsp), %eax
movl %eax, 0x6c(%rbx)
leaq 0x70(%rbx), %rdi
leaq 0x80(%rbx), %rax
movq %rax, 0x70(%rbx)
movq 0x160(%rsp), %rsi
movq 0x168(%rsp), %rdx
addq %rsi, %rdx
callq 0xac68
movb $0x0, 0x98(%rbx)
cmpb $0x1, 0x188(%rsp)
leaq 0x80(%rsp), %r15
jne 0x3d595
movq 0x180(%rsp), %rax
movq %rax, 0x90(%rbx)
movb $0x1, 0x98(%rbx)
leaq 0xc0(%rsp), %rdi
callq 0xa808
movq %r12, %rdi
callq 0xa838
movq %r14, %rdi
callq 0xa868
movq 0x70(%rsp), %rdi
cmpq %r15, %rdi
je 0x3d5cc
movq 0x80(%rsp), %rsi
incq %rsi
callq 0x92e0
leaq 0x1a0(%rsp), %r14
movq %r14, %rdi
callq 0xa8da
movq -0x8(%r14), %rdi
testq %rdi, %rdi
je 0x3d5ea
callq 0xa946
leaq 0x170(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x3d60b
movq 0x170(%rsp), %rsi
incq %rsi
callq 0x92e0
leaq 0x140(%rsp), %rdi
callq 0xa808
leaq 0x128(%rsp), %rdi
callq 0xa838
leaq 0x110(%rsp), %r14
movq %r14, %rdi
callq 0xa868
movq -0x20(%r14), %rdi
leaq 0x100(%rsp), %rax
cmpq %rax, %rdi
je 0x3d656
movq 0x100(%rsp), %rsi
incq %rsi
callq 0x92e0
leaq 0xd8(%rsp), %rdi
callq 0x40d92
leaq 0x238(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x3d684
movq 0x238(%rsp), %rsi
incq %rsi
callq 0x92e0
leaq 0x208(%rsp), %rdi
callq 0xa808
leaq 0x1f0(%rsp), %rdi
callq 0xa838
leaq 0x1d8(%rsp), %r14
movq %r14, %rdi
callq 0xa868
movq -0x20(%r14), %rdi
leaq 0x1c8(%rsp), %rax
cmpq %rax, %rdi
je 0x3d6cf
movq 0x1c8(%rsp), %rsi
incq %rsi
callq 0x92e0
movq %rbx, %rax
addq $0x258, %rsp            # imm = 0x258
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x3d6e6
movq %rax, %r14
leaq 0x30(%rsp), %rdi
callq 0x37daa
jmp 0x3d7e8
jmp 0x3d7e5
jmp 0x3d7e5
movq %rax, %r14
movq %rbx, %rdi
callq 0xa7c4
jmp 0x3d7e8
movq %rax, %r14
movq %rbp, %rdi
callq 0xa838
jmp 0x3d722
movq %rax, %r14
movq %r13, %rdi
callq 0xa868
jmp 0x3d72f
movq %rax, %r14
movq (%rbx), %rdi
cmpq %r15, %rdi
je 0x3d7e8
movq (%r15), %rsi
incq %rsi
callq 0x92e0
jmp 0x3d7e8
movq %rax, %r14
jmp 0x3d7f2
movq %rax, %r14
movq 0x38(%rsp), %rdi
testq %rdi, %rdi
je 0x3d765
callq 0xa946
movq 0x18(%rsp), %rdi
testq %rdi, %rdi
je 0x3d779
callq 0xa946
jmp 0x3d779
movq %rax, %r14
movq 0x28(%rsp), %rdi
testq %rdi, %rdi
je 0x3d78d
callq 0xa946
jmp 0x3d78d
movq %rax, %r14
movq 0x68(%rsp), %rdi
testq %rdi, %rdi
je 0x3d7a3
callq 0xa946
jmp 0x3d7a3
jmp 0x3d7a0
movq %rax, %r14
movq 0x70(%rsp), %rdi
cmpq %r13, %rdi
je 0x3d7ff
movq 0x80(%rsp), %rsi
incq %rsi
callq 0x92e0
jmp 0x3d7ff
movq %rax, %r14
jmp 0x3d7ff
movq %rax, %r14
jmp 0x3d80c
movq %rax, %r14
movq 0xf8(%rsp), %rdi
testq %rdi, %rdi
je 0x3d819
callq 0xa946
jmp 0x3d819
movq %rax, %r14
jmp 0x3d819
movq %rax, %r14
leaq 0x70(%rsp), %rdi
callq 0xa7c4
leaq 0x190(%rsp), %rdi
callq 0x37d68
leaq 0xf0(%rsp), %rdi
callq 0x37b5c
leaq 0xd8(%rsp), %rdi
callq 0x40d92
leaq 0x1b8(%rsp), %rdi
callq 0x37b5c
movq %r14, %rdi
callq 0x94e0