// File: /workspace/github_c_makefile_star2_O2/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, %r14
movq %rsi, 0x18(%rsp)
movabsq $0x3ffffffffffff, %r15  # imm = 0x3FFFFFFFFFFFF
leaq 0x3b0b(%rip), %rsi      # 0x6133
pushq $0x2
popq %rcx
pushq $0x1
popq %r8
movq %rdi, 0x8(%rsp)
callq 0x12cc
andq %r15, %r14
movq 0x10(%r14), %rbp
movq %rbp, %rax
shrq $0x32, %rax
cmpl $0x3fff, %eax           # imm = 0x3FFF
movq %r14, 0x20(%rsp)
jb 0x2661
movq %rbp, %rax
andq %r15, %rax
cmpl $0x0, (%rax)
sete %al
jmp 0x2663
xorl %eax, %eax
movabsq $0x7ffc000000000001, %r14 # imm = 0x7FFC000000000001
cmpq %r14, %rbp
je 0x2682
testb %al, %al
jne 0x2682
leaq 0x3d6b(%rip), %rsi      # 0x63e8
jmp 0x27d5
cmpq %r14, %rbp
jne 0x26c1
movq %r14, %rdx
movq 0x8(%rsp), %rbx
movq %rbx, %rdi
movq 0x18(%rsp), %rsi
movq %r14, %rcx
callq 0x4ab0
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 0x5086
movabsq $-0x4000000000001, %rax # imm = 0xFFFBFFFFFFFFFFFF
incq %rax
orq %rax, %rbp
movq %r14, %rbx
movq %r14, 0x10(%rsp)
cmpq %r14, %rbp
je 0x27f7
andq %r15, %rbp
movq 0x10(%rbp), %rdi
movabsq $-0x4000000000001, %rax # imm = 0xFFFBFFFFFFFFFFFF
cmpq %rax, %rdi
jbe 0x27c5
movq %rdi, %r12
andq %r15, %r12
cmpl $0x0, (%r12)
jne 0x27c5
callq 0x4378
cmpl $0x2, %eax
jne 0x27c5
movq 0x10(%r12), %rsi
movabsq $-0x4000000000001, %rax # imm = 0xFFFBFFFFFFFFFFFF
cmpq %rax, %rsi
jbe 0x27ce
movq %r15, %rcx
movq %rsi, %r13
andq %r15, %r13
cmpl $0x2, (%r13)
jne 0x27ce
movq 0x18(%r12), %rax
andq %rcx, %rax
movq 0x10(%rax), %r12
movq 0x8(%rsp), %r14
movq %r14, %rdi
movq 0x10(%rsp), %rdx
callq 0x434c
movq %rax, 0x10(%rsp)
movq %r14, %rdi
movq 0x18(%rsp), %rsi
movq %r12, %rdx
callq 0x4ebe
movabsq $-0x4000000000001, %rcx # imm = 0xFFFBFFFFFFFFFFFF
cmpq %rcx, %rax
jbe 0x279f
movq %rax, %rcx
andq %r15, %rcx
cmpl $0x4, (%rcx)
jne 0x279f
cmpq $0x0, 0x10(%rcx)
jne 0x279f
movq %r13, 0x10(%rcx)
movq 0x8(%rsp), %rdi
movq %rax, %rsi
movq %rbx, %rdx
callq 0x434c
movq %rax, %rbx
movq 0x18(%rbp), %rbp
movabsq $0x7ffc000000000001, %r14 # imm = 0x7FFC000000000001
jmp 0x26d9
leaq 0x3c4b(%rip), %rsi      # 0x6417
jmp 0x27d5
leaq 0x3c70(%rip), %rsi      # 0x6445
movq 0x8(%rsp), %rdi
xorl %eax, %eax
callq 0x45ec
addq $0x3, %r14
movq %r14, %rax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rbx, %r14
movq 0x10(%rsp), %rdx
jmp 0x268a