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

Switch environment to a list of mapping tuples (key, value)

parent 045292f6
......@@ -153,19 +153,23 @@ struct value* list_reverse(struct value* value);
#define SYMBOL_LEFT(node) HEAD(TAIL(node))
#define SYMBOL_RIGHT(node) TAIL(TAIL(node))
#define EXTEND_ENV(env) cons(cons(emptylist,emptylist), env)
#define INITIAL_ENV EXTEND_ENV(emptylist)
#define EXTEND_ENV(env) cons(emptylist, env)
#define INITIAL_ENV cons(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* environment(void);
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_let(struct value* env, struct value* var, struct value* val);
const byte_t* from_loadpath(struct value* module);
struct value* add_to_loaded_modules(struct value* symbol, struct value* env);
struct value* get_loaded_module(struct value* symbol);
extern struct value* global_symbollist;
extern struct value* loaded_modules;
extern struct ptrarray* loadpath;
extern struct value* emptylist;
extern struct value* True;
......
......@@ -90,19 +90,18 @@ initialize(struct value* arguments)
struct value*
env_lookup(struct value* env, struct value* symbol)
{
struct value *frame, *vars, *vals;
struct value *frame;
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);
while(!IS_NULL(frame)) {
struct value* pair = HEAD(frame);
vars = TAIL(vars);
vals = TAIL(vals);
if(NTH(pair, 0) == symbol)
return NTH(pair, 1);
frame = TAIL(frame);
}
env = PARENT_FRAMES(env);
......@@ -115,21 +114,20 @@ env_lookup(struct value* env, struct value* symbol)
struct value*
env_set(struct value* env, struct value* var, struct value* val)
{
struct value *frame, *vars, *vals;
struct value *frame;
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;
while(!IS_NULL(frame)) {
struct value* pair = HEAD(frame);
if(NTH(pair, 0) == var) {
NTH(pair, 1) = val;
return True;
}
vars = TAIL(vars);
vals = TAIL(vals);
frame = TAIL(frame);
}
env = PARENT_FRAMES(env);
......@@ -142,25 +140,64 @@ struct value*
env_let(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)) {
while(!IS_NULL(frame)) {
struct value* pair = HEAD(frame);
if(var == NTH(pair, 0)) {
failure(0, "Overwrite declaration from variable %s", var->symbol_value);
}
vars = TAIL(vars);
vals = TAIL(vals);
frame = TAIL(frame);
}
HEAD(frame) = cons(var, HEAD(frame));
TAIL(frame) = cons(val, TAIL(frame));
FIRST_FRAME(env) = cons(tuple2(var, val), FIRST_FRAME(env));
return True;
}
const byte_t*
from_loadpath(struct value* module)
{
size_t module_size = utf8_size(module->symbol_value);
byte_t* modulename = GC_MALLOC(sizeof(byte_t) * module_size);
byte_t* p;
memcpy(modulename, module->symbol_value, module_size);
for(p = modulename; p < modulename + module_size; ++p) {
if(*p == '.')
*p = '/';
}
size_t loadpath_size = ptrarray_size(loadpath);
size_t i;
for(i = 0; i < module_size; ++i) {
const byte_t* path = (const byte_t*) ptrarray_get(loadpath, i);
size_t path_size = utf8_size(path);
byte_t* full_path = GC_MALLOC(sizeof(byte_t) * (module_size + path_size + 2));
memcpy(full_path, path, path_size);
memcpy(full_path + path_size + 1, modulename, module_size);
full_path[path_size] = '/';
full_path[path_size + module_size + 1] = '\0';
FILE* port = fopen(full_path, "rb");
if(port) {
fclose(port);
return full_path;
}
}
return 0;
}
struct value*
core_raise(struct value* env, struct value* args)
......
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