Add AND and OR
diff --git a/doc/lisp_reference/lisp_reference.tex b/doc/lisp_reference/lisp_reference.tex
index a758d51..580e00f 100644
--- a/doc/lisp_reference/lisp_reference.tex
+++ b/doc/lisp_reference/lisp_reference.tex
@@ -46,6 +46,7 @@
     \fbox{#1}}}}
 \newcommand{\opt}[2]{\text{$[$}\param{#1}\default{#2}\text{$]$}}
 \newcommand{\mut}[1]{\text{$\widetilde{#1}$}}
+\newcommand{\mighteval}[1]{\text{$\widehat{#1}$}}
 \newcommand{\super}[1]{\text{$ ^{#1} $}}
 
 \newcommand{\optlist}[1]{\text{\(
@@ -78,16 +79,17 @@
 
 The following text styles and symbols are used within this document to indicate particular values or meanings:
 
-\begin{tabular}[t]{p{0.2\linewidth} p{0.7\linewidth}}
+\begin{tabular}[t]{p{0.2\linewidth} p{0.64\linewidth}}
     \func{cons} & A function ``cons.'' \\
     \const{\plus{}foo\plus} & A constant ``\plus{}foo\plus.'' \\
     \var{\earmuff{}bar\earmuff} & A global variable ``\earmuff{}bar\earmuff''. \\
     \reader{baz} & A reader macro ``baz.'' \\
     \mac{quux} & A macro ``quux.'' \\
-    \param{parameter} & A function argument ``parameter`` \\
+    \param{parameter} & A function argument ``parameter'' \\
     \opt{var}{123} & An optional function argument ``var'' with the default value ``123.'' \\
     \param{args}\more & ``args'' represents the rest of the items in the list. \\
     \mut{\param{mut}} & A function argument ``mut'' that might be mutated. \\
+    \mighteval{\param{maybe}} & ``maybe'' may or may not be evaluated. \\
     \ret{value} & Indicates that a form will evaluate to ``value''. \\
     \type{integer} & The type ``integer''. \\
     \optlist{\text{a}\\\text{b}} & One of ``a'' or ``b.''
@@ -144,6 +146,13 @@
     Evaluate \param{forms} from first to last, finally returning \ret{the last form}.
 }
 
+\definition{
+    (\mac{and} \param{first} \param{\mighteval{rest}}\more)\index{and} \\
+    (\mac{or} \param{first} \param{\mighteval{rest}}\more)\index{or}
+}{
+    Short circuiting $\land$ and $\lor$, respectively. Return the first value that is \nil{} or truthy, respectively, or the last value if all are truthy/\nil{}.
+}
+
 \section{Numbers}
 
 \subsection{Integers}
@@ -166,7 +175,7 @@
 \section{Function Manipulation}
 
 \definition{
-    (\func{funcall} \param{function} \param{args}\more)\index{funcall} \\
+    (\func{funcall} \param{args}\more)\index{funcall} \\
     (\func{apply} \param{function} \param{args})\index{apply}
 }{
     Call the \type{closure} or \type{function-object} \param{function} with \param{args} and evaluate to \ret{its result}. An error occurs if \param{args} are not acceptable.
@@ -176,7 +185,7 @@
     (\mac{function} \param{function-name})\index{function} \\
     \reader{\#\textquotesingle}\param{function-name}\index{\#\textquotesingle}
 }{
-    Create a \ret{\type{function-object} from an existing function}. \param{function} must be a symbol literal at compile time.
+    Create a \ret{\type{function-object} from an existing function or macro}. \param{function} must be a symbol literal at compile time.
 }
 
 \definition{
diff --git a/src/lisp/compiler.dasc b/src/lisp/compiler.dasc
index f176b7d..213b644 100644
--- a/src/lisp/compiler.dasc
+++ b/src/lisp/compiler.dasc
@@ -220,7 +220,7 @@
 		enum namespace namespace = NS_FUNCTION;
 
 		if (symstreq(form, "defmacro"))
-		namespace = NS_MACRO;
+			namespace = NS_MACRO;
 
 		struct local local;
 		struct args *a;
@@ -396,7 +396,7 @@
 				// Remove unnecessary pop
 				| push eax;
 			}
-				| pop eax;
+			| pop eax;
 		}
 	}
 }
@@ -485,6 +485,37 @@
 				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)
+			{
+				err_at(val, "and & or require at least 1 argument.");
+			}
+
+			int after = nextpc(local, Dst);
+
+			for (; !nilp(args); args = cdr(args))
+			{
+				compile_expression(env, local, car(args), false, Dst);
+				if (!nilp(cdr(args)))
+				{
+					| cmp eax, nil;
+					if (or)
+					{
+						| jne =>early;
+					}
+					else
+					{
+						| je =>early;
+					}
+				}
+			}
+
+			|=>after:;
+		}
 		else if (symstreq(fsym, "progn"))
 		{
 			for (value_t val = args; !nilp(val); val = cdr(val))
@@ -563,11 +594,26 @@
 				    "compile time");
 			}
 
-			struct function *f =
-			    find_function(env, (char *)(car(args) ^ SYMBOL_TAG));
-			value_t closure = create_closure(f->code_ptr, f->args, 0);
+			char *name = (char *)(car(args) ^ SYMBOL_TAG);
 
-			| mov eax, (closure);
+			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)
+				{
+					err_at(val, "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"))
 		{
@@ -808,6 +854,15 @@
 			compile_variable(v, Dst);
 		}
 	}
+	else if (closurep(val))
+	{
+		| mov eax, val;
+	}
+	else
+	{
+		printval(val, 1);
+		err_at(val, "Don't know how to compile this, sorry.");
+	}
 }
 
 struct variable *add_variable(struct local *local, enum var_type type,