diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2024-02-28 08:46:18 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2024-02-28 08:46:18 -0800 |
commit | d12b6d6896a9838abd925feae34f6c01d535f223 (patch) | |
tree | 6b14f862693f28a31e2b6ae0fa0d6f60939ad73f | |
parent | 0490e3a4bf568584e7701ee34fd8f27b1f518404 (diff) | |
download | txr-d12b6d6896a9838abd925feae34f6c01d535f223.tar.gz txr-d12b6d6896a9838abd925feae34f6c01d535f223.tar.bz2 txr-d12b6d6896a9838abd925feae34f6c01d535f223.zip |
seq_build: convert list buiding to list_collect.
We want to use the list_collect functions for consistency.
For instance, these functions allow an atom to be added
to an improper list if the terminating atom is a sequence.
(append '(1 . "abc") "d") yields (1 . "abcd").
* lib.h (struct seq_build): New member, tail.
* lib.c (seq_build_list_add): Use list_collect.
(seq_build_list_pend): Use list_collect_nconc.
(seq_build_list_finish): Nothing to do here, except
call seq_build_convert_to_finished since bu->obj
is the head of the list at all times now.
(seq_build_improper_add, seq_build_improper_pend):
Functions removed.
(sb_improper_ops): Structure removed.
(seq_build_convert_to_improper): Function removed.
(seq_build_convert_to_list): Different strategy needed
here now. The list just goes into bu->obj, and we have
to set up the tail to either point to the last cons
cell's cdr, or else to bu->obj if the list is empty.
(seq_build_init): Initialize bu->tail in the three cases
that set up list collection.
-rw-r--r-- | lib.c | 77 | ||||
-rw-r--r-- | lib.h | 1 |
2 files changed, 10 insertions, 68 deletions
@@ -1475,45 +1475,18 @@ static void seq_build_buf_finish(seq_build_t *bu) static void seq_build_list_add(seq_build_t *bu, val item) { - val obj = bu->obj; - - if (obj) { - val head = us_cdr(obj); - val nobj = cons(item, head); - us_rplacd(obj, nobj); - bu->obj = nobj; - } else { - val nobj = cons(item, nil); - us_rplacd(nobj, nobj); - bu->obj = nobj; - } + bu->tail = list_collect(bu->tail, item); } -static void seq_build_convert_to_improper(seq_build_t *bu, val atom); - -static void seq_build_list_pend(seq_build_t *bu, val item) +static void seq_build_list_pend(seq_build_t *bu, val items) { - while (consp(item)) { - seq_build_list_add(bu, us_car(item)); - item = us_cdr(item); - } - - if (item) - seq_build_convert_to_improper(bu, item); + bu->tail = list_collect_nconc(bu->tail, items); } static void seq_build_convert_to_finished(seq_build_t *bu); static void seq_build_list_finish(seq_build_t *bu) { - val obj = bu->obj; - - if (obj) { - val head = us_cdr(obj); - us_rplacd(obj, nil); - bu->obj = head; - } - seq_build_convert_to_finished(bu); } @@ -1529,20 +1502,6 @@ static void seq_build_carray_finish(seq_build_t *bu) bu->obj = carray_list(bu->obj, bu->u.carray_type, nil); } -static void seq_build_improper_add(seq_build_t *bu, val item) -{ - val atom = butlastn(zero, bu->obj); - (void) item; - uw_throwf(error_s, lit("~a: cannot add after atom ~s"), bu->self, atom, nao); -} - -static void seq_build_improper_pend(seq_build_t *bu, val item) -{ - val atom = butlastn(zero, bu->obj); - (void) item; - uw_throwf(error_s, lit("~a: cannot append after atom ~s"), bu->self, atom, nao); -} - static struct seq_build_ops sb_vec_ops = seq_build_ops_init(seq_build_vec_add, seq_build_generic_pend, @@ -1580,42 +1539,21 @@ static struct seq_build_ops seq_build_obj_mark); static struct seq_build_ops - sb_improper_ops = seq_build_ops_init(seq_build_improper_add, - seq_build_improper_pend, - 0, - seq_build_obj_mark); - -static struct seq_build_ops sb_finished_ops = seq_build_ops_init(0, 0, 0, seq_build_obj_mark); static void seq_build_convert_to_list(seq_build_t *bu, val list) { if (list) { - val tail = lastcons(list); - us_rplacd(tail, list); - bu->obj = tail; + bu->obj = list; + bu->tail = tail(list); } else { bu->obj = nil; + bu->tail = mkcloc(bu->obj); } bu->ops = &sb_list_ops; } -static void seq_build_convert_to_improper(seq_build_t *bu, val atom) -{ - val obj = bu->obj; - - if (obj) { - val head = us_cdr(obj); - us_rplacd(obj, atom); - bu->obj = head; - } else { - bu->obj = atom; - } - - bu->ops = &sb_improper_ops; -} - static void seq_build_convert_to_finished(seq_build_t *bu) { bu->ops = &sb_finished_ops; @@ -1652,6 +1590,7 @@ void seq_build_init(val self, seq_build_t *bu, val likeobj) if (from_list_meth) { bu->obj = nil; + bu->tail = mkcloc(bu->obj); bu->u.from_list_meth = from_list_meth; bu->ops = &sb_struct_ops; break; @@ -1659,6 +1598,7 @@ void seq_build_init(val self, seq_build_t *bu, val likeobj) } if (likeobj->co.cls == carray_cls) { bu->obj = nil; + bu->tail = mkcloc(bu->obj); bu->u.carray_type = carray_type(likeobj); bu->ops = &sb_carray_ops; } @@ -1668,6 +1608,7 @@ void seq_build_init(val self, seq_build_t *bu, val likeobj) case LCONS: default: bu->obj = nil; + bu->tail = mkcloc(bu->obj); bu->ops = &sb_list_ops; break; } @@ -471,6 +471,7 @@ struct seq_iter_ops { typedef struct seq_build { val obj; + loc tail; val self; union { val from_list_meth; |