From d94af272503d246929556087ae687d0fa8170611 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Thu, 13 Oct 2016 06:51:20 -0700 Subject: Bugfix: sub and length on abstract sequences. * lib.c (length_proper_list): New static function. (length): Use length_proper_list for objects. (sub): Call nullify on COBJ object before passing to sub_list. * tests/012/aseq.tl, tests/012/aseq.expected: New files. --- lib.c | 31 ++++++++++++++++++++++++++++++- tests/012/aseq.expected | 0 tests/012/aseq.tl | 15 +++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 tests/012/aseq.expected create mode 100644 tests/012/aseq.tl diff --git a/lib.c b/lib.c index a3b88366..c032bde1 100644 --- a/lib.c +++ b/lib.c @@ -2752,6 +2752,31 @@ val length_list(val list) return bn_len; } +static val length_proper_list(val list) +{ + cnum len = 0; + val bn_len; + + gc_hint(list); + + while (list && len < INT_PTR_MAX) { + len++; + list = cdr(list); + } + + if (len < INT_PTR_MAX) + return num(len); + + bn_len = num(INT_PTR_MAX); + + while (list) { + bn_len = succ(bn_len); + list = cdr(list); + } + + return bn_len; +} + val getplist(val list, val key) { gc_hint(list); @@ -8178,6 +8203,8 @@ val copy(val seq) } } +static val length_proper_list(val list); + val length(val seq) { switch (type(seq)) { @@ -8198,7 +8225,7 @@ val length(val seq) if (seq->co.cls == hash_s) return hash_count(seq); if (structp(seq) && maybe_slot(seq, car_s)) - return length_list(nullify(seq)); + return length_proper_list(nullify(seq)); /* fallthrough */ default: type_mismatch(lit("length: ~s is not a sequence"), seq, nao); @@ -8240,6 +8267,8 @@ val sub(val seq, val from, val to) case NIL: return nil; case COBJ: + seq = nullify(seq); + /* fallthrough */ case CONS: case LCONS: return sub_list(seq, from, to); diff --git a/tests/012/aseq.expected b/tests/012/aseq.expected new file mode 100644 index 00000000..e69de29b diff --git a/tests/012/aseq.tl b/tests/012/aseq.tl new file mode 100644 index 00000000..7901c4ab --- /dev/null +++ b/tests/012/aseq.tl @@ -0,0 +1,15 @@ +(load "../common") + +(defstruct (add n list) nil + n list + (:method cdr (me) (if (cdr me.list) (new (add me.n (cdr me.list))))) + (:method car (me) (+ me.n (car me.list))) + (:method nullify (me) (if me.list me)) + (:method lambda (me i) (ref me i))) + +(defvarl o (new (add 3 (range 10 100 10)))) + +(test (car o) 13) +(test (cadr o) 23) +(test [o 4] 53) +(test (cadr (last o)) nil) -- cgit v1.2.3