// File: /workspace/github_c_makefile_star2_O3/jiribenes[P]scheme/src/core.c
// Function: builtin_let
static value_t builtin_let(vm_t *vm, env_t *env, value_t args) {
    // (let ((a 10) (b 20) ...) <exprs...>)
    arity_check(vm, "let", args, 2, true);
    value_t bindings = AS_CONS(args)->car;
    if (!IS_CONS(bindings) && !IS_NIL(bindings)) {
        error_runtime(vm, "let: bindings (first argument) must be a list!");
        return UNDEFINED_VAL;
    }

    value_t vars = NIL_VAL;
    value_t vals = NIL_VAL;
    if (!IS_NIL(bindings)) {
        value_t binding, iter;
        SCM_FOREACH (binding, AS_CONS(bindings), iter) {
            if (!IS_CONS(binding) || cons_len(binding) != 2) {
                error_runtime(vm,
                              "let: binding is not of type (variable value)!");
                return UNDEFINED_VAL;
            }
            value_t var = AS_CONS(binding)->car;
            value_t val = AS_CONS(AS_CONS(binding)->cdr)->car;
            if (!IS_SYMBOL(var)) {
                error_runtime(vm,
                              "let: left side of the binding is not a symbol!");
                return UNDEFINED_VAL;
            }
            value_t temp = cons_fn(vm, var, vars);
            vars = temp;

            value_t val_eval = eval(vm, env, val);

            // If value in binding is an unnamed function,
            // set it's name to var in binding
            if (IS_FUNCTION(val_eval)) {
                function_t *func = AS_FUNCTION(val_eval);
                symbol_t *sym = AS_SYMBOL(var);
                if (func->name == NULL) {
                    func->name = sym;
                }
            }
            temp = cons_fn(vm, val_eval, vals);
            vals = temp;
        }
    }

    env_t *new_env = env_push(vm, env, vars, vals);
    value_t body = AS_CONS(args)->cdr;
    return begin(vm, new_env, body);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rdx, %r15
movq %rsi, 0x18(%rsp)
movq %rdi, 0x8(%rsp)
movq %rdx, %rdi
callq 0x4a8d
cmpl $0x1, %eax
jg 0x283e
leaq 0x3851(%rip), %rsi      # 0x6074
leaq 0x3941(%rip), %rdx      # 0x616b
movq 0x8(%rsp), %rdi
movl $0x2, %ecx
movl %eax, %r8d
xorl %eax, %eax
callq 0x4cc4
movabsq $0x3ffffffffffff, %rbx  # imm = 0x3FFFFFFFFFFFF
andq %rbx, %r15
movq 0x10(%r15), %r14
movq %r14, %rax
shrq $0x32, %rax
cmpl $0x3fff, %eax           # imm = 0x3FFF
jb 0x286b
movq %r14, %rax
andq %rbx, %rax
cmpl $0x0, (%rax)
sete %al
jmp 0x286d
xorl %eax, %eax
movabsq $0x7ffc000000000001, %r12 # imm = 0x7FFC000000000001
cmpq %r12, %r14
je 0x288c
testb %al, %al
jne 0x288c
leaq 0x3b99(%rip), %rsi      # 0x6420
jmp 0x29da
movq %r15, 0x20(%rsp)
cmpq %r12, %r14
jne 0x28da
movq %r12, %r13
movq %r12, 0x10(%rsp)
movq 0x8(%rsp), %rbx
movq %rbx, %rdi
movq 0x18(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq %r13, %rcx
callq 0x51c7
movq 0x20(%rsp), %rcx
movq 0x18(%rcx), %rdx
movq %rbx, %rdi
movq %rax, %rsi
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x583d
movq %r12, 0x10(%rsp)
movq %r12, %r13
andq %rbx, %r14
movq 0x10(%r14), %rdi
movabsq $-0x4000000000001, %rax # imm = 0xFFFBFFFFFFFFFFFF
cmpq %rax, %rdi
jbe 0x29ca
movq %rdi, %r15
andq %rbx, %r15
cmpl $0x0, (%r15)
jne 0x29ca
callq 0x4a8d
cmpl $0x2, %eax
jne 0x29ca
movq 0x10(%r15), %rsi
movabsq $-0x4000000000001, %rax # imm = 0xFFFBFFFFFFFFFFFF
cmpq %rax, %rsi
jbe 0x29d3
movq %rbx, %rcx
movq %rsi, %rbp
andq %rbx, %rbp
cmpl $0x2, (%rbp)
jne 0x29d3
movq 0x18(%r15), %rax
andq %rcx, %rax
movq 0x10(%rax), %r15
movq 0x8(%rsp), %r12
movq %r12, %rdi
movq 0x10(%rsp), %rdx
callq 0x4a42
movq %rax, 0x10(%rsp)
movq %r12, %rdi
movq 0x18(%rsp), %rsi
movq %r15, %rdx
callq 0x5627
movabsq $-0x4000000000001, %rcx # imm = 0xFFFBFFFFFFFFFFFF
cmpq %rcx, %rax
jbe 0x299b
movq %rax, %rcx
andq %rbx, %rcx
cmpl $0x4, (%rcx)
jne 0x299b
cmpq $0x0, 0x10(%rcx)
jne 0x299b
movq %rbp, 0x10(%rcx)
movq 0x8(%rsp), %rdi
movq %rax, %rsi
movq %r13, %rdx
callq 0x4a42
movq %rax, %r13
movq 0x18(%r14), %r14
movabsq $0x7ffc000000000001, %r12 # imm = 0x7FFC000000000001
cmpq %r12, %r14
jne 0x28e2
jmp 0x289e
leaq 0x3a7e(%rip), %rsi      # 0x644f
jmp 0x29da
leaq 0x3aa3(%rip), %rsi      # 0x647d
movq 0x8(%rsp), %rdi
xorl %eax, %eax
callq 0x4cc4
addq $0x3, %r12
movq %r12, %rax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq