tisp

tiny lisp
git clone git://edryd.org/tisp
Log | Files | Refs | LICENSE

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);