diff options
-rw-r--r-- | share/txr/stdlib/build.tl | 67 | ||||
-rw-r--r-- | txr.1 | 68 |
2 files changed, 86 insertions, 49 deletions
diff --git a/share/txr/stdlib/build.tl b/share/txr/stdlib/build.tl index 41826255..2c9f97ca 100644 --- a/share/txr/stdlib/build.tl +++ b/share/txr/stdlib/build.tl @@ -32,59 +32,50 @@ bc.tail bc.head)) (:method add (self . items) - (let ((tl self.tail)) - (usr:rplacd tl (copy-list (cdr tl))) - (set tl (last tl)) - (usr:rplacd tl items) + (let ((st self.tail)) + (rplacd st (append (cdr st) nil))) + (let ((tl (last self.tail))) + (usr:rplacd tl (append (cdr tl) items)) (set self.tail tl)) nil) (:method add* (self . items) - (let ((ic (copy-list items)) - (h self.head)) - (usr:rplacd (last ic) (cdr h)) - (usr:rplacd h ic)) + (let ((h self.head)) + (usr:rplacd h (append items (cdr h)))) nil) (:method pend (self . lists) - (let ((tl self.tail)) - (while lists - (usr:rplacd tl (copy-list (cdr tl))) - (set tl (last tl)) - (let ((nx (car lists))) - (usr:rplacd tl (if (tailp tl nx) - (copy-list nx) - nx))) - (set lists (cdr lists))) - (set self.tail tl)) - nil) + (when lists + (let ((st self.tail)) + (rplacd st (append (cdr st) nil))) + (let* ((tl (last self.tail)) + (cp (let ((ll (car (last lists)))) + (if (consp ll) + (let ((lt (last ll))) + (eq tl lt))))) + (nl [apply append lists])) + (usr:rplacd tl (append (cdr tl) (if cp (copy-list nl) nl))) + (set self.tail tl)) + nil)) (:method pend* (self . lists) - (let* ((h (cdr self.head)) - (nh (cons nil nil)) - (tl nh)) - (while lists - (usr:rplacd tl (copy-list (cdr tl))) - (set tl (last tl)) - (usr:rplacd tl (car lists)) - (set lists (cdr lists))) - (set tl (last tl)) - (usr:rplacd tl (if (tailp tl h) (copy-list h) h)) - (set self.head nh)) + (let* ((h self.head) + (pf [apply apply (append lists (list (cdr h)))])) + (usr:rplacd h pf) + (set self.tail self.head)) nil) (:method ncon (self . lists) - (let ((tl self.tail)) - (while lists - (set tl (last tl)) - (usr:rplacd tl (car lists)) - (set lists (cdr lists))) - (set self.tail tl)) - nil) + (when lists + (let* ((tl (last self.tail)) + (nl [apply nconc lists])) + (usr:rplacd tl (nconc (cdr tl) nl)) + (set self.tail tl)) + nil)) (:method ncon* (self . lists) (let* ((h self.head) - (pf (nconc (nconc . lists) (cdr h)))) + (pf [apply nconc (append lists (list (cdr h)))])) (usr:rplacd h pf) (if (eq self.tail h) (set self.tail pf))) @@ -32199,13 +32199,17 @@ without an argument to produce an object .meta obj the invoking the method call .mono -.meti << obj .(ncon << list ) +.meti << obj .(ncon << initial-list ) .onom on this object. The object produced by the expression .meta list is installed (without being copied) into the object as the prefix of the list to be constructed. +The +.meta initial-list +argument can be a sequence other than a list. + .TP* Example: .verb @@ -32239,7 +32243,18 @@ adds elements at the front. These methods return .codn nil . -.TP* Example: +The precise semantics is as follows. +All of the +.meta element +arguments are combined into a list as if by the +.code list +function, and the resulting list combined with the current contents of the +.code list-builder +object as if using the +.code append +function. The resulting list becomes the new contents. + +.TP* Examples: .verb ;; Build the list (1 2 3 4) @@ -32249,6 +32264,14 @@ These methods return lb.(add* 1 2) lb.(get)) -> (1 2 3 4) + + ;; Add "c" to "abc" + ;; same semantics as (append "abc" #\ec) + + (let ((lb (build-list "ab"))) + lb.(add #\ec) + lb.(get)) + -> "abc" .brev .coNP Methods @ pend and @ pend* @@ -32277,9 +32300,18 @@ method is similar, except it prepends the catenated lists to the front of the list being constructed. -Both methods have the property that the -constructed list does not share structure -with the input lists. +The +.code pend +and +.code pend* +operations do not mutate the input lists, but may cause the +resulting list to share structure with the input lists. + +These functions may mutate the list already contained in +.metn list-builder ; +however, they avoid mutating those parts of the current list +that are shared with inputs that were given in earlier +calls to these functions. These methods return .codn nil . @@ -32322,17 +32354,31 @@ method is similar, except it prepends the catenated lists to the front of the list being constructed. -These methods destructively manipulate -the input lists. Moreover, they cause the -list being constructed to share substructure -with the input lists. +These methods may destructively manipulate the list already contained in the +.meta list-builder +object, and likewise may destructively manipulate the input lists. +They may cause the list being constructed to share substructure with the input +lists. -Additionally, the +Additionally, these methods may destructively manipulate the list already +contained in the +.meta list-builder +object without regard for shared structure between that list and inputs +given earlier any of the +.codn pend , +.codn pend* , +.code ncon +or +.code ncon* +functions. + +The .code ncon* function can be called with a single argument which is an atom. This atom will simply be installed as the terminating atom of the -list being constructed. +list being constructed, if the current list is +an ordinary list. These methods return .codn nil . |