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");