/* -*- mode:c -*- */

#include "compiler.h"
#include "gc.h"
#include "lib/std.h"
#include "lisp.h"
#include "plat/plat.h"

#include <dasm_proto.h>
#include <dasm_x86.h>

#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define value_size sizeof(value_t)

|.arch x86;

|.macro setup, nvars;
|1:;
| push ebp;
| mov ebp, esp;
| sub esp, (value_size * nvars);
|.endmacro;

|.macro cleanup;
| mov esp, ebp;
| pop ebp;
| ret;
|.endmacro;

|.macro call_extern, address;
| call &address;
|.endmacro;

dasm_State *d;
unsigned int npc = 8;

|.macro run_gc;
| mov eax, esp;
| push ebp;
| push eax;
| mov eax, _do_gc;
| call eax;
|.endmacro;

struct function *find_function(struct environment *env, char *name)
{
	struct function *f;

	for (f = env->first; f && strcmp(f->name, name); f = f->prev)
	{
	}

	return f;
}

unsigned int local_alloc(struct local *local)
{
	for (int i = 0; i < local->num_stack_slots; i++)
	{
		if (local->stack_slots[i] == false)
		{
			local->stack_slots[i] = true;

			if (i >= local->num_stack_entries)
				local->num_stack_entries++;

			return i;
		}
	}

	int old_size = local->num_stack_slots;
	local->num_stack_slots += 4;
	local->stack_slots =
	    realloc(local->stack_slots, local->num_stack_slots * sizeof(bool));
	// unreadable: set the remaining slots to unused
	memset(local->stack_slots + old_size, 0, local->num_stack_slots - old_size);
	local->stack_slots[old_size] = true;

	return old_size;
}

void local_free(struct local *local, unsigned int slot)
{
	local->stack_slots[slot] = false;
}

void del_local(struct local *local)
{
	free(local->stack_slots);

	for (struct variable *next, *f = local->first; f; f = next)
	{
		next = f->prev;
		free(f);
	}
}

void del_env(struct environment *env)
{
	for (struct function *next, *f = env->first; f; f = next)
	{
		next = f->prev;
		// We're not gonna bother munmap()ing the function
		free(f);
	}

	for (struct loaded_file *next, *l = env->first_loaded; l; l = next)
	{
		next = l->previous;
		free(l->resolved_path);
		free(l);
	}

	free(env);
}

void add_load(struct environment *env, char *path)
{
	static char buffer[512];
	long size = readlink(path, buffer, 512);
	buffer[size] = '\0';
	char *resolved = strdup(buffer);

	struct loaded_file *f = malloc(sizeof(struct loaded_file));
	f->resolved_path = resolved;
	f->previous = env->first_loaded;
	env->first_loaded = f;
}

struct error compile_function(value_t args, enum namespace namespace,
							  struct environment *env,
							  struct local *local_out,
							  struct local *local_parent,
							  struct args **args_out, char *name,
							  char *path,
							  dasm_State **state)
{
	UNUSED(namespace);

	E_INIT();

	dasm_State *d;
	dasm_State **Dst = &d;

	|.section code, imports;
	dasm_init(&d, DASM_MAXSECTION);

	|.globals lbl_;
	void *labels[lbl__MAX];
	dasm_setupglobal(&d, labels, lbl__MAX);

	|.actionlist lisp_actions;
	dasm_setup(&d, lisp_actions);

	struct local local;
	local.parent = NULL;
	local.first = NULL;
	local.num_vars = 0;
	local.npc = 8;
	local.nextpc = 0;
	local.stack_slots = malloc(sizeof(bool) * 4);
	memset(local.stack_slots, 0, sizeof(bool) * 4);
	local.num_stack_slots = 4;
	local.num_stack_entries = 0;
	local.num_closure_slots = 0;
	local.parent = local_parent;
	local.current_function_name = name;
	local.current_file_path = path;

	dasm_growpc(&d, local.npc);

	value_t arglist = car(args);
	value_t body = cdr(args);

	// This will add the arguments to local too.
	struct args *ar;
	TRY(list_to_args(env, arglist, &local, &ar));
	local.args = ar;

	if (!ar)
	{
		NEARVAL(arglist);
		THROW(EMALFORMED, "Malformed argument list");
	}

	for (value_t body_ = body; !nilp(body_); body_ = cdr(body_))
	{
		TRY(walk_and_alloc(env, &local, carref(body_)));
	}

	| setup (local.num_stack_entries);

	memset(local.stack_slots, 0, local.num_stack_slots * sizeof(bool));
	local.num_stack_entries = 0;

	for (; !nilp(body); body = cdr(body))
	{
		bool tail = nilp(cdr(body));
		TRY(compile_expression(env, &local, car(body), tail, Dst));
	}

	| cleanup;

	if (local_out)
		*local_out = local;

	if (args_out)
		*args_out = ar;

	*state = d;

	OKAY();
}

struct error compile_tl(value_t val, struct environment *env, char *fname)
{
	E_INIT();

	NEARVAL(val);

	if (!listp(val))
	{
		THROW(EEXPECTED, "Top level form must be a list");
	}

	value_t form = car(val);
	value_t args = cdr(val);

	if (symstreq(form, "defun") || symstreq(form, "defmacro"))
	{
		enum namespace namespace = NS_FUNCTION;

		if (symstreq(form, "defmacro"))
			namespace = NS_MACRO;

		struct local local;
		struct args *a;
		char *name = (char *)(car(args) ^ SYMBOL_TAG);

		dasm_State *d;
		TRY(compile_function(cdr(args), namespace, env, &local,
							 NULL, &a, name, fname, &d));

		add_function(env, name, link_program(&d), a, namespace);

		dasm_free(&d);
		del_local(&local);
	}
	else if (symstreq(form, "progn"))
	{
		for (value_t val = args; !nilp(val); val = cdr(val))
		{
			TRY(compile_tl(car(val), env, fname));
		}
	}
	else if (symstreq(form, "load"))
	{
		if (length(args) != 1)
		{
			NEARVAL(args);
			THROW(EARGS, "load expects exactly 1 argument, %d given",
				  length(args));
		}
		load_relative(env, fname, car(args));
	}

	OKAY();
}

struct error walk_and_alloc(struct environment *env, struct local *local, value_t *bp)
{
	E_INIT();

	value_t body = *bp;

	// TODO: handle macros
	if (!listp(body))
		OKAY();

	value_t args = cdr(body);

	if (symstreq(car(body), "let1"))
	{
		int slot = local_alloc(local);

		value_t expr = cdr(args);
		for (; !nilp(expr); expr = cdr(expr))
		{
			walk_and_alloc(env, local, carref(expr));
		}

		local_free(local, slot);
	}
	else if (symstreq(car(body), "lambda"))
	{
		// We don't want to walk the lambda because it's another function. When
		// the lambda is compiled it will be walked.
		OKAY();
	}
	else
	{
		// Is this a macro?
		
		struct function *mac = NULL;

		if (symbolp(car(body)))
			mac = find_function(env, (char *)(car(body) ^ SYMBOL_TAG));
		else
			walk_and_alloc(env, local, carref(body));

		if (mac && mac->namespace == NS_MACRO)
		{
			unsigned char pool = push_pool(0);
			value_t form = call_list(mac, args);
			pop_pool(pool);

			add_to_pool(form);
			*bp = form;

			walk_and_alloc(env, local, bp);
		}
		else
		{
			for (; !nilp(args); args = cdr(args))
			{
				walk_and_alloc(env, local, carref(args));
			}
		}
	}

	OKAY();
}

bool load(struct environment *env, char *path)
{
	if (!file_exists(path))
		return false;

	add_load(env, path);

	unsigned char pool = make_pool();
	unsigned char pop = push_pool(pool);

	struct istream *is = new_fistream(path, false);
	if (!is)
		return false;

	value_t val;

	struct error read_error;

	while (IS_OKAY((read_error = read1(is, &val))))
	{
		if (!IS_OKAY(compile_tl(val, env, path)))
		{
			goto failure;
		}
	}

	if (!read_error.safe_state)
	{
		goto failure;
	}

	del_fistream(is);
	pop_pool(pop);

	return true;

failure:
	del_fistream(is);
	pop_pool(pool);

	return false;
}

value_t load_relative(struct environment *env, char *to, value_t name)
{
	if (!stringp(name))
		return nil;

	char *new_path = (char *)(name ^ STRING_TAG);
	char *relative_to = strdup(to);
	char full_path[512];

	snprintf(full_path, 512, "%s/%s", dirname(relative_to), new_path);

	if (load(env, full_path))
		return t;
	else
		return nil;
}

struct error compile_file(char *filename, struct environment **e)
{
	E_INIT();

	value_t val;
	struct environment *env = malloc(sizeof(struct environment));
	env->first = NULL;
	env->first_loaded = NULL;

	add_load(env, filename);
	TRY(load_std(env));

	bool ok_ = load(env, filename);

	if (!ok_)
	{
		free(env);
		THROWSAFE(ENOTFOUND);
	}

	*e = env;

	OKAY();
}

int nextpc(struct local *local, dasm_State **Dst)
{
	int n = local->nextpc++;
	if (n > local->npc)
	{
		local->npc += 16;
		dasm_growpc(Dst, local->npc);
	}
	return n;
}

struct error compile_backquote(struct environment *env, struct local *local,
							   value_t val, dasm_State **Dst)
{
	E_INIT();

	if (!listp(val))
	{
		| mov eax, (val);
	}
	else
	{
		value_t fsym = car(val), args = cdr(val);
		int nargs = length(args),
			n = length(val);

		NEARVAL(val);

		if (symstreq(fsym, "unquote"))
		{
			if (nargs != 1)
			{
				THROW(EARGS, "unquote (or ,) takes exactly 1 argument");
			}

			TRY(compile_expression(env, local, car(args), false, Dst));
		}
		else
		{
			| push nil;

			for (int i = n - 1; i >= 0; i--)
			{
				value_t v = elt(val, i);

				if (listp(v) && symstreq(car(v), "unquote-splice"))
				{
					NEARVAL(v);

					if (length(v) != 2)
					{
						THROW(EARGS, "unquote-splice (or ,@) takes exactly 1 argument");
					}

					value_t expr = car(cdr(v));

					if (!listp(expr))
					{
						THROW(EINVALID, "unquote-splice (or ,@) argument must be a list");
					}

					TRY(compile_expression(env, local, expr, false, Dst));
					| push eax;
					| call_extern merge2;
					| add esp, 8;
					| push eax;
				}
				else
				{
					TRY(compile_backquote(env, local, v, Dst));
					| push eax;
					| call_extern cons;
					| add esp, 8;

					// Remove unnecessary pop
					| push eax;
				}
			}
			| pop eax;
		}
	}

	OKAY();
}

value_t eval(struct environment *env, value_t form)
{
	// Eval!
	value_t function = cons(nil, cons(form, nil));

	struct local local;
	struct args *args;

	dasm_State *d;
	struct error err;

	if (!IS_OKAY((err = compile_function(function, NS_ANONYMOUS, env, &local, NULL,
										 &args, NULL, "/", &d))))
	{
		ereport(err);
		return nil;
	}

	del_local(&local);

	value_t (*f)() = link_program(&d);
	return f();
}

struct error compile_variable(struct variable *v, dasm_State *Dst)
{
	E_INIT();
	switch (v->type)
	{
	case V_ARGUMENT:
		| mov eax, dword[ebp + (value_size * (v->number + 2))];
		break;
	case V_BOUND:
		| mov eax, dword[ebp - ((v->number + 1) * value_size)];
		break;
	case V_FREE:
		// edi is the closure context pointer
		| mov eax, dword[edi + (v->number * value_size)];
		break;
	default:
		THROW(EUNIMPL, "Sorry, can only access V_ARGUMENT, V_BOUND, and V_FREE vars");
	}
	OKAY();
}

struct error compile_expression(struct environment *env, struct local *local,
								value_t val, bool tail, dasm_State **Dst)
{
	E_INIT();

	NEARVAL(val);

	if (symstreq(val, "nil") || nilp(val))
	{
		| mov eax, (nil);
	}
	else if (symstreq(val, "t"))
	{
		| mov eax, (t);
	}
	else if (integerp(val) || stringp(val))
	{
		| mov eax, val;
	}
	else if (listp(val))
	{
		value_t fsym = car(val);
		value_t args = cdr(val);
		int nargs = length(args);

		if (!symbolp(fsym))
		{
			THROW(EEXPECTED, "Function name must be a symbol");
		}

		if (symstreq(fsym, "if"))
		{
			if (nargs < 2 || nargs > 3)
			{
				THROW(EARGS, "Must give at least 2 arguments to if");
			}

			TRY(compile_expression(env, local, car(args), false, Dst));
			int false_label = nextpc(local, Dst),
			    after_label = nextpc(local, Dst);

			// result is in eax
			| cmp eax, (nil);
			| je =>false_label;

			TRY(compile_expression(env, local, elt(args, 1), tail, Dst));
			| jmp =>after_label;
			|=>false_label:;
			if (nargs == 3)
				TRY(compile_expression(env, local, elt(args, 2), tail, Dst));
			|=>after_label:;
		}
		else if (symstreq(fsym, "and") || symstreq(fsym, "or"))
		{
			bool or = symstreq(fsym, "or"); // false == and

			// Boolean and and or, short circuit like &&/||
			if (nargs < 1)
			{
				THROW(EARGS, "and & or require at least 1 argument.");
			}

			int after = nextpc(local, Dst);

			for (; !nilp(args); args = cdr(args))
			{
				NEARVAL(args);

				TRY(compile_expression(env, local, car(args), false, Dst));
				if (!nilp(cdr(args)))
				{
					| cmp eax, nil;
					if (or)
					{
						| jne =>after;
					}
					else
					{
						| je =>after;
					}
				}
			}

			|=>after:;
		}
		else if (symstreq(fsym, "progn"))
		{
			for (value_t val = args; !nilp(val); val = cdr(val))
			{
				NEARVAL(args);

				bool t = tail && nilp(cdr(val));
				TRY(compile_expression(env, local, car(val), t, Dst));
			}
		}
		else if (symstreq(fsym, "let1"))
		{
			if (nargs < 2)
			{
				THROW(EARGS, "Must give at least 2 arguments to let1");
			}
			value_t binding = car(args);
			value_t rest = cdr(args);

			NEARVAL(binding);
			if (length(binding) != 2)
			{
				THROW(EARGS, "Binding list in let1 must contain exactly two entries");
			}

			NEARVAL(rest);

			value_t name = car(binding);
			value_t value = car(cdr(binding));

			TRY(compile_expression(env, local, value, false, Dst));

			int i = local_alloc(local);

			add_variable(local, V_BOUND, (char *)(name ^ SYMBOL_TAG), i);

			| mov dword[ebp - ((i + 1) * value_size)], eax;

			for (; !nilp(rest); rest = cdr(rest))
			{
				bool t = tail && nilp(cdr(rest));
				NEARVAL(rest);
				TRY(compile_expression(env, local, car(rest), t, Dst));
			}

			local_free(local, i);
		}
		else if (symstreq(fsym, "gc"))
		{
			if (nargs)
			{
				THROW(EARGS, "gc takes no arguments");
			}

			| run_gc;
		}
		else if (symstreq(fsym, "quote"))
		{
			if (nargs != 1)
				THROW(EARGS, "quote should take exactly 1 argument");

			// Simple!
			| mov eax, (car(args));
		}
		else if (symstreq(fsym, "backquote"))
		{
			if (nargs != 1)
				THROW(EARGS, "backquote should take exactly 1 argument");

			TRY(compile_backquote(env, local, car(args), Dst));
		}
		else if (symstreq(fsym, "function"))
		{
			if (nargs != 1)
			{
				THROW(EARGS, "function should take exactly 1 argument");
			}

			NEARVAL(args);
			if (!symbolp(car(args)))
			{
				THROW(EINVALID, "argument to function should be a symbol resolvable at "
				    "compile time");
			}

			char *name = (char *)(car(args) ^ SYMBOL_TAG);

			if (!strcmp(name, local->current_function_name))
			{
				| push 0;
				| push local->args;
				| push <1;
				| call_extern create_closure;
			}
			else
			{
				struct function *f = find_function(env, name);

				if (!f)
				{
					THROW(EINVALID, "Function `%s' does not exist", (char *)(car(args) ^ SYMBOL_TAG));
				}
				value_t closure = create_closure(f->code_ptr, f->args, 0);
				| mov eax, (closure);
			}
		}
		else if (symstreq(fsym, "list"))
		{
			| push (nil);

			for (int i = nargs - 1; i >= 0; i--)
			{
				TRY(compile_expression(env, local, elt(args, i), false, Dst));

				| push eax;
				| call_extern cons;
				| add esp, (2 * value_size);
				| push eax;
			}
			| pop eax;
		}
		else if (symstreq(fsym, "lambda"))
		{
			// Compile the function with this as the parent scope
			struct local new_local;
			int nargs_out;
			dasm_State *d;
			TRY(compile_function(
					args, NS_ANONYMOUS, env, &new_local, local, &nargs_out,
					"recurse", local->current_file_path, &d));

			// Link the function
			void *func_ptr = link_program(&d);

			// Create a closure object with the correct number of captures at
			// runtime
			| push (new_local.num_closure_slots);
			| push (nargs_out);
			| push (func_ptr);
			| call_extern create_closure;
			| add esp, 12;

			// Walk the generated local scope for V_FREE variables, since each
			// of these exists in our scope (or higher), evaluate it and set it
			// as a member of the lambda capture.

			for (struct variable *var = new_local.first; var; var = var->prev)
			{
				if (var->type == V_FREE)
				{
					// Closure in eax
					| push eax;
					// Variable now in eax
					TRY(compile_variable(find_variable(local, var->name), Dst));
					| push eax;

					// The capture offset
					| push (var->number);
					| call_extern set_closure_capture_variable;
					// Skip the value and index
					| add esp, 8;
					// Pop the closure back in to eax
					| pop eax;
				}
			}

			// Closure is still in eax

			dasm_free(&d);
			del_local(&new_local);
		}
		else if (symstreq(fsym, "eval"))
		{
			if (nargs != 1)
			{
				THROW(EARGS, "eval takes exactly 1 argument");
			}

			TRY(compile_expression(env, local, car(args), false, Dst));
			| push eax;
			| push (env);
			| call_extern eval;
		}
		else if (symstreq(fsym, "load"))
		{
			if (nargs != 1)
			{
				THROW(EARGS, "load takes exactly 1 argument, %d given", nargs);
			}

			TRY(compile_expression(env, local, car(args), false, Dst));
			| push eax;
			| push (local->current_file_path);
			| push (env);
			| call_extern load_relative;
		}
		else
		{
			char *name = (char *)(fsym ^ SYMBOL_TAG);
			struct function *func = find_function(env, name);

			bool is_recursive = false;
			struct args *nargs_needed = NULL;

			// The number of arguments actually passed on the stack,
			// i.e. all varargs are 1.
			int real_nargs;

			if (local->current_function_name &&
			    symstreq(fsym, local->current_function_name))
			{
				is_recursive = true;
				nargs_needed = local->args;
			}
			else
			{
				if (func == NULL)
				{
					THROW(EINVALID, "Function %s undefined", name);
				}

				nargs_needed = func->args;
			}

			if (!are_args_acceptable(nargs_needed, nargs))
			{
				THROW(EARGS,
					  "wrong number of args in function call: %s, "
					  "want %d args but given %d\n",
					  name, nargs_needed->num_required, nargs);
			}

			int total_taken = nargs_needed->num_optional +
				nargs_needed->num_required;

			real_nargs = total_taken + (nargs_needed->variadic ? 1 : 0);

			if (is_recursive || func->namespace == NS_FUNCTION)
			{
				int nargs = length(args);

				int line = cons_line(val);
				char *file = cons_file(val);

				if (nargs_needed->variadic)
				{
					| push (nil);
				}

				if (nargs > total_taken && nargs_needed->variadic)
				{
					// We are passing varargs, which means we need to make a list

					for (int i = nargs - 1; i >= total_taken; i--)
					{
						TRY(compile_expression(env, local, elt(args, i), false, Dst));
						| push eax;
						| call_extern cons;
						| add esp, 8;
						| push eax;
					}
				}

				for (int i = nargs_needed->num_optional - 1;
				     i >= nargs - nargs_needed->num_required; i--)
				{
					// Push the default optional values
					| push (nargs_needed->optional_arguments[i].value);
				}

				int min = MIN(nargs, total_taken);

				for (int i = min - 1; i >= 0; i--)
				{
					TRY(compile_expression(env, local, elt(args, i), false, Dst));
					| push eax;
				}

				if (is_recursive)
				{
					if (tail)
					{
						// Move all the arguments pushed to the stack
						// back up to the argument bit of the stack.

						for (int i = 0; i < real_nargs; i++)
						{
							| pop eax;
							| mov dword[ebp + (value_size * (i + 2))], eax;
						}

						// Jmp back to start
						| mov esp, ebp;
						| pop ebp;
						| jmp <1;
					}
					else
					{
						| call <1;
					}
				}
				else
				{
					// | mov ebx, (func->code_addr);
					| call_extern func->code_addr;
				}
				| add esp, (real_nargs * value_size);
				// result in eax
			}
			else if (func->namespace == NS_MACRO)
			{
				// Make sure that the stuff allocated by the macro isn't in a
				// pool
				unsigned char pool = push_pool(0);

				value_t expanded_to = call_list(func, args);

				pop_pool(pool);

				TRY(compile_expression(env, local, expanded_to, false, Dst));
			}
		}
	}
	else if (symbolp(val))
	{
		if (symstreq(val, "+current-file+"))
		{
			value_t file_name_val = strval(local->current_file_path);

			| mov eax, (file_name_val);
		}
		else
		{
			struct variable *v =
			    find_variable(local, (char *)(val ^ SYMBOL_TAG));

			if (!v)
			{
				THROW(EINVALID, "Variable `%s' unbound", (char *)(val ^ SYMBOL_TAG));
			}

			TRY(compile_variable(v, Dst));
		}
	}
	else if (closurep(val))
	{
		| mov eax, val;
	}
	else
	{
		printval(val, 1);
		THROW(EUNIMPL, "Don't know how to compile this, sorry.");
	}

	OKAY();
}

struct variable *add_variable(struct local *local, enum var_type type,
                              char *name, int number)
{
	struct variable *var = malloc(sizeof(struct variable));
	var->prev = local->first;
	var->type = type;
	var->name = name;
	var->number = number;

	local->first = var;

	return var;
}

void destroy_local(struct local *local)
{
	for (struct variable *v = local->first; v;)
	{
		struct variable *t = v;
		v = v->prev;
		free(t);
	}
}

struct variable *find_variable(struct local *local, char *name)
{
	struct variable *v = local->first;

	for (; v && strcmp(v->name, name) != 0; v = v->prev)
	{
	}

	if (!v)
	{
		if (local->parent)
		{
			v = find_variable(local->parent, name);

			if (v)
			{
				// We found this in a parent scope, add it as a V_FREE variable
				// to skip the search.
				v = add_variable(local, V_FREE, name,
				                 local->num_closure_slots++);
			}
		}
	}
	return v;
}

extern value_t _call_list(void *addr, value_t list, value_t *edi);

value_t call_list_args(void *code_ptr, struct args *args, value_t list,
                       void *data)
{
	list = deep_copy(list);

	int nargs = length(list);

	value_t *val = &list;

	for (value_t i = list; !nilp(i); i = cdr(i))
	{
		val = cdrref(i);
	}

	int total_required = args->num_required + args->num_optional;

	if (nargs > total_required)
	{
		// Take the remainder of the list and put it as the last item in the
		// list.
		value_t trailing = cxdr(list, total_required);
		value_t last_item = cons(trailing, nil);

		*cxdrref(&list, total_required) = last_item;
	}
	else if (nargs < total_required)
	{
		for (int i = nargs - args->num_required; i < args->num_optional; i++)
		{
			// Append the i-th defualt argument
			value_t appended = cons(args->optional_arguments[i].value, nil);
			*val = appended;
			val = cdrref(appended);
		}
	}

	// We want to call this if we pass the correct # of arguments or less, just
	// not if we have already passed varargs. Appends a nil argument.
	if (nargs <= total_required)
	{
		// Enough real arguments but no variadic arguments. Pass a nil list.
		*val = cons(nil, nil);
	}

	return _call_list(code_ptr, list, data);
}

value_t call_list(struct function *fun, value_t list)
{
	return call_list_args(fun->code_ptr, fun->args, list, NULL);
}

value_t call_list_closure(struct closure *c, value_t list)
{
	return call_list_args(c->function, c->args, list, c->data);
}

struct args *new_args()
{
	struct args *a = malloc(sizeof(struct args));
	a->num_optional = 0;
	a->num_required = 0;
	a->variadic = false;

	return a;
}

struct args *add_optional_arg(struct args *args, value_t name, value_t value)
{
	int i = args->num_optional++;
	args =
	    realloc(args, sizeof(struct args) + sizeof(struct optional_argument) *
	                                            args->num_optional);

	args->optional_arguments[i] = (struct optional_argument){
	    .value = value,
	    .name = name,
	};

	return args;
}

bool are_args_acceptable(struct args *args, int number)
{
	if (args->variadic)
	{
		return number >= args->num_required;
	}
	else
	{
		return number >= args->num_required &&
		       number <= args->num_required + args->num_optional;
	}
}

struct error list_to_args(struct environment *env, value_t list,
                          struct local *local, struct args **a)
{
	E_INIT();

	struct args *args = new_args();

	bool in_optional = false;

	for (value_t i = list; !nilp(i); i = cdr(i))
	{
		value_t val = car(i);
		NEARVAL(i);

		if (symbolp(val))
		{
			if (!args->variadic && symstreq(val, "&"))
			{
				i = cdr(i);
				value_t name = car(i);

				if (!symbolp(name))
				{
					THROW(EEXPECTED, "You must provide a symbol after & in an argument list "
						  "to bind the\n"
						  "variadic arguments to.");
				}

				args->variadic = true;

				add_variable(local, V_ARGUMENT, (char *)(name ^ SYMBOL_TAG),
				             args->num_optional + args->num_required);

				continue;
			}

			if (!in_optional)
			{
				add_variable(local, V_ARGUMENT, (char *)(val ^ SYMBOL_TAG),
				             args->num_required++);
			}
			else
			{
				char *name = (char *)(val ^ SYMBOL_TAG);
				if (name[0] == '&')
				{
					THROW(EINVALID, "Non-optional argument following optional arguments "
						  "starts with a &\n"
						  "did you mean to declare a variadic argument? If so "
						  "leave a space\n"
						  "between the & and name.");
				}
				else
				{
					THROW(EINVALID, "Cannot define a non-optional argument after an "
						  "optional one.");
				}
			}
		}
		else if (listp(val))
		{
			NEARVAL(val);

			in_optional = true;
			int len = length(val);

			if (len != 2)
			{
				THROW(EINVALID, "A list defining an optional value must be structured like "
					  "(name expr)\n"
					  "with exactly two arguments.");
			}

			value_t name = car(val);
			value_t expr = car(cdr(val));

			value_t function = cons(nil, cons(expr, nil));

			dasm_State *d;
			TRY(compile_function(function, NS_ANONYMOUS, env, NULL, NULL, NULL,
			                     NULL, local->current_file_path, &d));

			// TODO: GC stack top!
			value_t (*compiled)() = link_program(&d);

			value_t value = compiled();
			args = add_optional_arg(args, name, value);

			add_variable(local, V_ARGUMENT, (char *)(name ^ SYMBOL_TAG),
			             args->num_required + args->num_optional - 1);
		}
	}

	*a = args;
	OKAY();
}

void display_args(struct args *args)
{
	printf("Args object taking %d require arguments and %d optionals:\n",
	       args->num_required, args->num_optional);

	for (int i = 0; i < args->num_optional; i++)
	{
		printf("   %d\t%s\n", i,
		       (char *)(args->optional_arguments[i].name ^ SYMBOL_TAG));
		printval(args->optional_arguments[i].value, 2);
	}
}
