diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2024-02-28 19:09:58 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2024-02-28 19:09:58 -0800 |
commit | 001147e1d3a37718c4b75c2d56ea475455707464 (patch) | |
tree | 6759908b1bd12d7a2f946deb49ed91118c05bfb0 | |
parent | d12b6d6896a9838abd925feae34f6c01d535f223 (diff) | |
download | txr-001147e1d3a37718c4b75c2d56ea475455707464.tar.gz txr-001147e1d3a37718c4b75c2d56ea475455707464.tar.bz2 txr-001147e1d3a37718c4b75c2d56ea475455707464.zip |
seq_build: seq_pend must be nondestructive for lists.
Let's have both a seq_pend and seq_nconc, where seq_nconc
can reuse the pieces of list passed to it.
* lib.h (struct seq_build_ops): New member, nconc.
(seq_build_ops_init): Add nconc parameter and initializer.
(seq_nconc): Function declared.
* lib.c (seq_build_list_pend): Switch to list_collect_append,
otherwise mappend behaves destructively.
(seq_build_list_nconc): New function.
(sb_vec_ops, sb_str_ops, sb_buf_ops, sb_struct_ops,
sb_carray_ops): Use seq_build_generic_pend for nconc
operation.
(sb_list_ops): Use new seq_build_list_nconc for nconc
operation.
(sb_finished_ops): Use null pointer for nconc operation.
(seq_nconc): New function.
-rw-r--r-- | lib.c | 18 | ||||
-rw-r--r-- | lib.h | 6 |
2 files changed, 21 insertions, 3 deletions
@@ -1480,6 +1480,11 @@ static void seq_build_list_add(seq_build_t *bu, val item) static void seq_build_list_pend(seq_build_t *bu, val items) { + bu->tail = list_collect_append(bu->tail, items); +} + +static void seq_build_list_nconc(seq_build_t *bu, val items) +{ bu->tail = list_collect_nconc(bu->tail, items); } @@ -1505,41 +1510,47 @@ static void seq_build_carray_finish(seq_build_t *bu) static struct seq_build_ops sb_vec_ops = seq_build_ops_init(seq_build_vec_add, seq_build_generic_pend, + seq_build_generic_pend, 0, seq_build_obj_mark); static struct seq_build_ops sb_str_ops = seq_build_ops_init(seq_build_str_add, seq_build_generic_pend, + seq_build_generic_pend, seq_build_str_finish, seq_build_obj_mark); static struct seq_build_ops sb_buf_ops = seq_build_ops_init(seq_build_buf_add, seq_build_generic_pend, + seq_build_generic_pend, seq_build_buf_finish, seq_build_obj_mark); static struct seq_build_ops sb_struct_ops = seq_build_ops_init(seq_build_list_add, seq_build_generic_pend, + seq_build_generic_pend, seq_build_struct_finish, seq_build_struct_mark); static struct seq_build_ops sb_carray_ops = seq_build_ops_init(seq_build_list_add, seq_build_generic_pend, + seq_build_generic_pend, seq_build_carray_finish, seq_build_carray_mark); static struct seq_build_ops sb_list_ops = seq_build_ops_init(seq_build_list_add, seq_build_list_pend, + seq_build_list_nconc, seq_build_list_finish, seq_build_obj_mark); static struct seq_build_ops - sb_finished_ops = seq_build_ops_init(0, 0, 0, seq_build_obj_mark); + sb_finished_ops = seq_build_ops_init(0, 0, 0, 0, seq_build_obj_mark); static void seq_build_convert_to_list(seq_build_t *bu, val list) { @@ -1624,6 +1635,11 @@ void seq_pend(seq_build_t *bu, val items) bu->ops->pend(bu, items); } +void seq_nconc(seq_build_t *bu, val items) +{ + bu->ops->nconc(bu, items); +} + val seq_finish(seq_build_t *bu) { if (bu->ops->finish) @@ -483,12 +483,13 @@ typedef struct seq_build { struct seq_build_ops { void (*add)(struct seq_build *, val); void (*pend)(struct seq_build *, val); + void (*nconc)(struct seq_build *, val); void (*finish)(struct seq_build *); void (*mark)(struct seq_build *); }; -#define seq_build_ops_init(add, pend, finish, mark) \ - { add, pend, finish, mark } +#define seq_build_ops_init(add, pend, nconc, finish, mark) \ + { add, pend, nconc, finish, mark } extern const seq_kind_t seq_kind_tab[MAXTYPE+1]; @@ -768,6 +769,7 @@ val iter_reset(val iter, val obj); void seq_build_init(val self, seq_build_t *bu, val likeobj); void seq_add(seq_build_t *bu, val item); void seq_pend(seq_build_t *bu, val items); +void seq_nconc(seq_build_t *bu, val items); val seq_finish(seq_build_t *bu); NORETURN val throw_mismatch(val self, val obj, type_t); INLINE val type_check(val self, val obj, type_t typecode) |