diff --git a/src/eval.c b/src/eval.c index 3de78c4..dc6f7ee 100644 --- a/src/eval.c +++ b/src/eval.c @@ -9,7 +9,7 @@ #include #include -static struct Object *lookup(struct Object *namespace, struct Object *name); +static struct Object *lookup(struct Object *environment, struct Object *name); static struct Object *eval_list( struct Object *object, @@ -21,13 +21,12 @@ struct Object *eval( struct Object *const environment ) { assert(Object_is_pair(environment)); - assert(OBJECT_IS_NULL(environment->pair.cdr)); // NULL is an empty list, can't eval assert(!OBJECT_IS_NULL(object)); // SYMBOL performs lookup - if (Object_is_symbol(object)) return lookup(environment->pair.car, object); + if (Object_is_symbol(object)) return lookup(environment, object); // Almost everything evaluates to itself if (!Object_is_pair(object)) return object; @@ -77,18 +76,27 @@ struct Object *eval_list( } } -struct Object *lookup(struct Object *namespace, struct Object *const name) +struct Object *lookup(struct Object *environment, struct Object *const name) { - assert(OBJECT_IS_LIST_HEAD(namespace)); + assert(OBJECT_IS_LIST_HEAD(environment)); assert(Object_is_symbol(name)); - while (!OBJECT_IS_NULL(namespace)) { - assert(Object_is_pair(namespace)); - struct Object *const item = namespace->pair.car; - assert(Object_is_pair(item)); - assert(Object_is_symbol(item->pair.car)); - if (strcmp(item->pair.car->s, name->s) == 0) return item->pair.cdr; - namespace = namespace->pair.cdr; + while (!OBJECT_IS_NULL(environment)) { + assert(Object_is_pair(environment)); + struct Object *namespace = environment->pair.car; + + while (!OBJECT_IS_NULL(namespace)) { + assert(Object_is_pair(namespace)); + struct Object *const item = namespace->pair.car; + + assert(Object_is_pair(item)); + assert(Object_is_symbol(item->pair.car)); + if (strcmp(item->pair.car->s, name->s) == 0) return item->pair.cdr; + + namespace = namespace->pair.cdr; + } + + environment = environment->pair.cdr; } struct Object *const builtin_procedure = builtins_get(name->s);