// File: /workspace/github_c_makefile_star2_O0/hughbarney[P]zepl/lisp.c
// Function: evalExpr
Object *evalExpr(Object ** object, Object ** env, GC_PARAM)
{
	GC_TRACE(gcObject, *object);
	GC_TRACE(gcEnv, *env);

	GC_TRACE(gcFunc, nil);
	GC_TRACE(gcArgs, nil);
	GC_TRACE(gcBody, nil);

	for (;;) {
		if ((*gcObject)->type == TYPE_SYMBOL)
			return envLookup(*gcObject, *gcEnv);
		if ((*gcObject)->type != TYPE_CONS)
			return *gcObject;

		*gcFunc = (*gcObject)->car;
		*gcArgs = (*gcObject)->cdr;

		*gcFunc = evalExpr(gcFunc, gcEnv, GC_ROOTS);
		*gcBody = nil;

		if ((*gcFunc)->type == TYPE_LAMBDA) {
			*gcBody = (*gcFunc)->body;
			*gcArgs = evalList(gcArgs, gcEnv, GC_ROOTS);
			*gcEnv = newEnv(gcFunc, gcArgs, GC_ROOTS);
			*gcObject = evalProgn(gcBody, gcEnv, GC_ROOTS);
		} else if ((*gcFunc)->type == TYPE_MACRO) {
			*gcObject = expandMacroTo(gcFunc, gcArgs, gcObject, GC_ROOTS);
		} else if ((*gcFunc)->type == TYPE_PRIMITIVE) {
			Primitive *primitive = &primitives[(*gcFunc)->primitive];
			int nArgs = 0;

			for (Object * args = *gcArgs; args != nil; args = args->cdr, nArgs++)
				if (args->type != TYPE_CONS)
					exceptionWithObject(args, "is not a list");

			if (nArgs < primitive->nMinArgs)
				exceptionWithObject(*gcFunc, "expects at least %d arguments", primitive->nMinArgs);
			if (nArgs > primitive->nMaxArgs && primitive->nMaxArgs >= 0)
				exceptionWithObject(*gcFunc, "expects at most %d arguments", primitive->nMaxArgs);
			if (primitive->nMaxArgs < 0 && nArgs % -primitive->nMaxArgs)
				exceptionWithObject(*gcFunc, "expects a multiple of %d arguments", -primitive->nMaxArgs);

			switch ((*gcFunc)->primitive) {
			case PRIMITIVE_QUOTE:
				return (*gcArgs)->car;
			case PRIMITIVE_SETQ:
				return evalSetq(gcArgs, gcEnv, GC_ROOTS);
			case PRIMITIVE_PROGN:
				*gcObject = evalProgn(gcArgs, gcEnv, GC_ROOTS);
				break;
			case PRIMITIVE_IF:
				*gcObject = evalIf(gcArgs, gcEnv, GC_ROOTS);
				break;
			case PRIMITIVE_COND:
				*gcObject = evalCond(gcArgs, gcEnv, GC_ROOTS);
				break;
			case PRIMITIVE_LAMBDA:
				return evalLambda(gcArgs, gcEnv, GC_ROOTS);
			case PRIMITIVE_MACRO:
				return evalMacro(gcArgs, gcEnv, GC_ROOTS);
			default:
				*gcArgs = evalList(gcArgs, gcEnv, GC_ROOTS);
				return primitive->eval(gcArgs, GC_ROOTS);
			}
		} else
			exceptionWithObject(*gcFunc, "is not a function");
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x130, %rsp            # imm = 0x130
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movl $0x3, -0x48(%rbp)
movq $0x0, -0x40(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x30(%rbp)
leaq -0x48(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x50(%rbp)
leaq -0x48(%rbp), %rax
movq %rax, -0x20(%rbp)
movl $0x3, -0x78(%rbp)
movq $0x0, -0x70(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x68(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x60(%rbp)
leaq -0x78(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x80(%rbp)
leaq -0x78(%rbp), %rax
movq %rax, -0x20(%rbp)
movl $0x3, -0xa8(%rbp)
movq $0x0, -0xa0(%rbp)
movq 0x5f61(%rip), %rax      # 0xf220
movq %rax, -0x98(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x90(%rbp)
leaq -0xa8(%rbp), %rax
addq $0x10, %rax
movq %rax, -0xb0(%rbp)
leaq -0xa8(%rbp), %rax
movq %rax, -0x20(%rbp)
movl $0x3, -0xd8(%rbp)
movq $0x0, -0xd0(%rbp)
movq 0x5f16(%rip), %rax      # 0xf220
movq %rax, -0xc8(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0xc0(%rbp)
leaq -0xd8(%rbp), %rax
addq $0x10, %rax
movq %rax, -0xe0(%rbp)
leaq -0xd8(%rbp), %rax
movq %rax, -0x20(%rbp)
movl $0x3, -0x108(%rbp)
movq $0x0, -0x100(%rbp)
movq 0x5ecb(%rip), %rax      # 0xf220
movq %rax, -0xf8(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0xf0(%rbp)
leaq -0x108(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x110(%rbp)
leaq -0x108(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x50(%rbp), %rax
movq (%rax), %rax
cmpl $0x2, (%rax)
jne 0x93ac
movq -0x50(%rbp), %rax
movq (%rax), %rdi
movq -0x80(%rbp), %rax
movq (%rax), %rsi
callq 0x6e90
movq %rax, -0x8(%rbp)
jmp 0x97b5
movq -0x50(%rbp), %rax
movq (%rax), %rax
cmpl $0x3, (%rax)
je 0x93c8
movq -0x50(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x8(%rbp)
jmp 0x97b5
movq -0x50(%rbp), %rax
movq (%rax), %rax
movq 0x10(%rax), %rcx
movq -0xb0(%rbp), %rax
movq %rcx, (%rax)
movq -0x50(%rbp), %rax
movq (%rax), %rax
movq 0x18(%rax), %rcx
movq -0xe0(%rbp), %rax
movq %rcx, (%rax)
movq -0xb0(%rbp), %rdi
movq -0x80(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x9220
movq %rax, %rcx
movq -0xb0(%rbp), %rax
movq %rcx, (%rax)
movq 0x5e06(%rip), %rcx      # 0xf220
movq -0x110(%rbp), %rax
movq %rcx, (%rax)
movq -0xb0(%rbp), %rax
movq (%rax), %rax
cmpl $0x4, (%rax)
jne 0x94b0
movq -0xb0(%rbp), %rax
movq (%rax), %rax
movq 0x18(%rax), %rcx
movq -0x110(%rbp), %rax
movq %rcx, (%rax)
movq -0xe0(%rbp), %rdi
movq -0x80(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x9ed0
movq %rax, %rcx
movq -0xe0(%rbp), %rax
movq %rcx, (%rax)
movq -0xb0(%rbp), %rdi
movq -0xe0(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x60e0
movq %rax, %rcx
movq -0x80(%rbp), %rax
movq %rcx, (%rax)
movq -0x110(%rbp), %rdi
movq -0x80(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x97d0
movq %rax, %rcx
movq -0x50(%rbp), %rax
movq %rcx, (%rax)
jmp 0x97b0
movq -0xb0(%rbp), %rax
movq (%rax), %rax
cmpl $0x5, (%rax)
jne 0x94e9
movq -0xb0(%rbp), %rdi
movq -0xe0(%rbp), %rsi
movq -0x50(%rbp), %rdx
movq -0x20(%rbp), %rcx
callq 0x9df0
movq %rax, %rcx
movq -0x50(%rbp), %rax
movq %rcx, (%rax)
jmp 0x97ae
movq -0xb0(%rbp), %rax
movq (%rax), %rax
cmpl $0x6, (%rax)
jne 0x9794
movq -0xb0(%rbp), %rax
movq (%rax), %rax
movslq 0x10(%rax), %rcx
leaq 0x5d2f(%rip), %rax      # 0xf240
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x118(%rbp)
movl $0x0, -0x11c(%rbp)
movq -0xe0(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x128(%rbp)
movq -0x128(%rbp), %rax
cmpq 0x5cd8(%rip), %rax      # 0xf220
je 0x9590
movq -0x128(%rbp), %rax
cmpl $0x3, (%rax)
je 0x956b
movq -0x128(%rbp), %rdi
leaq 0x1fcb(%rip), %rsi      # 0xb52f
movb $0x0, %al
callq 0x50e0
jmp 0x956d
movq -0x128(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x128(%rbp)
movl -0x11c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x11c(%rbp)
jmp 0x953a
movl -0x11c(%rbp), %eax
movq -0x118(%rbp), %rcx
cmpl 0x8(%rcx), %eax
jge 0x95c4
movq -0xb0(%rbp), %rax
movq (%rax), %rdi
movq -0x118(%rbp), %rax
movl 0x8(%rax), %edx
leaq 0x1f9d(%rip), %rsi      # 0xb55a
movb $0x0, %al
callq 0x50e0
movl -0x11c(%rbp), %eax
movq -0x118(%rbp), %rcx
cmpl 0xc(%rcx), %eax
jle 0x9605
movq -0x118(%rbp), %rax
cmpl $0x0, 0xc(%rax)
jl 0x9605
movq -0xb0(%rbp), %rax
movq (%rax), %rdi
movq -0x118(%rbp), %rax
movl 0xc(%rax), %edx
leaq 0x1f3f(%rip), %rsi      # 0xb53d
movb $0x0, %al
callq 0x50e0
movq -0x118(%rbp), %rax
cmpl $0x0, 0xc(%rax)
jge 0x9650
movl -0x11c(%rbp), %eax
movq -0x118(%rbp), %rdx
xorl %ecx, %ecx
subl 0xc(%rdx), %ecx
cltd
idivl %ecx
cmpl $0x0, %edx
je 0x9650
movq -0xb0(%rbp), %rax
movq (%rax), %rdi
movq -0x118(%rbp), %rax
xorl %edx, %edx
subl 0xc(%rax), %edx
leaq 0x23a4(%rip), %rsi      # 0xb9ed
movb $0x0, %al
callq 0x50e0
movq -0xb0(%rbp), %rax
movq (%rax), %rax
movl 0x10(%rax), %eax
movq %rax, -0x130(%rbp)
subq $0x6, %rax
ja 0x9753
movq -0x130(%rbp), %rax
leaq 0x1e04(%rip), %rcx      # 0xb480
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0xe0(%rbp), %rax
movq (%rax), %rax
movq 0x10(%rax), %rax
movq %rax, -0x8(%rbp)
jmp 0x97b5
movq -0xe0(%rbp), %rdi
movq -0x80(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x9040
movq %rax, -0x8(%rbp)
jmp 0x97b5
movq -0xe0(%rbp), %rdi
movq -0x80(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x97d0
movq %rax, %rcx
movq -0x50(%rbp), %rax
movq %rcx, (%rax)
jmp 0x9792
movq -0xe0(%rbp), %rdi
movq -0x80(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x98e0
movq %rax, %rcx
movq -0x50(%rbp), %rax
movq %rcx, (%rax)
jmp 0x9792
movq -0xe0(%rbp), %rdi
movq -0x80(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x99b0
movq %rax, %rcx
movq -0x50(%rbp), %rax
movq %rcx, (%rax)
jmp 0x9792
movq -0xe0(%rbp), %rdi
movq -0x80(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x9b70
movq %rax, -0x8(%rbp)
jmp 0x97b5
movq -0xe0(%rbp), %rdi
movq -0x80(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x9c20
movq %rax, -0x8(%rbp)
jmp 0x97b5
movq -0xe0(%rbp), %rdi
movq -0x80(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x9ed0
movq %rax, %rcx
movq -0xe0(%rbp), %rax
movq %rcx, (%rax)
movq -0x118(%rbp), %rax
movq 0x10(%rax), %rax
movq -0xe0(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq *%rax
movq %rax, -0x8(%rbp)
jmp 0x97b5
jmp 0x97ac
movq -0xb0(%rbp), %rax
movq (%rax), %rdi
leaq 0x226b(%rip), %rsi      # 0xba10
movb $0x0, %al
callq 0x50e0
jmp 0x97ae
jmp 0x97b0
jmp 0x9384
movq -0x8(%rbp), %rax
addq $0x130, %rsp            # imm = 0x130
popq %rbp
retq
nopw %cs:(%rax,%rax)