// File: /workspace/github_c_makefile_star2_O1/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 $0x38, %rsp
movq %rdx, %rbx
movq %rsi, %r14
movq %rdi, %r15
movq %rdx, %rdi
callq 0x4bae
cmpl $0x1, %eax
jg 0x285b
leaq 0x4832(%rip), %rsi      # 0x7074
leaq 0x4922(%rip), %rdx      # 0x716b
movq %r15, %rdi
movl $0x2, %ecx
movl %eax, %r8d
xorl %eax, %eax
callq 0x4e18
movabsq $0x3ffffffffffff, %r12  # imm = 0x3FFFFFFFFFFFF
andq %r12, %rbx
movq %rbx, 0x28(%rsp)
movq 0x10(%rbx), %rbp
movq %rbp, %rax
shrq $0x32, %rax
cmpl $0x3fff, %eax           # imm = 0x3FFF
jb 0x288d
movq %rbp, %rax
andq %r12, %rax
cmpl $0x0, (%rax)
sete %al
jmp 0x288f
xorl %eax, %eax
movabsq $0x7ffc000000000001, %rbx # imm = 0x7FFC000000000001
cmpq %rbx, %rbp
je 0x28c9
testb %al, %al
jne 0x28c9
leaq 0x4b77(%rip), %rsi      # 0x7420
movq %r15, %rdi
xorl %eax, %eax
callq 0x4e18
addq $0x3, %rbx
movq %rbx, %rax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpq %rbx, %rbp
jne 0x28d9
movq %rbx, %rcx
movq %rbx, %rdx
jmp 0x2a44
movl $0x0, 0xc(%rsp)
movq %rbx, 0x10(%rsp)
movq %rbx, 0x18(%rsp)
movq %r15, 0x20(%rsp)
andq %r12, %rbp
movq 0x10(%rbp), %rdi
movabsq $-0x4000000000001, %rax # imm = 0xFFFBFFFFFFFFFFFF
cmpq %rax, %rdi
jbe 0x2a12
movq %rdi, %r13
andq %r12, %r13
cmpl $0x0, (%r13)
jne 0x2a12
callq 0x4bae
cmpl $0x2, %eax
jne 0x2a12
movq 0x10(%r13), %r15
movabsq $-0x4000000000001, %rax # imm = 0xFFFBFFFFFFFFFFFF
cmpq %rax, %r15
jbe 0x294a
movq %r15, %rax
andq %r12, %rax
cmpl $0x2, (%rax)
sete %bl
jmp 0x294c
xorl %ebx, %ebx
testb %bl, %bl
je 0x29d8
movq 0x18(%r13), %rax
andq %r12, %rax
movq 0x10(%rax), %rax
movq %rax, 0x30(%rsp)
movq %r14, %r13
movq 0x20(%rsp), %r14
movq %r14, %rdi
movq %r15, %rsi
movq 0x10(%rsp), %rdx
callq 0x4b63
movq %rax, 0x10(%rsp)
movq %r14, %rdi
movq %r13, %r14
movq %r13, %rsi
movq 0x30(%rsp), %rdx
callq 0x5781
movabsq $-0x4000000000001, %rcx # imm = 0xFFFBFFFFFFFFFFFF
cmpq %rcx, %rax
jbe 0x29bc
movq %rax, %rcx
andq %r12, %rcx
cmpl $0x4, (%rcx)
jne 0x29bc
cmpq $0x0, 0x10(%rcx)
jne 0x29bc
andq %r12, %r15
movq %r15, 0x10(%rcx)
movq 0x20(%rsp), %r15
movq %r15, %rdi
movq %rax, %rsi
movq 0x18(%rsp), %rdx
callq 0x4b63
movq %rax, 0x18(%rsp)
jmp 0x29ee
movq 0x20(%rsp), %r15
movq %r15, %rdi
leaq 0x4a96(%rip), %rsi      # 0x747d
xorl %eax, %eax
callq 0x4e18
testb %bl, %bl
je 0x2a25
movq 0x18(%rbp), %rbp
movabsq $0x7ffc000000000001, %rbx # imm = 0x7FFC000000000001
cmpq %rbx, %rbp
sete %al
movl %eax, 0xc(%rsp)
jne 0x28f0
jmp 0x2a2f
leaq 0x4a36(%rip), %rsi      # 0x744f
movq %r15, %rdi
xorl %eax, %eax
callq 0x4e18
jmp 0x2a2f
movabsq $0x7ffc000000000001, %rbx # imm = 0x7FFC000000000001
testb $0x1, 0xc(%rsp)
movq 0x18(%rsp), %rcx
movq 0x10(%rsp), %rdx
je 0x28b3
movq %r15, %rdi
movq %r14, %rsi
callq 0x52d8
movq 0x28(%rsp), %rcx
movq 0x18(%rcx), %rdx
movq %r15, %rdi
movq %rax, %rsi
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x59d0