// File: /workspace/github_cpp_makefile_star2_O2/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 $0x268, %rsp            # imm = 0x268
movq %r8, %r13
movq %rcx, %r12
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x1c8(%rsp), %rdi
movq %rdx, %rsi
movq %r8, %rdx
callq 0x30c2e
leaq 0x238(%rsp), %r15
leaq 0x128(%rsp), %rdi
movq %r15, %rsi
callq 0x32e5f
leaq 0x68(%rsp), %rdi
leaq 0x128(%rsp), %rcx
movq %r13, %rsi
movq %r14, %rdx
callq 0x32550
leaq 0x130(%rsp), %rdi
callq 0xa248
leaq 0x128(%rsp), %rdi
leaq 0x68(%rsp), %rdx
movq %r12, %rsi
callq 0x30c2e
movl 0x234(%rsp), %ebp
movl 0x190(%rsp), %r12d
leaq 0xbb0e(%rip), %rdx      # 0x3c497
leaq 0x98(%rsp), %rdi
movq %r14, %rsi
callq 0x3249c
leaq 0x18(%rsp), %rdi
leaq 0x98(%rsp), %rsi
callq 0x3294b
leaq 0x8(%rsp), %rdi
movq %r15, %rsi
callq 0x33141
leaq 0x2c(%rsp), %rcx
movl $0x8, (%rcx)
leaq 0x80(%rsp), %rdi
leaq 0x18(%rsp), %rsi
leaq 0x8(%rsp), %rdx
callq 0x32fe3
leaq 0x38(%rsp), %r13
leaq 0x88(%rsp), %r15
movaps -0x8(%r15), %xmm0
movaps %xmm0, -0x8(%r13)
xorps %xmm0, %xmm0
movaps %xmm0, -0x8(%r15)
leaq 0x100(%rsp), %rdi
leaq 0x30(%rsp), %rcx
movl %ebp, %esi
movl %r12d, %edx
callq 0x3045a
movq %r13, %rdi
callq 0xa248
movq %r15, %rdi
callq 0xa248
leaq 0x10(%rsp), %rdi
callq 0xa248
leaq 0x20(%rsp), %rdi
callq 0xa248
leaq 0x98(%rsp), %rdi
callq 0x9130
leaq 0x98(%rsp), %rdi
leaq 0x1c8(%rsp), %rsi
leaq 0x128(%rsp), %rdx
callq 0x972c
leaq 0xe8(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x325c6
cmpb $0x1, 0x260(%rsp)
jne 0x30aa8
leaq 0x258(%rsp), %rdx
leaq 0x30(%rsp), %rdi
movq %r14, %rsi
xorl %ecx, %ecx
callq 0x2c314
leaq 0xb8(%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0x9ece
jmp 0x30aca
leaq 0x30(%rsp), %rdi
pushq $0x1
popq %rdx
movq %r14, %rsi
callq 0x325f2
leaq 0xb8(%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0x9ece
leaq 0x30(%rsp), %rdi
callq 0xa3e2
leaq 0x98(%rsp), %rsi
movq %rbx, %rdi
callq 0x324d4
movl 0x230(%rsp), %eax
movl %eax, 0x68(%rbx)
leaq 0x198(%rsp), %rsi
movl -0x4(%rsi), %eax
movl %eax, 0x6c(%rbx)
leaq 0x70(%rbx), %rdi
callq 0x32614
leaq 0x98(%rsp), %rdi
callq 0xa08a
leaq 0x100(%rsp), %rdi
callq 0xa198
leaq 0x128(%rsp), %rdi
callq 0x2c15c
leaq 0x68(%rsp), %rdi
callq 0x3321a
leaq 0x1c8(%rsp), %rdi
callq 0x2c15c
movq %rbx, %rax
addq $0x268, %rsp            # imm = 0x268
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x30b5a
movq %rax, %r14
leaq 0x30(%rsp), %rdi
callq 0xa3e2
jmp 0x30be8
jmp 0x30be5
jmp 0x30be5
movq %rax, %r14
movq %rbx, %rdi
callq 0xa08a
jmp 0x30be8
movq %rax, %r14
jmp 0x30bf5
movq %rax, %r14
movq %r13, %rdi
callq 0xa248
movq %r15, %rdi
callq 0xa248
jmp 0x30b97
movq %rax, %r14
leaq 0x10(%rsp), %rdi
callq 0xa248
jmp 0x30ba6
movq %rax, %r14
leaq 0x20(%rsp), %rdi
callq 0xa248
jmp 0x30bb5
movq %rax, %r14
leaq 0x98(%rsp), %rdi
callq 0x9130
jmp 0x30c02
movq %rax, %r14
jmp 0x30c02
movq %rax, %r14
jmp 0x30c0f
movq %rax, %r14
leaq 0x130(%rsp), %rdi
callq 0xa248
jmp 0x30c19
movq %rax, %r14
jmp 0x30c19
movq %rax, %r14
leaq 0x98(%rsp), %rdi
callq 0xa08a
leaq 0x100(%rsp), %rdi
callq 0xa198
leaq 0x128(%rsp), %rdi
callq 0x2c15c
leaq 0x68(%rsp), %rdi
callq 0x3321a
leaq 0x1c8(%rsp), %rdi
callq 0x2c15c
movq %r14, %rdi
callq 0x94d0