diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2020-07-07 06:46:22 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2020-07-07 06:46:22 -0700 |
commit | 623ce6c9829d9352d05f6dae3204c1705be95702 (patch) | |
tree | 383bc7d6127762ced11d2e80b0dfea7c3b91054d /tests | |
parent | 91b24fc71e53a0b356ef97708f467b9da37fbb6b (diff) | |
download | txr-623ce6c9829d9352d05f6dae3204c1705be95702.tar.gz txr-623ce6c9829d9352d05f6dae3204c1705be95702.tar.bz2 txr-623ce6c9829d9352d05f6dae3204c1705be95702.zip |
New: protocol for iteration with structs.
* lib.c (seq_iterable): Return t if argument is a structure
supporting the iter-begin method.
(seq_iter_get_oop, seq_iter_peek_oop, seq_iter_get_fast_oop,
seq_iter_peek_fast_oop): New static functions.
(seq_iter_init_with_info): Handle COBJ case. If the COBJ is a
structure which suports the iter-begin method, then retrieve
the iterator object by calling it, and then prepare the
iterator structure for either the fast or the canonical
protocol based on whether the iterator supports iter-more.
(seq_iter_mark): Mark the iter member if the iterator is a
struct object.
(iter_begin): Rearrange tests here to check object type first
before sequence kind. If the object is a structure supporting
the iter-begin method, then call it and return its value.
(iter_more, iter_step): Check for struct object with
corresponding special methods and return.
(iter_reset): Similar change like in iter_begin. We check for
the iter-reset special method and try to use it, otherwise
fall back on the regular iter_begin logic.
* lib.h (struct seq_iter): New member next of the ul union
for caching the result of a peek operation.
* struct.c (iter_begin_s, iter_more_s, iter_item_s,
iter_step_s, iter_reset_s): New symbol variables;
(special_sym): Pointers to new symbol variables added to
array.
(struct_init): New symbol variables initialized.
(get_special_required_slot): New function.
* struct.h (iter_begin_s, iter_more_s, iter_item_s,
iter_step_s, iter_reset_s): Declared.
(enum special_slot): New enum members iter_begin_m,
iter_more_m, iter_item_m, iter_step_m, iter_reset_m.
(get_special_required_slot): Declared.
* txr.1: Documented.
* tests/012/oop-seq.expected: New file.
* tests/012/oop-seq.tl: New file.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/012/oop-seq.expected | 0 | ||||
-rw-r--r-- | tests/012/oop-seq.tl | 56 |
2 files changed, 56 insertions, 0 deletions
diff --git a/tests/012/oop-seq.expected b/tests/012/oop-seq.expected new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/tests/012/oop-seq.expected diff --git a/tests/012/oop-seq.tl b/tests/012/oop-seq.tl new file mode 100644 index 00000000..919f34cc --- /dev/null +++ b/tests/012/oop-seq.tl @@ -0,0 +1,56 @@ +(load "../common") + +(defstruct counter-iter-fast () + cur-val + step + limit + (:method iter-item (me) + me.cur-val) + (:method iter-step (me) + (inc me.cur-val me.step) + (if (< me.cur-val me.limit) me))) + +(defstruct counter-fast () + init + step + limit + (:method iter-begin (me) + (if (< me.init me.limit) + (new counter-iter-fast + cur-val me.init + step me.step + limit me.limit)))) + +(defstruct counter-iter-canon () + cur-val + step + limit + (:method iter-item (me) + me.cur-val) + (:method iter-more (me) + (< me.cur-val me.limit)) + (:method iter-step (me) + (inc me.cur-val me.step) + me)) + +(defstruct counter-canon () + init + step + limit + (:method iter-begin (me) + (new counter-iter-canon + cur-val me.init + step me.step + limit me.limit))) + +(test (list-seq (new counter-canon init 0 step 2 limit 10)) + (0 2 4 6 8)) + +(test (list-seq (new counter-fast init 0 step 2 limit 10)) + (0 2 4 6 8)) + +(test (list-seq (new counter-canon init 0 step 1 limit 0)) + nil) + +(test (list-seq (new counter-fast init 0 step 1 limit 0)) + nil) |