Fix bug in error handling where __sub would be clobbered.
diff --git a/src/lisp/compiler.dasc b/src/lisp/compiler.dasc
index e591ed3..5810f69 100644
--- a/src/lisp/compiler.dasc
+++ b/src/lisp/compiler.dasc
@@ -187,7 +187,7 @@
 
 	for (value_t body_ = body; !nilp(body_); body_ = cdr(body_))
 	{
-		walk_and_alloc(&local, car(body_));
+		TRY(walk_and_alloc(env, &local, carref(body_)));
 	}
 
 	| setup (local.num_stack_entries);
@@ -269,11 +269,15 @@
 	OKAY();
 }
 
-void walk_and_alloc(struct local *local, value_t body)
+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))
-		return;
+		OKAY();
 
 	value_t args = cdr(body);
 
@@ -284,7 +288,7 @@
 		value_t expr = cdr(args);
 		for (; !nilp(expr); expr = cdr(expr))
 		{
-			walk_and_alloc(local, car(expr));
+			walk_and_alloc(env, local, carref(expr));
 		}
 
 		local_free(local, slot);
@@ -293,15 +297,40 @@
 	{
 		// We don't want to walk the lambda because it's another function. When
 		// the lambda is compiled it will be walked.
-		return;
+		OKAY();
 	}
 	else
 	{
-		for (; !nilp(args); args = cdr(args))
+		// 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)
 		{
-			walk_and_alloc(local, car(args));
+			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)
@@ -320,16 +349,31 @@
 
 	value_t val;
 
-	while (IS_OKAY(read1(is, &val)))
+	struct error read_error;
+
+	while (IS_OKAY((read_error = read1(is, &val))))
 	{
 		if (!IS_OKAY(compile_tl(val, env, path)))
-			break;
+		{
+			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)
@@ -411,6 +455,10 @@
 
 			TRY(compile_expression(env, local, car(args), false, Dst));
 		}
+		else if (symstreq(fsym, "unquote-splice"))
+		{
+
+		}
 		else
 		{
 			| push nil;