// File: /workspace/github_c_makefile_star2_O0/samsonjs[P]lake/src/eval.c
// Function: define
static LakeVal *_define(LakeCtx *ctx, Env *env, LakeList *expr)
{
    /* TODO: make these more robust, check all expected params */

    /* (define x 42) */
    if (LIST_N(expr) == 3 && lake_is_type(TYPE_SYM, LIST_VAL(expr, 1)))
    {
        list_shift(expr); /* drop the "define" symbol */
        LakeSym *var = SYM(list_shift(expr));
        LakeVal *form = list_shift(expr);
        env_define(env, var, eval(ctx, env, form));
    }

    /* (define (inc x) (+ 1 x)) */
    else if (LIST_N(expr) >= 3 && lake_is_type(TYPE_LIST, LIST_VAL(expr, 1)))
    {
        list_shift(expr); /* drop the "define" symbol */
        LakeList *params = LIST(list_shift(expr));
        LakeSym *var = SYM(list_shift(params));
        LakeList *body = expr;
        env_define(env, var, VAL(fn_make(params, NULL, body, env)));
    }

    /* (define (print format . args) (...)) */
    else if (LIST_N(expr) >= 3 && lake_is_type(TYPE_DLIST, LIST_VAL(expr, 1)))
    {
        list_shift(expr); /* drop the "define" symbol */
        LakeDottedList *def = DLIST(list_shift(expr));
        LakeList *params = dlist_head(def);
        LakeSym *varargs = SYM(dlist_tail(def));
        LakeSym *var = SYM(list_shift(params));
        LakeList *body = expr;
        env_define(env, var, VAL(fn_make(params, varargs, body, env)));
    }

    else
    {
        invalid_special_form(expr, "define requires at least 2 parameters");
    }

    return NULL;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x18(%rbp), %rax
cmpq $0x3, 0x18(%rax)
jne 0x239b
movq -0x18(%rbp), %rcx
movl $0x1, %eax
cmpq 0x18(%rcx), %rax
jae 0x2327
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x8(%rax), %rax
movq %rax, -0x70(%rbp)
jmp 0x232f
xorl %eax, %eax
movq %rax, -0x70(%rbp)
jmp 0x232f
movq -0x70(%rbp), %rsi
movl $0x1, %edi
callq 0x40d0
cmpl $0x0, %eax
je 0x239b
movq -0x18(%rbp), %rdi
callq 0x4a90
movq -0x18(%rbp), %rdi
callq 0x4a90
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rdi
callq 0x4a90
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0x2840
movq -0x80(%rbp), %rdi
movq -0x78(%rbp), %rsi
movq %rax, %rdx
callq 0x1a10
jmp 0x2554
movq -0x18(%rbp), %rax
cmpq $0x3, 0x18(%rax)
jb 0x2460
movq -0x18(%rbp), %rcx
movl $0x1, %eax
cmpq 0x18(%rcx), %rax
jae 0x23ce
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x8(%rax), %rax
movq %rax, -0x88(%rbp)
jmp 0x23d9
xorl %eax, %eax
movq %rax, -0x88(%rbp)
jmp 0x23d9
movq -0x88(%rbp), %rsi
movl $0x5, %edi
callq 0x40d0
cmpl $0x0, %eax
je 0x2460
movq -0x18(%rbp), %rdi
callq 0x4a90
movq -0x18(%rbp), %rdi
callq 0x4a90
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rdi
callq 0x4a90
movq %rax, -0x38(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x30(%rbp), %rdi
movq -0x40(%rbp), %rdx
movq -0x10(%rbp), %rcx
xorl %eax, %eax
movl %eax, %esi
callq 0x32c0
movq -0x98(%rbp), %rdi
movq -0x90(%rbp), %rsi
movq %rax, %rdx
callq 0x1a10
jmp 0x2552
movq -0x18(%rbp), %rax
cmpq $0x3, 0x18(%rax)
jb 0x2540
movq -0x18(%rbp), %rcx
movl $0x1, %eax
cmpq 0x18(%rcx), %rax
jae 0x2493
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x8(%rax), %rax
movq %rax, -0xa0(%rbp)
jmp 0x249e
xorl %eax, %eax
movq %rax, -0xa0(%rbp)
jmp 0x249e
movq -0xa0(%rbp), %rsi
movl $0x6, %edi
callq 0x40d0
cmpl $0x0, %eax
je 0x2540
movq -0x18(%rbp), %rdi
callq 0x4a90
movq -0x18(%rbp), %rdi
callq 0x4a90
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rdi
callq 0x16f0
movq %rax, -0x50(%rbp)
movq -0x48(%rbp), %rdi
callq 0x1710
movq %rax, -0x58(%rbp)
movq -0x50(%rbp), %rdi
callq 0x4a90
movq %rax, -0x60(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq -0x50(%rbp), %rdi
movq -0x58(%rbp), %rsi
movq -0x68(%rbp), %rdx
movq -0x10(%rbp), %rcx
callq 0x32c0
movq -0xb0(%rbp), %rdi
movq -0xa8(%rbp), %rsi
movq %rax, %rdx
callq 0x1a10
jmp 0x2550
movq -0x18(%rbp), %rdi
leaq 0x6cca(%rip), %rsi      # 0x9215
callq 0x3210
jmp 0x2552
jmp 0x2554
xorl %eax, %eax
addq $0xb0, %rsp
popq %rbp
retq
nop