factor/basis/lists/lists.factor

138 lines
3.4 KiB
Factor
Raw Normal View History

2009-05-16 14:34:39 -04:00
! Copyright (C) 2008 James Cash, Daniel Ehrenberg, Chris Double.
! See http://factorcode.org/license.txt for BSD license.
2020-02-15 08:19:38 -05:00
USING: accessors combinators combinators.short-circuit kernel
2020-02-24 12:11:46 -05:00
lexer locals make math namespaces parser sequences words ;
IN: lists
! List Protocol
MIXIN: list
GENERIC: car ( cons -- car )
GENERIC: cdr ( cons -- cdr )
GENERIC: nil? ( object -- ? )
2014-09-28 18:20:50 -04:00
2013-03-24 12:58:05 -04:00
TUPLE: cons-state { car read-only } { cdr read-only } ;
2013-03-24 12:58:05 -04:00
C: cons cons-state
2013-03-24 12:58:05 -04:00
M: cons-state car ( cons -- car ) car>> ;
2013-03-24 12:58:05 -04:00
M: cons-state cdr ( cons -- cdr ) cdr>> ;
SINGLETON: +nil+
M: +nil+ nil? drop t ;
2008-06-04 00:56:06 -04:00
M: object nil? drop f ;
2009-05-16 14:34:39 -04:00
: atom? ( obj -- ? ) list? not ; inline
2009-05-16 14:34:39 -04:00
: nil ( -- symbol ) +nil+ ; inline
2009-05-16 14:34:39 -04:00
: uncons ( cons -- car cdr ) [ car ] [ cdr ] bi ; inline
2009-05-16 14:34:39 -04:00
: swons ( cdr car -- cons ) swap cons ; inline
2009-05-16 14:34:39 -04:00
: unswons ( cons -- cdr car ) uncons swap ; inline
2009-05-16 14:34:39 -04:00
: 1list ( obj -- cons ) nil cons ; inline
2009-05-16 14:34:39 -04:00
: 1list? ( list -- ? ) { [ nil? not ] [ cdr nil? ] } 1&& ; inline
2011-10-14 15:08:48 -04:00
: 2list ( a b -- cons ) 1list cons ; inline
2011-10-14 15:08:48 -04:00
: 3list ( a b c -- cons ) 2list cons ; inline
2009-05-16 14:34:39 -04:00
: cadr ( list -- elt ) cdr car ; inline
2014-09-28 18:20:50 -04:00
2016-04-18 12:46:29 -04:00
: 2car ( list -- car cadr ) uncons car ; inline
2014-09-28 18:20:50 -04:00
2016-04-18 12:46:29 -04:00
: 3car ( list -- car cadr caddr ) uncons uncons car ; inline
2009-05-16 14:34:39 -04:00
: lnth ( n list -- elt ) swap [ cdr ] times car ; inline
<PRIVATE
2009-05-16 14:34:39 -04:00
: (leach) ( list quot -- cdr quot )
[ [ car ] dip call ] [ [ cdr ] dip ] 2bi ; inline
2009-05-16 14:34:39 -04:00
PRIVATE>
: leach ( ... list quot: ( ... elt -- ... ) -- ... )
2008-08-24 04:59:37 -04:00
over nil? [ 2drop ] [ (leach) leach ] if ; inline recursive
2010-03-10 00:02:43 -05:00
: foldl ( ... list identity quot: ( ... prev elt -- ... next ) -- ... result )
2008-08-24 04:59:37 -04:00
swapd leach ; inline
2010-03-10 00:02:43 -05:00
:: foldr ( ... list identity quot: ( ... prev elt -- ... next ) -- ... result )
2016-04-18 12:46:29 -04:00
list nil? [
identity
] [
2009-02-09 16:31:57 -05:00
list cdr identity quot foldr
list car quot call
2008-08-24 04:59:37 -04:00
] if ; inline recursive
2008-06-05 14:32:43 -04:00
: llength ( list -- n )
0 [ drop 1 + ] foldl ;
: lreverse ( list -- newlist )
2011-10-14 15:08:48 -04:00
nil [ swons ] foldl ;
: lmap ( ... list quot: ( ... elt -- ... newelt ) -- ... result )
[ nil ] dip [ swapd dip cons ] curry foldl lreverse ; inline
: lappend ( list1 list2 -- newlist )
2011-10-14 15:08:48 -04:00
[ lreverse ] dip [ swons ] foldl ;
: lcut ( list index -- before after )
2016-04-18 12:46:29 -04:00
[ nil ] dip [ [ unswons ] dip cons ] times lreverse swap ;
2014-09-28 18:20:50 -04:00
: sequence>list ( sequence -- list )
2009-05-16 14:34:39 -04:00
<reversed> nil [ swons ] reduce ;
2009-02-09 16:31:57 -05:00
: lmap>array ( ... list quot: ( ... elt -- ... newelt ) -- ... array )
collector [ leach ] dip { } like ; inline
2009-05-16 14:34:39 -04:00
2014-09-28 18:20:50 -04:00
: list>array ( list -- array )
[ ] lmap>array ;
2015-07-14 19:35:59 -04:00
: deeplist>array ( list -- array )
[ dup list? [ deeplist>array ] when ] lmap>array ;
2013-03-24 17:15:32 -04:00
INSTANCE: cons-state list
2009-02-09 16:31:57 -05:00
INSTANCE: +nil+ list
2014-09-28 18:20:50 -04:00
GENERIC: >list ( object -- list )
M: list >list ;
2018-07-13 21:36:07 -04:00
M: sequence >list sequence>list ;
ERROR: list-syntax-error ;
<PRIVATE
: items>list ( sequence -- list )
[ +nil+ ] [
<reversed> unclip-slice [ swons ] reduce
] if-empty ;
2020-02-24 12:11:46 -05:00
: ?list-syntax-error ( right-of-dot? -- )
building get empty? or [ list-syntax-error ] when ;
: (parse-list-literal) ( right-of-dot? -- )
scan-token {
{ "}" [ drop +nil+ , ] }
2020-02-24 12:11:46 -05:00
{ "." [ ?list-syntax-error t (parse-list-literal) ] }
2020-02-15 08:04:08 -05:00
[
parse-datum dup parsing-word? [
V{ } clone swap execute-parsing first
] when
, [ "}" expect ] [ f (parse-list-literal) ] if
]
2020-02-15 08:04:08 -05:00
} case ;
: parse-list-literal ( -- list )
2020-02-15 08:04:08 -05:00
[ f (parse-list-literal) ] { } make items>list ;
PRIVATE>
2020-02-15 08:04:08 -05:00
SYNTAX: L{ parse-list-literal suffix! ;