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 | |
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.
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | eval.c | 40 |
2 files changed, 47 insertions, 6 deletions
@@ -1,5 +1,18 @@ 2012-01-11 Kaz Kylheku <kaz@kylheku.com> + 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. + +2012-01-11 Kaz Kylheku <kaz@kylheku.com> + * eval.c (each_s, each_star_s, collect_each_s, collect_each_star_s): New symbol variables. (op_each): New static function. @@ -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) |