Document some new Lisp functions, add functions for env. inspection
diff --git a/doc/lisp_reference/all-functions-present.sh b/doc/lisp_reference/all-functions-present.sh
new file mode 100755
index 0000000..b2623ab
--- /dev/null
+++ b/doc/lisp_reference/all-functions-present.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+# Prints a list of the functions that are not yet documented.
+
+../../src/lisp/lisp all-functions.lisp | while read -r fun
+do
+	if grep "$fun" lisp_reference.tex > /dev/null; then
+		# nothing
+		true
+	else
+		echo "$fun"
+	fi
+done
diff --git a/doc/lisp_reference/all-functions.lisp b/doc/lisp_reference/all-functions.lisp
new file mode 100644
index 0000000..0659c3d
--- /dev/null
+++ b/doc/lisp_reference/all-functions.lisp
@@ -0,0 +1,5 @@
+;; Prints all defined Lisp functions
+(defun main ()
+  (mapcar (lambda (fun)
+			(print fun))
+		  (env-functions +current-env+)))
diff --git a/doc/lisp_reference/lisp_reference.tex b/doc/lisp_reference/lisp_reference.tex
index 11b2207..0f204b9 100644
--- a/doc/lisp_reference/lisp_reference.tex
+++ b/doc/lisp_reference/lisp_reference.tex
@@ -389,6 +389,40 @@
   not compiling a file. Return \ret{\nil}.
 }
 
+\section{Inspecting \& Modifying the Environment}
+
+\subsection{Managing Memory}
+
+\definition{
+  (\func{gc})\index{gc}
+}{
+  Run the garbage collector.
+}
+
+\definition{
+  (\func{gc-stats})\index{gc-stats}
+}{
+  Return some
+  statistics about the garbage collector, in the form of a list:
+  \ret{(\param{total-allocs} \param{gc-runs})}, where
+  \param{total-allocs} is the current number of active allocations,
+  and \param{gc-runs} is the total number of times the garbage
+  collector has been run.
+}
+
+\subsection{Introspection}
+
+\definition{ \const{\pluses{current-env}} }{ An opaque object
+  representing the current environment.  }
+
+\definition{
+  (\func{env-functions} \param{current-env})
+}{
+  Returns a
+  list of symbols, each of which is the name of a function defined in
+  the environment specified by \param{current-env}.
+}
+
 \printindex
 
 \printglossaries
diff --git a/src/lisp/compiler.dasc b/src/lisp/compiler.dasc
index bfe74e1..a0b0236 100644
--- a/src/lisp/compiler.dasc
+++ b/src/lisp/compiler.dasc
@@ -981,6 +981,13 @@
 
 			| mov eax, (file_name_val);
 		}
+		else if (symstreq(val, "+current-env+"))
+		{
+			// TODO: we return this as a raw "integer", which is a bad
+			// idea. Once classes are added this needs to be wrapped
+			// in a class.
+			| mov eax, (env);
+		}
 		else
 		{
 			struct variable *v =
diff --git a/src/lisp/lib/std.c b/src/lisp/lib/std.c
index 1afe993..a0b7c78 100644
--- a/src/lisp/lib/std.c
+++ b/src/lisp/lib/std.c
@@ -1,5 +1,6 @@
 #include "std.h"
 #include "../gc.h"
+#include "../compiler.h"
 #include "../plat/plat.h"
 #include <stdlib.h>
 #include <string.h>
@@ -200,6 +201,22 @@
 					 nil));
 }
 
+value_t l_list_functions(value_t env)
+{
+	if (!integerp(env))
+		return nil;
+
+	struct environment *e = (void *)env;
+	value_t list = nil;
+
+	for (struct function *fun = e->first; fun; fun = fun->prev)
+	{
+		list = cons(symval(fun->name), list);
+	}
+
+	return list;
+}
+
 #define LISP_PREDICATE(name) value_t l_##name(value_t v) { return name(v) ? t : nil; }
 
 LISP_PREDICATE(listp)
@@ -243,6 +260,8 @@
 
 	add_c_function(env, "gc-stats", l_gc_stats, 0);
 
+	add_c_function(env, "env-functions", l_list_functions, 1);
+
 	if (!load_library(env, "std"))
 	{
 		fprintf(stderr, "Not found std\n");