commit 9999dbbba7e3594c099d442834d4a2b38aa4fc9f
parent 99e99fe8625352b98aa4e1d20e59e67b8d8fd992
Author: Ed van Bruggen <edvb@uw.edu>
Date: Thu, 24 Oct 2019 12:23:47 -0700
Add set! primitive
Diffstat:
test.c | | | 34 | +++++++++++++++++++++------------- |
tisp.c | | | 23 | +++++++++++++++++++++++ |
2 files changed, 44 insertions(+), 13 deletions(-)
diff --git a/test.c b/test.c
@@ -163,22 +163,30 @@ char *tests[][2] = {
{ "(= '((1 2) 3 4) '((1 2) 3 4))", "t" },
{ "(= '((1 b) 3 4) '((1 2) 3 4))", "()" },
- { "define", NULL },
- { "(define foo 4)", "" },
- { "foo", "4" },
- { "(define bar foo)", "" },
- { "bar", "4" },
- { "(define add +)", "" },
- { "(add foo bar)", "8" },
- { "(define (one x) (add x 1))", "" },
- { "(one foo)", "5" },
+ { "define", NULL },
+ { "(define foo 4)", "" },
+ { "foo", "4" },
+ { "(define bar foo)", "" },
+ { "bar", "4" },
+ { "(set! foo 5)", "" },
+ { "foo", "5" },
+ { "(set! foo (+ foo bar))", "" },
+ { "foo", "9" },
+ { "(define add +)", "" },
+ { "(add foo bar)", "13" },
+ { "(define (one x) (add x 1))", "" },
+ { "(one foo)", "10" },
{ "(define (more x)"
" (define term 3)"
- " (+ x term))", "" },
- { "(more 8)", "11" },
+ " (+ x term))", "" },
+ { "(more 8)", "11" },
{ "(define (add2 x)"
- " (+ x 1) (+ x 2))", "" },
- { "(add2 2)", "4" },
+ " (+ x 1) (+ x 2))", "" },
+ { "(add2 2)", "4" },
+ { "(set! add2 2)", "" },
+ { "add2", "2" },
+ { "(set! add2 \"2\")", "" },
+ { "add2", "\"2\"" },
{ "lambda", NULL },
{ "((lambda (x) x) 3)", "3" },
diff --git a/tisp.c b/tisp.c
@@ -948,6 +948,28 @@ prim_define(Env env, Val args)
return env->none;
}
+static Val
+prim_set(Env env, Val args)
+{
+ Val val;
+ Hash h;
+ Entry e = NULL;
+ tsp_arg_num(args, "set!", 2);
+ tsp_arg_type(car(args), "set!", SYMBOL);
+ if (!(val = tisp_eval(env, cadr(args))))
+ return NULL;
+ /* find first occurrence of symbol */
+ for (h = env->h; h; h = h->next) {
+ e = entry_get(h, car(args)->v.s);
+ if (e->key)
+ break;
+ }
+ if (!e || !e->key)
+ tsp_warnf("set!: variable %s is not defined", car(args)->v.s);
+ e->val = val;
+ return env->none;
+}
+
/* loads tisp file or C dynamic library */
static Val
prim_load(Env env, Val args)
@@ -1071,6 +1093,7 @@ tisp_env_init(size_t cap)
tsp_env_fn(lambda);
tsp_env_fn(macro);
tsp_env_fn(define);
+ tsp_env_name_fn(set!, set);
tsp_env_fn(load);
tsp_env_fn(error);
tsp_env_fn(version);