// File: /workspace/github_c_makefile_star2_O0/qpfiffer[P]lair/src/eval.c
// Function: lair_call_runtime_function
static const struct _lair_type *_lair_call_runtime_function(struct _lair_runtime *r, const struct _lair_ast *top_level_ast, const struct _lair_ast *defined_function_ast, struct _lair_env *env) {
	/* Figure out how many arguments are require for this function. */
	int argc = 0;
	struct _lair_ast *_first_function_arg = ((struct _lair_ast *)defined_function_ast)->next;
	struct _lair_ast *_func_eval_ast = _first_function_arg;
	while (_func_eval_ast->atom.type == LR_FUNCTION_ARG) {
		argc++;
		_func_eval_ast = _func_eval_ast->next;
	}

	if (argc > 0) {
		const struct _lair_type **args = _get_function_args(r, argc, top_level_ast, env);
		check(r, args != NULL, ERR_RUNTIME, "No arguments.");

		/* So heres how this works. What we do is create a new `struct _lair_env` object
		 * with the parent set to the current `env`, and then we dynamically
		 * create new 'functions' which return the function arguments. Since there
		 * are no real variables in Den, we just create functions that return the
		 * values that we want, and bind them into the local scope. Or something like
		 * that.
		 */
		struct _lair_env *scoped_env = _lair_env_with_parent(env);
		int i;
		struct _lair_ast *function_parameter = _first_function_arg;
		for (i = 0; i < argc; i++) {
			check(r, function_parameter->atom.type == LR_FUNCTION_ARG, ERR_SYNTAX,
					"Ran out of function argument parameters, buf function expects more.");
			_lair_add_simple_function(scoped_env, function_parameter->atom.value.str, args[i]);
			function_parameter = function_parameter->next;
		}
		const struct _lair_type *to_return = _lair_env_eval(r, _func_eval_ast, scoped_env);
		_lair_free_env(scoped_env);
		return to_return;
	} else {
		return _lair_env_eval(r, _func_eval_ast, env);
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movl $0x0, -0x2c(%rbp)
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
cmpl $0x5, 0x28(%rax)
jne 0x3314
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x40(%rbp)
jmp 0x32f3
cmpl $0x0, -0x2c(%rbp)
jle 0x33fd
movq -0x10(%rbp), %rdi
movl -0x2c(%rbp), %esi
movq -0x18(%rbp), %rdx
movq -0x28(%rbp), %rcx
callq 0x3420
movq %rax, -0x48(%rbp)
movq -0x10(%rbp), %rdi
cmpq $0x0, -0x48(%rbp)
setne %al
andb $0x1, %al
movzbl %al, %esi
movl $0x2, %edx
leaq 0x31d1(%rip), %rcx      # 0x6524
callq 0x1830
movq -0x28(%rbp), %rdi
callq 0x27a0
movq %rax, -0x50(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0x60(%rbp)
movl $0x0, -0x54(%rbp)
movl -0x54(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jge 0x33d5
movq -0x10(%rbp), %rdi
movq -0x60(%rbp), %rax
cmpl $0x5, 0x28(%rax)
sete %al
andb $0x1, %al
movzbl %al, %esi
movl $0x1, %edx
leaq 0x3196(%rip), %rcx      # 0x6532
callq 0x1830
movq -0x50(%rbp), %rdi
movq -0x60(%rbp), %rax
movq 0x30(%rax), %rsi
movq -0x48(%rbp), %rax
movslq -0x54(%rbp), %rcx
movq (%rax,%rcx,8), %rdx
callq 0x2f80
movq -0x60(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x60(%rbp)
movl -0x54(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
jmp 0x3374
movq -0x10(%rbp), %rdi
movq -0x40(%rbp), %rsi
movq -0x50(%rbp), %rdx
callq 0x27e0
movq %rax, -0x68(%rbp)
movq -0x50(%rbp), %rdi
callq 0x31f0
movq -0x68(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x3412
movq -0x10(%rbp), %rdi
movq -0x40(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0x27e0
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x70, %rsp
popq %rbp
retq
nopl (%rax)