<http://www.gnu.org/licenses/>.
*/
+#include "alloc.h"
#include "eval.h"
+#include "oblist.h"
-#include "alloc.h"
+#include <string.h>
// globals for now
extern object ret;
extern frame *cf;
extern object *cst;
+extern vector_object globals;
void
push_frame (void (*fn) (), tuple_object args, void (*cont) ())
// * FSUBR: call impl
// * complex FUNCTION: call impl
+static object *gval (atom_object * var);
+
// Upon initial entry, `cf->args.body[0]` is the FORM, and
// `ret` is the result of evaluating the FORM's first position.
// Typically, the first position will be an ATOM, which is
{
switch (ret.type)
{
- /*
- case EVALTYPE_ATOM:
- break;
- case EVALTYPE_FIX32:
- case EVALTYPE_FIX64:
- break;
- */
+ case EVALTYPE_ATOM:
+ {
+ object *val = gval (&ret.atom);
+ if (!val)
+ {
+ // TODO: lvalue lookup
+ assert (0 && "attempted to call unbound symbol");
+ }
+ if (val->type == EVALTYPE_SUBR)
+ TAILCALL (val->subr);
+ assert (0 && "I don't know how to call that");
+ break;
+ /*
+ case EVALTYPE_FIX32:
+ case EVALTYPE_FIX64:
+ break;
+ */
+ }
default:
assert (0 && "I don't know how to call that");
}
assert (0 && "I don't know how to eval that");
}
}
+
+inline static object *
+create_global_binding (uvector_object oblist, const char *pname)
+{
+ object *p = stack_push (&globals);
+ stack_push (&globals)->atom =
+ oblist_find_or_insert (root, pname, strlen (pname));
+ return p;
+}
+
+static void
+subr_root ()
+{
+ ret.uvector = root;
+ pop_frame ();
+}
+
+void
+init_standard_env ()
+{
+ create_global_binding (root, "ROOT")->subr = new_subr (subr_root);
+}
+
+object *
+gval (atom_object * var)
+{
+ object *gvals = HEAP_OBJECT (globals.val.body);
+ for (int i = 0; i < globals.val.len / 2; i++)
+ {
+ // TODO: need proper atom comparison once multiple OBLISTs active
+ if (as_atom (&gvals[i * 2])->val.body == var->val.body)
+ {
+ return &gvals[i * 2 + 1];
+ }
+ }
+ return 0;
+}
<http://www.gnu.org/licenses/>.
*/
+#include "atom.h"
#include "read.h"
#include "eval.h"
#include "print.h"
pool_ptr ptop;
object *vhp_base;
heap_ptr vhp;
+vector_object globals;
// oblists (move to ASOCs once implemented)
uvector_object root;
READER_OBJCT = 64
};
+void init_standard_env ();
+
int
main ()
{
ptop = 1;
vhp = 1;
root = oblist_create (13);
+ globals = vector_create (64);
+ init_standard_env ();
// terminate input
assert (buf[n - 1] == '\n');
buf[n - 1] = '\0';
#include "object.h"
+#include <string.h>
+
uint32_t
list_length (const list_object * o)
{
}
*/
+dope_object *
+vec_dope (const vector_object * o)
+{
+ return (dope_object *) & HEAP_OBJECT (o->val.body)[o->val.len];
+}
+
dope_object *
uv_dope (const uvector_object * o)
{
return (dope_object *) & HEAP_OBJECT (o->val.body)[(o->val.len + 1) / 2 +
1];
}
+
+vector_object
+vector_create (uint32_t capacity)
+{
+ heap_ptr body = heap_alloc (capacity);
+ memset (HEAP_OBJECT (body), '\0', capacity * sizeof (object));
+ return new_vector (body + capacity, 0);
+}
+
+object *
+stack_push (vector_object * v)
+{
+ if (vec_dope (v)->len > v->val.len)
+ {
+ // TODO
+ assert (0 && "not implemented: GROW in stack_push");
+ }
+ v->val.len++;
+ return HEAP_OBJECT (--(v->val.body));
+}
vector_object vector;
uvector_object uvector;
atom_object atom;
+ subr_object subr;
} pool_object;
union object
uvector_object uvector;
atom_object atom;
tuple_object tuple;
+ subr_object subr;
};
/**
uint32_t list_length (const list_object * o);
+dope_object *vec_dope (const vector_object * o);
+
dope_object *uv_dope (const uvector_object * o);
static inline evaltype
o->type = type;
}
+// Allocate an vector of LOSEs and return a handle with length=0.
+vector_object vector_create (uint32_t capacity);
+
+// Stack-like interface to a VECTOR (with automatic GROW!)
+object *stack_push (vector_object * v);
+
/**
Checked downcasts.
*/