From ef524fdf234fe51a37021b8c1a3bb700d5501132 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Tue, 27 Feb 2024 08:18:42 -0800 Subject: seq_build: build lists in order using tail pointer. * lib.c (seq_build_list_add, seq_build_list_finish): We use the trick that bu->obj (if not nil) points to the tail cons cell of the list being built, and the cdr of that tail always points back to the head. To finish the list, all we do is nil out that head pointer, so the list is properly terminated, and then plan the head as bu->obj. --- lib.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/lib.c b/lib.c index b8aed8d6..c83afa4d 100644 --- a/lib.c +++ b/lib.c @@ -1472,12 +1472,29 @@ static void seq_build_buf_finish(seq_build_t *bu) static void seq_build_list_add(seq_build_t *bu, val item) { - bu->obj = cons(item, bu->obj); + 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; + } } static void seq_build_list_finish(seq_build_t *bu) { - bu->obj = nreverse(bu->obj); + val obj = bu->obj; + + if (obj) { + val head = us_cdr(obj); + us_rplacd(obj, nil); + bu->obj = head; + } } static void seq_build_struct_finish(seq_build_t *bu) -- cgit v1.2.3