// File: /workspace/github_c_makefile_star2_O0/qpfiffer[P]lair/src/eval.c
// Function: get_function_args
static const struct _lair_type **_get_function_args(
		struct _lair_runtime *r,
		const int argc,
		const struct _lair_ast *ast_node,
		struct _lair_env *env) {
	if (argc == 0)
		return NULL;

	const struct _lair_ast *next_node = ast_node->next;
	if (next_node->atom.type == LR_FUNCTION_ARG &&
			strncmp(next_node->atom.value.str, "!", 1) == 0) {
		/* I guess we're building a JIT now. */
		/* Evalue at the RHS: */
		ast_node->next->atom.type = LR_CALL;

		/* This one is a function, the next one is a call, so we evaluate the
		 * one after that:
		 */
		_reevaluate_until_break(r, env, ast_node->next->next);
	}

	if (next_node->atom.type == LR_CALL) {
		check(r, argc == 1, ERR_RUNTIME, "Function takes more than one argument, but RHS is only one argument.");
		/* We need to evaluate the RHS before we can pass it to the function
		 * as arguments.
		 */
		const struct _lair_type **args = calloc(1, sizeof(struct _lair_type *));
		args[0] = _lair_env_eval(r, ast_node->next, env);
		return args;
	}

	const struct _lair_type **args = calloc(argc, sizeof(struct _lair_type *));
	const struct _lair_ast *cur_node = ast_node->next;
	int i = 0;
	/* XXX: Bug here. You could have a function like this:
	 * ! print ! add_two x ! add_two 2 2
	 * Which would do something weird. Need to be able to see how far
	 * the eval went.
	 */
	for (;i < argc; i++) {
		check(r, cur_node != NULL, ERR_RUNTIME, "Not enough arguments to function.");
		args[i] = _lair_env_eval(r, cur_node, env);
		cur_node = cur_node->next;
	}
	return args;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
cmpl $0x0, -0x14(%rbp)
jne 0x344a
movq $0x0, -0x8(%rbp)
jmp 0x359e
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
cmpl $0x5, 0x28(%rax)
jne 0x34a6
movq -0x30(%rbp), %rax
movq 0x30(%rax), %rdi
leaq 0x304c(%rip), %rsi      # 0x64bb
movl $0x1, %edx
callq 0x1050
cmpl $0x0, %eax
jne 0x34a6
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movl $0xb, 0x28(%rax)
movq -0x10(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x8(%rax), %rdx
callq 0x35b0
movq -0x30(%rbp), %rax
cmpl $0xb, 0x28(%rax)
jne 0x3510
movq -0x10(%rbp), %rdi
cmpl $0x1, -0x14(%rbp)
sete %al
andb $0x1, %al
movzbl %al, %esi
movl $0x2, %edx
leaq 0x2ff1(%rip), %rcx      # 0x64bd
callq 0x1830
movl $0x1, %edi
movl $0x8, %esi
callq 0x1110
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x28(%rbp), %rdx
callq 0x27e0
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, (%rax)
movq -0x38(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x359e
movslq -0x14(%rbp), %rdi
movl $0x8, %esi
callq 0x1110
movq %rax, -0x40(%rbp)
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x48(%rbp)
movl $0x0, -0x4c(%rbp)
movl -0x4c(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x3596
movq -0x10(%rbp), %rdi
cmpq $0x0, -0x48(%rbp)
setne %al
andb $0x1, %al
movzbl %al, %esi
movl $0x2, %edx
leaq 0x2fa8(%rip), %rcx      # 0x6502
callq 0x1830
movq -0x10(%rbp), %rdi
movq -0x48(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0x27e0
movq %rax, %rdx
movq -0x40(%rbp), %rax
movslq -0x4c(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x48(%rbp)
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
jmp 0x3535
movq -0x40(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x50, %rsp
popq %rbp
retq
nopl (%rax,%rax)