Compiler can compile simple nested expressions and function calls.

The generated code can be called from C, and values can be passed between.
diff --git a/src/lisp/compiler.dasc b/src/lisp/compiler.dasc
index ed97019..2594abd 100644
--- a/src/lisp/compiler.dasc
+++ b/src/lisp/compiler.dasc
@@ -1,11 +1,13 @@
 /* -*- mode:c -*- */
 
 #include "compiler.h"
+#include "plat/plat.h"
+#include "lib/std.h"
 
 #include <dasm_proto.h>
 #include <dasm_x86.h>
 
-#define value_size sizeof (struct value)
+#define value_size sizeof (value_t)
 
 |.arch x86;
 
@@ -39,7 +41,7 @@
 	return f;
 }
 
-void compile (struct istream *is)
+void compile (value_t val)
 {
 	|.section code;
 	dasm_init (&d, DASM_MAXSECTION);
@@ -52,6 +54,17 @@
 	dasm_setup (&d, lisp_actions);
 
 	dasm_growpc (&d, npc);
+
+	struct environment env;
+	env.first = NULL;
+	char *name = "main";
+	load_std (&env);
+
+	printval (val, 0);
+	compile_expr_to_func (&env, name, val, &d);
+
+	value_t (*fun)() = find_function (&env, name)->def0;
+	printval (fun (), 0);
 }
 
 void compile_expression (struct environment *env, struct local *local,
@@ -63,25 +76,42 @@
 	}
 	else if ( listp (val) )
 	{
-		value_t func = car (val);
-		if ( !symbolp (func) )
-			err ("function name must be a symbol");
+		value_t fsym = car (val);
 
-		struct function *func = find_function (env, func ^ SYMBOL_TAG);
+		if ( !symbolp (fsym) )
+		{
+			err ("function name must be a symbol");
+		}
+
+		struct function *func = find_function (env, (char *) (fsym ^ SYMBOL_TAG));
 		value_t args = cdr (val);
 		int nargs = length (args);
 
 		if ( nargs != func->nargs )
 			err ("wrong number of args");
 
-		for ( int i = length (args) - 1; i >= 0; i++ )
+		for ( int i = length (args) - 1; i >= 0; i-- )
 		{
 			compile_expression (env, local, elt (args, i), Dst);
 			| push eax;
 		}
 
-		| call (func->code_addr);
+		| mov ebx, (func->code_addr);
+		| call ebx;
 		| add esp, (nargs * 4);
 		// result in eax
 	}
 }
+
+void compile_expr_to_func (struct environment *env, char *name, value_t val,
+                           dasm_State **Dst)
+{
+	| setup 0;
+
+	struct local local;
+	compile_expression (env, &local, val, Dst);
+	
+	| cleanup;
+
+	add_function (env, name, link (Dst), 0);
+}
diff --git a/src/lisp/compiler.h b/src/lisp/compiler.h
index f7be765..37eaeba 100644
--- a/src/lisp/compiler.h
+++ b/src/lisp/compiler.h
@@ -1,9 +1,9 @@
 #pragma once
 
 #include "lisp.h"
+#include <dasm_proto.h>
 #include <stdbool.h>
 #include <stdint.h>
-#include <dasm_proto.h>
 
 struct function
 {
@@ -16,7 +16,7 @@
 		value_t (*def2) (value_t, value_t);
 		value_t (*def3) (value_t, value_t, value_t);
 		void *code_ptr;
-		uintrptr_t code_addr;
+		uintptr_t code_addr;
 	};
 
 	struct function *prev;
@@ -45,5 +45,7 @@
 
 void compile_expression (struct environment *env, struct local *local,
                          value_t val, dasm_State **Dst);
-void compile (struct istream *is);
+void compile_expr_to_func (struct environment *env, char *name, value_t val,
+                           dasm_State **Dst);
+void compile (value_t val);
 struct function *find_function (struct environment *env, char *name);
diff --git a/src/lisp/lib/std.c b/src/lisp/lib/std.c
index 35226da..7bed8de 100644
--- a/src/lisp/lib/std.c
+++ b/src/lisp/lib/std.c
@@ -1,4 +1,5 @@
 #include "std.h"
+#include <stdlib.h>
 
 value_t l_plus (value_t a, value_t b)
 {
@@ -19,7 +20,7 @@
 	new->nargs = nargs;
 	new->code_ptr = func;
 
-	env->prev = new;
+	env->first = new;
 }
 
 void load_std (struct environment *env)
diff --git a/src/lisp/lisp b/src/lisp/lisp
index 6f1ba3c..2421bd3 100755
--- a/src/lisp/lisp
+++ b/src/lisp/lisp
Binary files differ
diff --git a/src/lisp/lisp.c b/src/lisp/lisp.c
index ac10eab..6a008f1 100644
--- a/src/lisp/lisp.c
+++ b/src/lisp/lisp.c
@@ -490,18 +490,15 @@
 {
 	int i = 0;
 
-	FOREACH (item, v)
-	{
-		(void)item;
+	for ( ; !nilp (v); v = cdr (v) )
 		i++;
-	}
 
 	return i;
 }
 
 value_t elt (value_t v, int index)
 {
-	for ( int = 0; i < index; i++ )
+	for ( int i = 0; i < index; i++ )
 	{
 		v = cdr (v);
 	}
diff --git a/src/lisp/main.c b/src/lisp/main.c
index a83faab..1bda5f1 100644
--- a/src/lisp/main.c
+++ b/src/lisp/main.c
@@ -1,4 +1,5 @@
 #include "lisp.h"
+#include "compiler.h"
 
 int main (int argc, char **argv)
 {
@@ -13,8 +14,13 @@
 
 	while ( read1 (is, &val) )
 	{
-		printval (val, 0);
+//		printval (val, 0);
+		compile (val);
 	}
 
+	/* printf ("COMPILING\n"); */
+
+	return 0;
+
 	del_stristream (is);
 }
diff --git a/src/lisp/plat/linux.c b/src/lisp/plat/linux.c
index 23f7f82..bd9af10 100644
--- a/src/lisp/plat/linux.c
+++ b/src/lisp/plat/linux.c
@@ -1,6 +1,7 @@
 #include "plat.h"
 #include <stdlib.h>
 #include <string.h>
+#include <sys/mman.h>
 
 void *malloc_aligned (size_t size)
 {
@@ -27,3 +28,16 @@
 	void **ptr = (void **)addr;
 	free (ptr[ -1 ]);
 }
+
+void *link (dasm_State **Dst)
+{
+	size_t size;
+	void *buf;
+
+	dasm_link (Dst, &size);
+	buf = mmap (0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+	dasm_encode (Dst, buf);
+
+	mprotect (buf, size, PROT_READ | PROT_EXEC);
+	return buf;
+}
diff --git a/src/lisp/plat/plat.h b/src/lisp/plat/plat.h
index 227e0d2..87544ba 100644
--- a/src/lisp/plat/plat.h
+++ b/src/lisp/plat/plat.h
@@ -2,6 +2,7 @@
 
 #include <stdint.h>
 #include <stddef.h>
+#include <dasm_proto.h>
 
 /* Platform specific definitions */
 
@@ -9,3 +10,5 @@
 void *malloc_aligned (size_t size);
 void *realloc_aligned (void *addr, size_t size);
 void free_aligned (void *addr);
+
+void *link (dasm_State **Dst);