Add macros
diff --git a/src/lisp/compiler.dasc b/src/lisp/compiler.dasc
index 32e2713..ec14078 100644
--- a/src/lisp/compiler.dasc
+++ b/src/lisp/compiler.dasc
@@ -95,8 +95,13 @@
 	value_t form = car(val);
 	value_t args = cdr(val);
 
-	if (symstreq(form, "defun"))
+	if (symstreq(form, "defun") || symstreq(form, "defmacro"))
 	{
+		enum namespace namespace = NS_FUNCTION;
+
+		if (symstreq(form, "defmacro"))
+			namespace = NS_MACRO;
+
 		dasm_State *d;
 		dasm_State **Dst = &d;
 
@@ -162,7 +167,7 @@
 		| cleanup;
 
 		add_function(env, (char *)(name ^ SYMBOL_TAG), link(Dst),
-		             length(arglist));
+		             length(arglist), namespace);
 
 		dasm_free(&d);
 		free(local.stack_slots);
@@ -375,16 +380,28 @@
 			if (nargs != func->nargs)
 				err("wrong number of args");
 
-			for (int i = length(args) - 1; i >= 0; i--)
+			if (func->namespace == NS_FUNCTION)
 			{
-				compile_expression(env, local, elt(args, i), Dst);
-				| push eax;
-			}
+				for (int i = length(args) - 1; i >= 0; i--)
+				{
+					compile_expression(env, local, elt(args, i), Dst);
+					| push eax;
+				}
 
-			| mov ebx, (func->code_addr);
-			| call ebx;
-			| add esp, (nargs * value_size);
-			// result in eax
+				| mov ebx, (func->code_addr);
+				| call ebx;
+				| add esp, (nargs * value_size);
+				// result in eax
+			}
+			else if (func->namespace == NS_MACRO)
+			{
+				value_t expanded_to = call_list(func, args);
+
+				printf("Macro expanded to:\n");
+				printval(expanded_to, 2);
+
+				compile_expression(env, local, expanded_to, Dst);
+			}
 		}
 	}
 	else if (symbolp(val))
@@ -422,7 +439,7 @@
 
 	| cleanup;
 
-	add_function(env, name, link(Dst), 0);
+	add_function(env, name, link(Dst), 0, NS_FUNCTION);
 }
 
 struct variable *add_variable(struct local *local, enum var_type type,
@@ -458,3 +475,10 @@
 
 	return v;
 }
+
+extern value_t _call_list(void *addr, value_t list);
+
+value_t call_list(struct function *func, value_t list)
+{
+	return _call_list(func->code_ptr, list);
+}