From d12b6d6896a9838abd925feae34f6c01d535f223 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 28 Feb 2024 08:46:18 -0800 Subject: 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. --- lib.c | 77 ++++++++----------------------------------------------------------- lib.h | 1 + 2 files changed, 10 insertions(+), 68 deletions(-) diff --git a/lib.c b/lib.c index 87c9ba37..c336bd7f 100644 --- a/lib.c +++ b/lib.c @@ -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, @@ -1579,43 +1538,22 @@ static struct seq_build_ops seq_build_list_finish, 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; } diff --git a/lib.h b/lib.h index a6e4869e..f254ce6b 100644 --- a/lib.h +++ b/lib.h @@ -471,6 +471,7 @@ struct seq_iter_ops { typedef struct seq_build { val obj; + loc tail; val self; union { val from_list_meth; -- cgit v1.2.3