summaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2020-06-02 19:02:09 -0700
committerKaz Kylheku <kaz@kylheku.com>2020-06-02 19:02:09 -0700
commit91c85dc6a85bef1c62743bd278ebeb8914bf8b4b (patch)
tree94ca0f512f5303dfd4c93b4c8be3c1a051d4d3f1 /eval.c
parentdcd0c4e0485ad5f8cf571bffa99add57c8aed183 (diff)
downloadtxr-91c85dc6a85bef1c62743bd278ebeb8914bf8b4b.tar.gz
txr-91c85dc6a85bef1c62743bd278ebeb8914bf8b4b.tar.bz2
txr-91c85dc6a85bef1c62743bd278ebeb8914bf8b4b.zip
Convert each-family operators to use iter-begin.
With this change we can do (each ((x vec)) ...) with reasonable efficiency, because we are no longer marching through the vector with cdr, copying the suffix. * eval.c (get_iter_f): New global variable. (op_each): Obtain iterators for all the objects with iter_begin, instead of treating them as lists. Probe the iterators for termination with iter_more, get the items with iter_item instead of car and step with iter_step instead of cdr. (eval_init): gc-protect the get_iter_f function and initialize it. * share/txr/stdlib/compiler.tl (expand-each): Replace the car/cdr and null testing with iter-init, iter-more, iter-item and iter-step.
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c21
1 files changed, 11 insertions, 10 deletions
diff --git a/eval.c b/eval.c
index 7f3e2b23..30bd153b 100644
--- a/eval.c
+++ b/eval.c
@@ -109,7 +109,7 @@ val whole_k, form_k, symacro_k;
val last_form_evaled;
-val call_f;
+val call_f, get_iter_f;
val origin_hash;
@@ -1840,23 +1840,23 @@ static val op_each(val form, val env)
val bindings = if3(vars,
get_bindings(vars, env),
env->e.vbindings);
- val lists = mapcar(cdr_f, bindings);
+ val iters = mapcar(get_iter_f, bindings);
list_collect_decl (collection, ptail);
uw_block_begin (nil, result);
for (;;) {
- val biter, liter;
+ val biter, iiter;
- for (biter = bindings, liter = lists; biter;
- biter = cdr(biter), liter = cdr(liter))
+ for (biter = bindings, iiter = iters; biter;
+ biter = cdr(biter), iiter = cdr(iiter))
{
val binding = car(biter);
- val list = car(liter);
- if (!list)
+ val iter = car(iiter);
+ if (!iter_more(iter))
goto out;
- rplacd(binding, car(list));
- rplaca(liter, cdr(list));
+ rplacd(binding, iter_item(iter));
+ rplaca(iiter, iter_step(iter));
}
{
@@ -6262,7 +6262,7 @@ void eval_init(void)
protect(&top_vb, &top_fb, &top_mb, &top_smb, &special, &builtin, &dyn_env,
&op_table, &pm_table, &last_form_evaled,
- &call_f, &unbound_s, &origin_hash, convert(val *, 0));
+ &call_f, &get_iter_f, &unbound_s, &origin_hash, convert(val *, 0));
top_fb = make_hash(t, nil, nil);
top_vb = make_hash(t, nil, nil);
top_mb = make_hash(t, nil, nil);
@@ -6273,6 +6273,7 @@ void eval_init(void)
pm_table = make_hash(nil, nil, nil);
call_f = func_n1v(generic_funcall);
+ get_iter_f = chain(cdr_f, func_n1(iter_begin), nao);
origin_hash = make_eq_hash(t, nil);