add parent environments
This commit is contained in:
parent
c16f08f22a
commit
1dfba9f4a1
25
src/mumble.c
25
src/mumble.c
|
@ -286,15 +286,17 @@ struct lispenv {
|
||||||
int count;
|
int count;
|
||||||
char** syms; // list of strings
|
char** syms; // list of strings
|
||||||
lispval** vals; // list of pointers to vals
|
lispval** vals; // list of pointers to vals
|
||||||
|
lispenv* parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
lispenv* new_lispenv()
|
lispenv* new_lispenv()
|
||||||
{
|
{
|
||||||
lispenv* n = malloc(sizeof(lispenv));
|
lispenv* e = malloc(sizeof(lispenv));
|
||||||
n->count = 0;
|
e->count = 0;
|
||||||
n->syms = NULL;
|
e->syms = NULL;
|
||||||
n->vals = NULL;
|
e->vals = NULL;
|
||||||
return n;
|
e->parent = NULL;
|
||||||
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy_lispenv(lispenv* env)
|
void destroy_lispenv(lispenv* env)
|
||||||
|
@ -311,8 +313,12 @@ void destroy_lispenv(lispenv* env)
|
||||||
env->vals = NULL;
|
env->vals = NULL;
|
||||||
free(env);
|
free(env);
|
||||||
env = NULL;
|
env = NULL;
|
||||||
|
// parent is it's own environment
|
||||||
|
// so it isn't destroyed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
lispval* clone_lispval(lispval* old);
|
lispval* clone_lispval(lispval* old);
|
||||||
lispval* get_from_lispenv(char* sym, lispenv* env)
|
lispval* get_from_lispenv(char* sym, lispenv* env)
|
||||||
{
|
{
|
||||||
|
@ -322,7 +328,13 @@ lispval* get_from_lispenv(char* sym, lispenv* env)
|
||||||
// return env->vals[i];
|
// return env->vals[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(env->parent != NULL){
|
||||||
|
return get_from_lispenv(sym, env->parent);
|
||||||
|
} else {
|
||||||
return lispval_err("Error: unbound symbol");
|
return lispval_err("Error: unbound symbol");
|
||||||
|
}
|
||||||
|
// and this explains shadowing!
|
||||||
}
|
}
|
||||||
|
|
||||||
void insert_in_lispenv(char* sym, lispval* v, lispenv* env)
|
void insert_in_lispenv(char* sym, lispval* v, lispenv* env)
|
||||||
|
@ -739,6 +751,9 @@ lispval* builtin_def(lispval* v, lispenv* env)
|
||||||
// A builtin for defining a function
|
// A builtin for defining a function
|
||||||
lispval* builtin_define_lambda(lispval* v, lispenv* env){
|
lispval* builtin_define_lambda(lispval* v, lispenv* env){
|
||||||
// @ { {x y} { + x y } }
|
// @ { {x y} { + x y } }
|
||||||
|
// def { {plus} {{@ {x y} {+ x y}} }}
|
||||||
|
// (eval plus) 1 2
|
||||||
|
// (@ { {x y} { + x y } }) 1 2
|
||||||
LISPVAL_ASSERT( v->count == 2, "Lambda definition requires two arguments; try @ { {x y} { + x y } }");
|
LISPVAL_ASSERT( v->count == 2, "Lambda definition requires two arguments; try @ { {x y} { + x y } }");
|
||||||
LISPVAL_ASSERT(v->cell[0]->type == LISPVAL_QEXPR, "Lambda definition (@) requires that the first sub-arg be a q-expression; try @ { {x y} { + x y } }");
|
LISPVAL_ASSERT(v->cell[0]->type == LISPVAL_QEXPR, "Lambda definition (@) requires that the first sub-arg be a q-expression; try @ { {x y} { + x y } }");
|
||||||
LISPVAL_ASSERT(v->cell[1]->type == LISPVAL_QEXPR, "Lambda definition (@) requires that the second sub-arg be a q-expression; try @ { {x y} { + x y } }");
|
LISPVAL_ASSERT(v->cell[1]->type == LISPVAL_QEXPR, "Lambda definition (@) requires that the second sub-arg be a q-expression; try @ { {x y} { + x y } }");
|
||||||
|
|
Loading…
Reference in New Issue
Block a user