diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2020-04-21 06:32:59 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2020-04-21 06:32:59 -0700 |
commit | 5e79646092720733a8cacf9121bf6fbbbd87425a (patch) | |
tree | c8fb4b9b979bbe863822b1491290a29652c81d7b /arith.c | |
parent | 005baf51e44ea40387717665aac2e6b9ec5fd617 (diff) | |
download | txr-5e79646092720733a8cacf9121bf6fbbbd87425a.tar.gz txr-5e79646092720733a8cacf9121bf6fbbbd87425a.tar.bz2 txr-5e79646092720733a8cacf9121bf6fbbbd87425a.zip |
Extending =, <, >, <= and >= to work on sequences.
* arith.c (seq_nueq, seq_lt, seq_le): New
static functions.
(gt, lt): Handle sequences via seq_lt.
(ge, le): Handle sequences via seq_le.
(numeq): Handle sequences via seq_eq.
* txr.1: Documented, and also added missing documentation
about comparison of ranges by these functions, fixed
mistake in the syntax (> listed twice) and added
some notes about symmetry of > >= and < <=.
Diffstat (limited to 'arith.c')
-rw-r--r-- | arith.c | 104 |
1 files changed, 95 insertions, 9 deletions
@@ -1898,6 +1898,62 @@ val pppred(val num) return minus(num, three); } +static val seq_lt(val self, val aseq, val bseq) +{ + seq_iter_t ita, itb; + seq_iter_init(self, &ita, aseq); + seq_iter_init(self, &itb, bseq); + + for (;;) { + val aelem, belem; + switch (seq_peek(&ita, &aelem) << 1 | seq_peek(&itb, &belem)) { + case 0: + return nil; + case 1: + return t; + case 2: + return nil; + case 3: + if (lt(aelem, belem)) + return t; + if (!numeq(aelem, belem)) + return nil; + seq_geti(&ita); + seq_geti(&itb); + break; + default: + internal_error("bad return value from iterator peek"); + } + } +} + +static val seq_le(val self, val aseq, val bseq) +{ + seq_iter_t ita, itb; + seq_iter_init(self, &ita, aseq); + seq_iter_init(self, &itb, bseq); + + for (;;) { + val aelem, belem; + switch (seq_peek(&ita, &aelem) << 1 | seq_peek(&itb, &belem)) { + case 0: + return t; + case 1: + return t; + case 2: + return nil; + case 3: + if (!le(aelem, belem)) + return nil; + seq_geti(&ita); + seq_geti(&itb); + break; + default: + internal_error("bad return value from iterator peek"); + } + } +} + val gt(val anum, val bnum) { val self = gt_s; @@ -1956,9 +2012,9 @@ tail: case TYPE_PAIR(FLNUM, COBJ): case TYPE_PAIR(RNG, COBJ): return do_binary_method(self, lt_s, bnum, anum); + default: + return seq_lt(self, bnum, anum); } - - invalid_ops(self, anum, bnum); } val lt(val anum, val bnum) @@ -2019,9 +2075,9 @@ tail: case TYPE_PAIR(FLNUM, COBJ): case TYPE_PAIR(RNG, COBJ): return do_binary_method(self, gt_s, bnum, anum); + default: + return seq_lt(self, anum, bnum); } - - invalid_ops(self, anum, bnum); } val ge(val anum, val bnum) @@ -2087,9 +2143,9 @@ tail: case TYPE_PAIR(FLNUM, COBJ): case TYPE_PAIR(RNG, COBJ): return do_binary_method(self, le_s, bnum, anum); + default: + return seq_le(self, bnum, anum); } - - invalid_ops(self, anum, bnum); } val le(val anum, val bnum) @@ -2155,9 +2211,39 @@ tail: case TYPE_PAIR(FLNUM, COBJ): case TYPE_PAIR(RNG, COBJ): return do_binary_method(self, ge_s, bnum, anum); + default: + return seq_le(self, anum, bnum); } +} - invalid_ops(self, anum, bnum); +static val seq_numeq(val self, val aseq, val bseq) +{ + seq_iter_t ita, itb; + seq_iter_init(self, &ita, aseq); + seq_iter_init(self, &itb, bseq); + + if (ita.inf.kind == SEQ_VECLIKE && itb.inf.kind == SEQ_VECLIKE) { + if (length(aseq) != length(bseq)) + return nil; + } + + for (;;) { + val aelem, belem; + switch (seq_peek(&ita, &aelem) + seq_peek(&itb, &belem)) { + case 0: + return t; + case 1: + return nil; + case 2: + if (!numeq(aelem, belem)) + return nil; + seq_geti(&ita); + seq_geti(&itb); + break; + default: + internal_error("bad return value from iterator peek"); + } + } } val numeq(val anum, val bnum) @@ -2208,9 +2294,9 @@ tail: case TYPE_PAIR(FLNUM, COBJ): case TYPE_PAIR(RNG, COBJ): return do_binary_method(self, self, bnum, anum); + default: + return seq_numeq(self, anum, bnum); } - - invalid_ops(self, anum, bnum); } val expt(val anum, val bnum) |