summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2024-02-28 08:46:18 -0800
committerKaz Kylheku <kaz@kylheku.com>2024-02-28 08:46:18 -0800
commitd12b6d6896a9838abd925feae34f6c01d535f223 (patch)
tree6b14f862693f28a31e2b6ae0fa0d6f60939ad73f
parent0490e3a4bf568584e7701ee34fd8f27b1f518404 (diff)
downloadtxr-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.c77
-rw-r--r--lib.h1
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,
@@ -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;
}
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;