// File: /workspace/github_cpp_makefile_star2_O1/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 0x3e126
leaq 0x228(%rsp), %r15
leaq 0xf8(%rsp), %rdi
movq $0x0, -0x8(%rdi)
leaq 0xf0(%rsp), %rsi
leaq 0x70(%rsp), %rdx
movq %r15, %rcx
callq 0x413dc
leaq 0xd8(%rsp), %rdi
leaq 0xf0(%rsp), %rcx
movq %r13, %rsi
movq %r14, %rdx
callq 0x40b9a
movq 0xf8(%rsp), %rdi
testq %rdi, %rdi
je 0x3dba6
callq 0xaa12
leaq 0xf0(%rsp), %rdi
leaq 0xd8(%rsp), %rdx
movq %r12, %rsi
callq 0x3e126
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 0xad30
leaq 0xd237(%rip), %rsi      # 0x4ae2b
leaq 0x70(%rsp), %rdi
callq 0x9540
leaq 0x68(%rsp), %rdi
movq $0x0, -0x8(%rdi)
leaq 0x60(%rsp), %rsi
leaq 0x10(%rsp), %rdx
leaq 0x70(%rsp), %rcx
callq 0x40e4a
leaq 0x18(%rsp), %rdi
movq $0x0, -0x8(%rdi)
leaq 0x10(%rsp), %rsi
leaq 0xc(%rsp), %rdx
movq %r15, %rcx
callq 0x41612
leaq 0xc(%rsp), %r9
movl $0x8, (%r9)
leaq 0x28(%rsp), %rdi
movq $0x0, -0x8(%rdi)
leaq 0x20(%rsp), %rsi
leaq 0xb(%rsp), %rdx
leaq 0x60(%rsp), %rcx
leaq 0x10(%rsp), %r8
callq 0x4150c
movups 0x20(%rsp), %xmm0
leaq 0x30(%rsp), %rcx
movups %xmm0, (%rcx)
xorps %xmm0, %xmm0
movups %xmm0, 0x20(%rsp)
leaq 0x190(%rsp), %rdi
movl %ebp, %esi
movl %r12d, %edx
callq 0x3d42c
movq 0x38(%rsp), %rdi
testq %rdi, %rdi
je 0x3dca6
callq 0xaa12
movq 0x28(%rsp), %rdi
testq %rdi, %rdi
je 0x3dcb5
callq 0xaa12
movq 0x18(%rsp), %rdi
testq %rdi, %rdi
je 0x3dcc4
callq 0xaa12
movq 0x68(%rsp), %rdi
testq %rdi, %rdi
je 0x3dcd3
callq 0xaa12
movq 0x70(%rsp), %rdi
cmpq %r13, %rdi
je 0x3dced
movq 0x80(%rsp), %rsi
incq %rsi
callq 0x92e0
leaq 0x70(%rsp), %rdi
leaq 0x1b8(%rsp), %rsi
leaq 0xf0(%rsp), %rdx
callq 0x9b9c
leaq 0xc0(%rsp), %rdi
leaq 0x190(%rsp), %rsi
callq 0x40c18
cmpb $0x1, 0x250(%rsp)
jne 0x3dd6b
leaq 0x40(%rsp), %r15
movq %r15, -0x10(%r15)
movq (%r14), %rsi
movq 0x8(%r14), %rdx
addq %rsi, %rdx
leaq 0x30(%rsp), %rdi
callq 0xad30
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 0xa6d0
jmp 0x3dda5
leaq 0x40(%rsp), %r15
movq %r15, -0x10(%r15)
movq (%r14), %rsi
movq 0x8(%r14), %rdx
addq %rsi, %rdx
leaq 0x30(%rsp), %rdi
callq 0xad30
leaq 0x30(%rsp), %rsi
movb $0x1, 0x24(%rsi)
movl $0x1, 0x20(%rsi)
leaq 0x90(%rsp), %rdi
callq 0xa6d0
leaq 0x50(%rsp), %r14
movq %r14, %rdi
callq 0xab60
movq -0x20(%r14), %rdi
cmpq %r15, %rdi
je 0x3ddc8
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 0xad30
leaq 0x20(%rbx), %r13
leaq 0x90(%rsp), %r14
movq %r13, %rdi
movq %r14, %rsi
callq 0x40eda
leaq 0x38(%rbx), %rbp
leaq 0xa8(%rsp), %r12
movq %rbp, %rdi
movq %r12, %rsi
callq 0x40f76
leaq 0x50(%rbx), %rdi
leaq 0xc0(%rsp), %rsi
callq 0x41010
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 0xad30
movb $0x0, 0x98(%rbx)
cmpb $0x1, 0x188(%rsp)
leaq 0x80(%rsp), %r15
jne 0x3de8d
movq 0x180(%rsp), %rax
movq %rax, 0x90(%rbx)
movb $0x1, 0x98(%rbx)
leaq 0xc0(%rsp), %rdi
callq 0xa8d4
movq %r12, %rdi
callq 0xa904
movq %r14, %rdi
callq 0xa934
movq 0x70(%rsp), %rdi
cmpq %r15, %rdi
je 0x3dec4
movq 0x80(%rsp), %rsi
incq %rsi
callq 0x92e0
leaq 0x1a0(%rsp), %r14
movq %r14, %rdi
callq 0xa9a6
movq -0x8(%r14), %rdi
testq %rdi, %rdi
je 0x3dee2
callq 0xaa12
leaq 0x170(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x3df03
movq 0x170(%rsp), %rsi
incq %rsi
callq 0x92e0
leaq 0x140(%rsp), %rdi
callq 0xa8d4
leaq 0x128(%rsp), %rdi
callq 0xa904
leaq 0x110(%rsp), %r14
movq %r14, %rdi
callq 0xa934
movq -0x20(%r14), %rdi
leaq 0x100(%rsp), %rax
cmpq %rax, %rdi
je 0x3df4e
movq 0x100(%rsp), %rsi
incq %rsi
callq 0x92e0
leaq 0xd8(%rsp), %rdi
callq 0x416a2
leaq 0x238(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x3df7c
movq 0x238(%rsp), %rsi
incq %rsi
callq 0x92e0
leaq 0x208(%rsp), %rdi
callq 0xa8d4
leaq 0x1f0(%rsp), %rdi
callq 0xa904
leaq 0x1d8(%rsp), %r14
movq %r14, %rdi
callq 0xa934
movq -0x20(%r14), %rdi
leaq 0x1c8(%rsp), %rax
cmpq %rax, %rdi
je 0x3dfc7
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 0x3dfde
movq %rax, %r14
leaq 0x30(%rsp), %rdi
callq 0x3852e
jmp 0x3e0e0
jmp 0x3e0dd
jmp 0x3e0dd
movq %rax, %r14
movq %rbx, %rdi
callq 0xa890
jmp 0x3e0e0
movq %rax, %r14
movq %rbp, %rdi
callq 0xa904
jmp 0x3e01a
movq %rax, %r14
movq %r13, %rdi
callq 0xa934
jmp 0x3e027
movq %rax, %r14
movq (%rbx), %rdi
cmpq %r15, %rdi
je 0x3e0e0
movq (%r15), %rsi
incq %rsi
callq 0x92e0
jmp 0x3e0e0
movq %rax, %r14
jmp 0x3e0ea
movq %rax, %r14
movq 0x38(%rsp), %rdi
testq %rdi, %rdi
je 0x3e05d
callq 0xaa12
movq 0x28(%rsp), %rdi
testq %rdi, %rdi
je 0x3e071
callq 0xaa12
jmp 0x3e071
movq %rax, %r14
movq 0x18(%rsp), %rdi
testq %rdi, %rdi
je 0x3e085
callq 0xaa12
jmp 0x3e085
movq %rax, %r14
movq 0x68(%rsp), %rdi
testq %rdi, %rdi
je 0x3e09b
callq 0xaa12
jmp 0x3e09b
jmp 0x3e098
movq %rax, %r14
movq 0x70(%rsp), %rdi
cmpq %r13, %rdi
je 0x3e0f7
movq 0x80(%rsp), %rsi
incq %rsi
callq 0x92e0
jmp 0x3e0f7
movq %rax, %r14
jmp 0x3e0f7
movq %rax, %r14
jmp 0x3e104
movq %rax, %r14
movq 0xf8(%rsp), %rdi
testq %rdi, %rdi
je 0x3e111
callq 0xaa12
jmp 0x3e111
movq %rax, %r14
jmp 0x3e111
movq %rax, %r14
leaq 0x70(%rsp), %rdi
callq 0xa890
leaq 0x190(%rsp), %rdi
callq 0x384ec
leaq 0xf0(%rsp), %rdi
callq 0x382e4
leaq 0xd8(%rsp), %rdi
callq 0x416a2
leaq 0x1b8(%rsp), %rdi
callq 0x382e4
movq %r14, %rdi
callq 0x94e0