diff options
-rw-r--r-- | arith.c | 78 | ||||
-rw-r--r-- | tests/016/arith.tl | 24 | ||||
-rw-r--r-- | txr.1 | 4 |
3 files changed, 72 insertions, 34 deletions
@@ -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) diff --git a/tests/016/arith.tl b/tests/016/arith.tl index 43efb6bb..52e8667b 100644 --- a/tests/016/arith.tl +++ b/tests/016/arith.tl @@ -142,3 +142,27 @@ (test (ffi-get (ffi-put #x-8000000000000000 (ffi int64)) (ffi int64)) #x-8000000000000000) + +(mtest + (sum #()) 0 + (sum #(1)) 1 + (sum #(1 2)) 3 + (sum #(1 2 3)) 6 + (sum #() (op * 10)) 0 + (sum #(1) (op * 10)) 10 + (sum #(1 2) (op * 10)) 30 + (sum #(1 2 3) (op * 10)) 60 + (sum 1..10) 45 + (sum 2..10) 44) + +(mtest + (prod #()) 1 + (prod #(1)) 1 + (prod #(1 2)) 2 + (prod #(1 2 3)) 6 + (prod #() (op * 10)) 1 + (prod #(1) (op * 10)) 10 + (prod #(1 2) (op * 10)) 200 + (prod #(1 2 3) (op * 10)) 6000 + (prod 2..8) 5040 + (prod 3..8) 2520) @@ -43961,7 +43961,9 @@ The and .code prod functions operate on an effective sequence of numbers derived from -.metn sequence . +.metn sequence , +which is an object suitable for iteration according to +.codn seq-begin . If the .meta keyfun |