lists: Add list literals.
[factor.git] / basis / lists / lists.factor
blob206752f7cacf3118b499ff74ca3d3dfeda933cdc
1 ! Copyright (C) 2008 James Cash, Daniel Ehrenberg, Chris Double.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors combinators.short-circuit kernel locals math
4 parser sequences ;
5 IN: lists
7 ! List Protocol
8 MIXIN: list
9 GENERIC: car ( cons -- car )
10 GENERIC: cdr ( cons -- cdr )
11 GENERIC: nil? ( object -- ?   )
13 TUPLE: cons-state { car read-only } { cdr read-only } ;
15 C: cons cons-state
17 M: cons-state car ( cons -- car ) car>> ;
19 M: cons-state cdr ( cons -- cdr ) cdr>> ;
21 SINGLETON: +nil+
22 M: +nil+ nil? drop t ;
23 M: object nil? drop f ;
25 : atom? ( obj -- ? ) list? not ; inline
27 : nil ( -- symbol ) +nil+ ; inline
29 : uncons ( cons -- car cdr ) [ car ] [ cdr ] bi ; inline
31 : swons ( cdr car -- cons ) swap cons ; inline
33 : unswons ( cons -- cdr car ) uncons swap ; inline
35 : 1list ( obj -- cons ) nil cons ; inline
37 : 1list? ( list -- ? ) { [ nil? not ] [ cdr nil? ] } 1&& ; inline
39 : 2list ( a b -- cons ) 1list cons ; inline
41 : 3list ( a b c -- cons ) 2list cons ; inline
43 : cadr ( list -- elt ) cdr car ; inline
45 : 2car ( list -- car cadr ) uncons car ; inline
47 : 3car ( list -- car cadr caddr ) uncons uncons car ; inline
49 : lnth ( n list -- elt ) swap [ cdr ] times car ; inline
51 <PRIVATE
53 : (leach) ( list quot -- cdr quot )
54     [ [ car ] dip call ] [ [ cdr ] dip ] 2bi ; inline
56 PRIVATE>
58 : leach ( ... list quot: ( ... elt -- ... ) -- ... )
59     over nil? [ 2drop ] [ (leach) leach ] if ; inline recursive
61 : foldl ( ... list identity quot: ( ... prev elt -- ... next ) -- ... result )
62     swapd leach ; inline
64 :: foldr ( ... list identity quot: ( ... prev elt -- ... next ) -- ... result )
65     list nil? [
66         identity
67     ] [
68         list cdr identity quot foldr
69         list car quot call
70     ] if ; inline recursive
72 : llength ( list -- n )
73     0 [ drop 1 + ] foldl ;
75 : lreverse ( list -- newlist )
76     nil [ swons ] foldl ;
78 : lmap ( ... list quot: ( ... elt -- ... newelt ) -- ... result )
79     [ nil ] dip [ swapd dip cons ] curry foldl lreverse ; inline
81 : lappend ( list1 list2 -- newlist )
82     [ lreverse ] dip [ swons ] foldl ;
84 : lcut ( list index -- before after )
85     [ nil ] dip [ [ unswons ] dip cons ] times lreverse swap ;
87 : sequence>list ( sequence -- list )
88     <reversed> nil [ swons ] reduce ;
90 : lmap>array ( ... list quot: ( ... elt -- ... newelt ) -- ... array )
91     collector [ leach ] dip { } like ; inline
93 : list>array ( list -- array )
94     [ ] lmap>array ;
96 : deeplist>array ( list -- array )
97     [ dup list? [ deeplist>array ] when ] lmap>array ;
99 INSTANCE: cons-state list
100 INSTANCE: +nil+ list
102 GENERIC: >list ( object -- list )
104 M: list >list ;
106 M: sequence >list sequence>list ;
108 SYNTAX: L{ \ } [ sequence>list ] parse-literal ;