Commit b99b193d authored by Chris Müller's avatar Chris Müller
Browse files

Add and simplify environment representation

add simpler representation for environments in order to remove
red-black trees.
parent fe5c60db
......@@ -785,6 +785,85 @@ cherry_read(byte_t** src, byte_t* buffer, size_t buffer_size)
// runtime utils
// ----------------------------------------------------------------------------
struct value*
env_lookup(struct value* env, struct value* symbol)
{
struct value *frame, *vars, *vals;
while(!IS_NULL(env)) {
frame = FIRST_FRAME(env);
vars = FRAME_VARIABLES(frame);
vals = FRAME_VALUES(frame);
while(!IS_NULL(vars)) {
if(symbol == HEAD(vars))
return HEAD(vals);
vars = TAIL(vars);
vals = TAIL(vals);
}
env = PARENT_FRAMES(env);
}
failure("Unbound variable found for symbol %s", symbol->symbol_value);
}
struct value*
env_set(struct value* env, struct value* var, struct value* val)
{
struct value *frame, *vars, *vals;
while(!IS_NULL(env)) {
frame = FIRST_FRAME(env);
vars = FRAME_VARIABLES(frame);
vals = FRAME_VALUES(frame);
while(!IS_NULL(vars)) {
if(var == HEAD(vars))
HEAD(vals) = val;
return True;
vars = TAIL(vars);
vals = TAIL(vals);
}
env = PARENT_FRAMES(env);
}
failure("Unbound variable found for symbol %s", var->symbol_value);
}
struct value*
env_add_binding_to_frame(struct value* frame, struct value* var, struct value* val)
{
HEAD(frame) = cons(var, HEAD(frame));
TAIL(frame) = cons(val, TAIL(frame));
}
struct value*
env_define(struct value* env, struct value* var, struct value* val)
{
struct value* frame = FIRST_FRAME(env);
struct value* vars = FRAME_VARIABLES(frame);
struct value* vals = FRAME_VALUES(frame);
while(!IS_NULL(vars)) {
if(var == HEAD(vars)) {
HEAD(vals) = val;
return True;
}
vars = TAIL(vars);
vals = TAIL(vals);
}
env_add_binding_to_frame(var, val, frame);
return True;
}
......
......@@ -121,12 +121,22 @@ struct value* cons(struct value* head, struct value* tail);
#define list3(A, B, C) cons(A, cons(B, cons(C, emptylist)))
#define list4(A, B, C, D) cons(A, cons(B, cons(C, cons(D, emptylist))))
#define SYMBOL_ENTRY(sym, left, right) \
cons(sym, cons(left, right))
#define SYMBOL_ENTRY(sym, left, right) cons(sym, cons(left, right))
#define SYMBOL_LEFT(node) HEAD(TAIL(node))
#define SYMBOL_RIGHT(node) TAIL(TAIL(node))
#define EXTEND_ENV(env, vars, vals) cons(cons(vars,vals), env)
#define INTIAL_ENV EXTEND_ENV(Emptylist, Emptylist, Emptylist)
#define FIRST_FRAME(env) HEAD(env)
#define PARENT_FRAMES(env) TAIL(env)
#define FRAME_VARIABLES(frame) HEAD(frame)
#define FRAME_VALUES(frame) TAIL(frame)
struct value* env_lookup(struct value* env, struct value* var);
struct value* env_set(struct value* env, struct value* var, struct value* val);
struct value* env_define(struct value* env, struct value* var, struct value* val);
struct value* env_add_binding_to_frame(struct value* frame, struct value* var, struct value* val);
struct closure {
struct value* (*execute)(struct closure* self);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment