summaryrefslogtreecommitdiffstats
path: root/arith.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-06-09 23:58:55 -0700
committerKaz Kylheku <kaz@kylheku.com>2021-06-09 23:58:55 -0700
commit00b6397408934f95c16f3fa33959fb17e34f63c9 (patch)
tree0d1a30809b17dae750bb0216511c0129e54f3e8b /arith.c
parent864d1c6fe182661a7bd7d4eda928f8a19318b651 (diff)
downloadtxr-00b6397408934f95c16f3fa33959fb17e34f63c9.tar.gz
txr-00b6397408934f95c16f3fa33959fb17e34f63c9.tar.bz2
txr-00b6397408934f95c16f3fa33959fb17e34f63c9.zip
arith: switch sum and prod to seq_iter.
* arith.c (nary_op_keyfun): Static function removed. (nary_op_seq, nary_op_seq_keyfun): New static functions. (sumv, prodv): Static functions removed. (sum, prod): Reimplement using nary_op_seq and nary_op_seq_keyfun. Conversion of sequence to list smuggled via args is gone. * tests/016/arith.tl: new sum and prod tests. * txr.1: Note about sum and prod taking an iterable sequence added.
Diffstat (limited to 'arith.c')
-rw-r--r--arith.c78
1 files changed, 45 insertions, 33 deletions
diff --git a/arith.c b/arith.c
index 44e466df..225d6586 100644
--- a/arith.c
+++ b/arith.c
@@ -4185,41 +4185,61 @@ val nary_op(val self, val (*bfun)(val, val),
return acc;
}
-static val nary_op_keyfun(val self, val (*bfun)(val, val),
- val (*ufun)(val self, val),
- struct args *args, val emptyval,
- val keyfun)
+val nary_simple_op(val (*bfun)(val, val),
+ struct args *args, val firstval)
{
- val acc, next;
+ val acc = firstval, next;
cnum index = 0;
- if (!args_more(args, index))
- return emptyval;
+ while (args_more(args, index)) {
+ next = args_get(args, &index);
+ acc = bfun(acc, next);
+ }
- acc = funcall1(keyfun, args_get(args, &index));
+ return acc;
+}
- if (!args_more(args, index))
+static val nary_op_seq(val self, val (*bfun)(val, val),
+ val (*ufun)(val self, val),
+ val seq, val emptyval)
+{
+ seq_iter_t item_iter;
+ val acc, next;
+ seq_iter_init(self, &item_iter, seq);
+
+ if (!seq_get(&item_iter, &acc))
+ return emptyval;
+
+ if (!seq_get(&item_iter, &next))
return ufun(self, acc);
do {
- next = funcall1(keyfun, args_get(args, &index));
acc = bfun(acc, next);
- } while (args_more(args, index));
+ } while (seq_get(&item_iter, &next));
return acc;
}
-
-val nary_simple_op(val (*bfun)(val, val),
- struct args *args, val firstval)
+static val nary_op_seq_keyfun(val self, val (*bfun)(val, val),
+ val (*ufun)(val self, val),
+ val seq, val emptyval, val keyfun)
{
- val acc = firstval, next;
- cnum index = 0;
+ seq_iter_t item_iter;
+ val acc, next;
+ seq_iter_init(self, &item_iter, seq);
- while (args_more(args, index)) {
- next = args_get(args, &index);
+ if (!seq_get(&item_iter, &acc))
+ return emptyval;
+
+ acc = funcall1(keyfun, acc);
+
+ if (!seq_get(&item_iter, &next))
+ return ufun(self, acc);
+
+ do {
+ next = funcall1(keyfun, next);
acc = bfun(acc, next);
- }
+ } while (seq_get(&item_iter, &next));
return acc;
}
@@ -4428,26 +4448,18 @@ val numneqv(struct args *args)
}
}
-static val sumv(struct args *nlist, val keyfun)
-{
- return nary_op_keyfun(plus_s, plus, unary_arith, nlist, zero, keyfun);
-}
-
val sum(val seq, val keyfun)
{
- args_decl_list(args, ARGS_MIN, tolist(seq));
- return if3(missingp(keyfun), plusv(args), sumv(args, keyfun));
-}
-
-static val prodv(struct args *nlist, val keyfun)
-{
- return nary_op_keyfun(mul_s, mul, unary_num, nlist, one, keyfun);
+ return if3(missingp(keyfun),
+ nary_op_seq(plus_s, plus, unary_arith, seq, zero),
+ nary_op_seq_keyfun(plus_s, plus, unary_arith, seq, zero, keyfun));
}
val prod(val seq, val keyfun)
{
- args_decl_list(args, ARGS_MIN, tolist(seq));
- return if3(missingp(keyfun), mulv(args), prodv(args, keyfun));
+ return if3(missingp(keyfun),
+ nary_op_seq(mul_s, mul, unary_num, seq, one),
+ nary_op_seq_keyfun(mul_s, mul, unary_num, seq, one, keyfun));
}
static val rexpt(val right, val left)