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);
+}