summaryrefslogtreecommitdiffstats
path: root/compile.c
diff options
context:
space:
mode:
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/compile.c b/compile.c
index 1f8be905..95cd59e5 100644
--- a/compile.c
+++ b/compile.c
@@ -320,15 +320,24 @@ block gen_collect(block expr) {
gen_op_var_bound(LOADV, array_var));
}
-block gen_fold(const char* varname, block init, block fold) {
- block loop = BLOCK(fold, gen_op_var_unbound(STOREV, varname), gen_op_simple(BACKTRACK));
+block gen_reduce(const char* varname, block source, block init, block body) {
+ block res_var = block_bind(gen_op_var_unbound(STOREV, "reduce"),
+ gen_noop(), OP_HAS_VARIABLE);
+
+ block loop = BLOCK(gen_op_simple(DUP),
+ source,
+ block_bind(gen_op_var_unbound(STOREV, varname),
+ BLOCK(gen_op_var_bound(LOADVN, res_var),
+ body,
+ gen_op_var_bound(STOREV, res_var)),
+ OP_HAS_VARIABLE),
+ gen_op_simple(BACKTRACK));
return BLOCK(gen_op_simple(DUP),
init,
- block_bind(gen_op_var_unbound(STOREV, varname),
- BLOCK(gen_op_target(FORK, loop),
- loop,
- gen_op_var_unbound(LOADV, varname)),
- OP_HAS_VARIABLE));
+ res_var,
+ gen_op_target(FORK, loop),
+ loop,
+ gen_op_var_bound(LOADVN, res_var));
}
block gen_definedor(block a, block b) {