// File: /workspace/github_c_makefile_star2_O0/jiribenes[P]scheme/src/core.c
// Function: builtin_define
static value_t builtin_define(vm_t *vm, env_t *env, value_t args) {
    cons_t *rest = AS_CONS(args);

    if (IS_SYMBOL(rest->car)) {  // (define <name> <body>)
        symbol_t *sym = AS_SYMBOL(rest->car);
        value_t body = AS_CONS(rest->cdr)->car;
        value_t val = eval(vm, env, body);

        if (IS_FUNCTION(val)) {
            // If <body> is a nameless function, set its name to <name>
            // (we won't do any renaming...)
            function_t *func = AS_FUNCTION(val);
            if (func->name == NULL) {
                func->name = sym;
            }
        }
        variable_add(vm, env, sym, val);

        return VOID_VAL;
    } else if (IS_CONS(rest->car)) {  // (define (<name> <params...>) <body...>)
        symbol_t *sym = AS_SYMBOL(AS_CONS(rest->car)->car);
        value_t params = AS_CONS(rest->car)->cdr;
        cons_t *body = AS_CONS(rest->cdr);

        function_t *func = function_new(vm, env, params, PTR_VAL(body));
        func->name = sym;

        variable_add(vm, env, sym, PTR_VAL(func));

        return VOID_VAL;
    } else {
        error_runtime(vm, "define: is wrong - first argument has to be"
                          "either a list or a symbol!");
        return NIL_VAL;
    }
}

// Assembly:
subq $0x98, %rsp
movq %rdi, 0x88(%rsp)
movq %rsi, 0x80(%rsp)
movq %rdx, 0x78(%rsp)
movabsq $0x3ffffffffffff, %rax  # imm = 0x3FFFFFFFFFFFF
andq 0x78(%rsp), %rax
movq %rax, 0x70(%rsp)
movq 0x70(%rsp), %rax
movq 0x10(%rax), %rdi
movl $0x2, %esi
callq 0x4d50
testb $0x1, %al
jne 0x2d2c
jmp 0x2dfa
movq 0x70(%rsp), %rcx
movabsq $0x3ffffffffffff, %rax  # imm = 0x3FFFFFFFFFFFF
andq 0x10(%rcx), %rax
movq %rax, 0x68(%rsp)
movq 0x70(%rsp), %rcx
movabsq $0x3ffffffffffff, %rax  # imm = 0x3FFFFFFFFFFFF
andq 0x18(%rcx), %rax
movq 0x10(%rax), %rax
movq %rax, 0x60(%rsp)
movq 0x88(%rsp), %rdi
movq 0x80(%rsp), %rsi
movq 0x60(%rsp), %rdx
callq 0x85b0
movq %rax, 0x58(%rsp)
movq 0x58(%rsp), %rdi
movl $0x4, %esi
callq 0x4d50
testb $0x1, %al
jne 0x2d94
jmp 0x2dc4
movabsq $0x3ffffffffffff, %rax  # imm = 0x3FFFFFFFFFFFF
andq 0x58(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0x50(%rsp), %rax
cmpq $0x0, 0x10(%rax)
jne 0x2dc2
movq 0x68(%rsp), %rcx
movq 0x50(%rsp), %rax
movq %rcx, 0x10(%rax)
jmp 0x2dc4
movq 0x88(%rsp), %rdi
movq 0x80(%rsp), %rsi
movq 0x68(%rsp), %rdx
movq 0x58(%rsp), %rcx
callq 0x7c70
movabsq $0x7ffc000000000005, %rax # imm = 0x7FFC000000000005
movq %rax, 0x90(%rsp)
jmp 0x2f44
movq 0x70(%rsp), %rax
movq 0x10(%rax), %rdi
xorl %esi, %esi
callq 0x4d50
testb $0x1, %al
jne 0x2e13
jmp 0x2f1c
movq 0x70(%rsp), %rax
movabsq $0x3ffffffffffff, %rcx  # imm = 0x3FFFFFFFFFFFF
andq 0x10(%rax), %rcx
movabsq $0x3ffffffffffff, %rax  # imm = 0x3FFFFFFFFFFFF
andq 0x10(%rcx), %rax
movq %rax, 0x48(%rsp)
movq 0x70(%rsp), %rcx
movabsq $0x3ffffffffffff, %rax  # imm = 0x3FFFFFFFFFFFF
andq 0x10(%rcx), %rax
movq 0x18(%rax), %rax
movq %rax, 0x40(%rsp)
movq 0x70(%rsp), %rcx
movabsq $0x3ffffffffffff, %rax  # imm = 0x3FFFFFFFFFFFF
andq 0x18(%rcx), %rax
movq %rax, 0x38(%rsp)
movq 0x88(%rsp), %rax
movq %rax, (%rsp)
movq 0x80(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0x40(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x38(%rsp), %rdi
callq 0x4d10
movq (%rsp), %rdi
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq %rax, %rcx
callq 0x69f0
movq %rax, 0x30(%rsp)
movq 0x48(%rsp), %rcx
movq 0x30(%rsp), %rax
movq %rcx, 0x10(%rax)
movq 0x88(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x80(%rsp), %rax
movq %rax, 0x20(%rsp)
movq 0x48(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0x30(%rsp), %rdi
callq 0x4d10
movq 0x18(%rsp), %rdi
movq 0x20(%rsp), %rsi
movq 0x28(%rsp), %rdx
movq %rax, %rcx
callq 0x7c70
movabsq $0x7ffc000000000005, %rax # imm = 0x7FFC000000000005
movq %rax, 0x90(%rsp)
jmp 0x2f44
movq 0x88(%rsp), %rdi
leaq 0x7400(%rip), %rsi      # 0xa32b
movb $0x0, %al
callq 0x73a0
movabsq $0x7ffc000000000001, %rax # imm = 0x7FFC000000000001
movq %rax, 0x90(%rsp)
movq 0x90(%rsp), %rax
addq $0x98, %rsp
retq
nopw %cs:(%rax,%rax)