diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2012-01-11 16:31:12 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2012-01-11 16:31:12 -0800 |
commit | b765dfd93a0499de9781ff50efdc989cf06bba03 (patch) | |
tree | 7096d6c672446845e41ee347448cfd2f5185af74 /eval.c | |
parent | 7639a095e61af6c9c0f502957b7ff2c3817acab1 (diff) | |
download | txr-b765dfd93a0499de9781ff50efdc989cf06bba03.tar.gz txr-b765dfd93a0499de9781ff50efdc989cf06bba03.tar.bz2 txr-b765dfd93a0499de9781ff50efdc989cf06bba03.zip |
TXR Lisp regression in C global variables.
* eval.c (struct c_var): New struct type.
(lookup_var, lookup_var_l): cptr type bindings now point to a struct
c_var, which has to be handled properly here.
(c_var_mark): New static function.
(c_var_ops): New static struct.
(reg_var): Register variables using struct c_var to provide
a pointer to the location and a cached cons that can be
returned as a binding.
Diffstat (limited to 'eval.c')
-rw-r--r-- | eval.c | 40 |
1 files changed, 34 insertions, 6 deletions
@@ -47,6 +47,11 @@ typedef val (*opfun_t)(val, val); +struct c_var { + val *loc; + val bind; +}; + val top_vb, top_fb; val op_table; @@ -109,8 +114,11 @@ val lookup_var(val env, val sym) { if (nullp(env)) { val bind = gethash(top_vb, sym); - if (cobjp(bind)) - return *(val *) cptr_get(bind); + if (cobjp(bind)) { + struct c_var *cv = (struct c_var *) cptr_get(bind); + cv->bind->c.cdr = *cv->loc; + return cv->bind; + } return bind; } else { type_check(env, ENV); @@ -128,8 +136,10 @@ val *lookup_var_l(val env, val sym) { if (nullp(env)) { val bind = gethash(top_vb, sym); - if (cobjp(bind)) - return (val *) cptr_get(bind); + if (cobjp(bind)) { + struct c_var *cv = (struct c_var *) cptr_get(bind); + return cv->loc; + } if (bind) return cdr_l(bind); return 0; @@ -1431,9 +1441,27 @@ static void reg_fun(val sym, val fun) sethash(top_fb, sym, cons(sym, fun)); } -static void reg_var(val sym, val *obj) +static void c_var_mark(val obj) +{ + struct c_var *cv = (struct c_var *) cptr_get(obj); + gc_mark(cv->bind); + /* we don't mark *loc since it should be a gc-protected C global! */ +} + +static struct cobj_ops c_var_ops = { + cobj_equal_op, + cobj_print_op, + cobj_destroy_free_op, + c_var_mark, + cobj_hash_op +}; + +static void reg_var(val sym, val *loc) { - sethash(top_vb, sym, cptr((mem_t *) obj)); + struct c_var *cv = (struct c_var *) chk_malloc(sizeof *cv); + cv->loc = loc; + cv->bind = cons(sym, *loc); + sethash(top_vb, sym, cobj((mem_t *) cv, cptr_s, &c_var_ops)); } void eval_init(void) |