diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2024-02-27 20:46:33 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2024-02-27 20:46:33 -0800 |
commit | b3a440ca242a07ed86f89d06208f15757d947e12 (patch) | |
tree | 805e1862a39da0c730627a0a30ecb78ad219ec52 /lib.c | |
parent | d36f90235fcf1561a43bf79283a40b042efff84a (diff) | |
download | txr-b3a440ca242a07ed86f89d06208f15757d947e12.tar.gz txr-b3a440ca242a07ed86f89d06208f15757d947e12.tar.bz2 txr-b3a440ca242a07ed86f89d06208f15757d947e12.zip |
seq_build: fix: incompatible items must create list.
In the make_like function, the list is converted to
string or buffer if the first element of the list
is a character, or integer. We need similar logic in
seq_build. We can make it better. When any item is
added which is incompatible, we can convert what we
have so far to a list, change the seq_build type
to list, and keep going.
* lib.c (seq_build_convert_to_list): New static
function.
(seq_build_str_add, seq_build_buf_add): If the item
is incompatible, convert the string or buffer to
a list and pass to seq_build_convert_to_list.
Then call bu->ops->add to add the item, now as a list.
(seq_build_buf_pend): Function removed.
(sb_buf_ops): Use the seq_build_generic_pend function
for the pend operation. This is because we have to
check each item one by one; we cannot use replace_buf.
Diffstat (limited to 'lib.c')
-rw-r--r-- | lib.c | 42 |
1 files changed, 30 insertions, 12 deletions
@@ -1438,9 +1438,16 @@ static void seq_build_vec_add(seq_build_t *bu, val item) vec_push(bu->obj, item); } +static void seq_build_convert_to_list(seq_build_t *bu, val list); + static void seq_build_str_add(seq_build_t *bu, val item) { - string_extend(bu->obj, item, nil); + if (chrp(item)) { + string_extend(bu->obj, item, nil); + } else { + seq_build_convert_to_list(bu, list_str(bu->obj)); + bu->ops->add(bu, item); + } } static void seq_build_str_finish(seq_build_t *bu) @@ -1451,17 +1458,14 @@ static void seq_build_str_finish(seq_build_t *bu) static void seq_build_buf_add(seq_build_t *bu, val item) { val buf = bu->obj; - val len = length_buf(buf); - - buf_put_uchar(buf, len, item); -} -static void seq_build_buf_pend(seq_build_t *bu, val seq) -{ - val buf = bu->obj; - val len = length_buf(buf); - - replace_buf(buf, seq, len, len); + if (integerp(item)) { + val len = length_buf(buf); + buf_put_uchar(buf, len, item); + } else { + seq_build_convert_to_list(bu, mapcar_listout(identity_f, buf)); + bu->ops->add(bu, item); + } } static void seq_build_buf_finish(seq_build_t *bu) @@ -1522,7 +1526,7 @@ static struct seq_build_ops static struct seq_build_ops sb_buf_ops = seq_build_ops_init(seq_build_buf_add, - seq_build_buf_pend, + seq_build_generic_pend, seq_build_buf_finish, seq_build_obj_mark); @@ -1544,6 +1548,20 @@ static struct seq_build_ops seq_build_list_finish, 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; + } else { + bu->obj = nil; + } + + bu->ops = &sb_list_ops; +} + + void seq_build_init(val self, seq_build_t *bu, val likeobj) { bu->self = self; |