1 ! Copyright (C) 2007, 2009 Chris Double, Doug Coleman, Eduardo
2 ! Cavazos, Slava Pestov.
3 ! See http://factorcode.org/license.txt for BSD license.
4 USING: arrays combinators kernel kernel.private math ranges
5 memoize.private sequences ;
8 ! These words can be inline combinators when the word does no math
9 ! on the input parameters, e.g. n.
10 ! If math is done, the word needs to be a macro so the math can
11 ! be done at compile-time.
14 ALIAS: n*quot (n*quot)
16 MACRO: call-n ( n -- quot )
17 [ call ] <repetition> '[ _ cleave ] ;
19 : repeat ( n obj quot -- ) swapd times ; inline
23 MACRO: nsum ( n -- quot )
26 ERROR: nonpositive-npick n ;
28 MACRO: npick ( n -- quot )
30 { [ dup 0 <= ] [ nonpositive-npick ] }
31 { [ dup 1 = ] [ drop [ dup ] ] }
32 [ 1 - [ dup ] [ '[ _ dip swap ] ] repeat ]
36 [ '[ _ npick ] ] keep call-n ; inline
38 MACRO: dupn ( n -- quot )
40 [ 1 - [ dup ] n*quot ] if-zero ;
42 MACRO: nrot ( n -- quot )
43 1 - [ ] [ '[ _ dip swap ] ] repeat ;
45 MACRO: -nrot ( n -- quot )
46 1 - [ ] [ '[ swap _ dip ] ] repeat ;
49 [ [ dip ] curry ] swap call-n call ; inline
52 [ drop ] swap call-n ; inline
55 '[ _ ndrop ] dip ; inline
58 MACRO: nrotd ( n d -- quot )
60 [ neg ] dip '[ _ _ -nrotd ]
62 [ 1 - [ ] [ '[ _ dip swap ] ] repeat ] dip '[ _ _ ndip ]
65 MACRO: -nrotd ( n d -- quot )
67 [ neg ] dip '[ _ _ nrotd ]
69 [ 1 - [ ] [ '[ swap _ dip ] ] repeat ] dip '[ _ _ ndip ]
72 MACRO: nrotated ( nrots depth dip -- quot )
73 [ '[ [ _ nrot ] ] replicate [ ] concat-as ] dip '[ _ _ ndip ] ;
75 MACRO: -nrotated ( -nrots depth dip -- quot )
76 [ '[ [ _ -nrot ] ] replicate [ ] concat-as ] dip '[ _ _ ndip ] ;
78 MACRO: nrotate-heightd ( n height dip -- quot )
79 [ '[ [ _ nrot ] ] replicate concat ] dip '[ _ _ ndip ] ;
81 MACRO: -nrotate-heightd ( n height dip -- quot )
83 '[ [ _ -nrot ] ] replicate concat
86 : ndupd ( n dip -- ) '[ [ _ ndup ] _ ndip ] call ; inline
88 MACRO: ntuckd ( ntuck ndip -- quot )
89 [ 1 + ] dip '[ [ dup _ -nrot ] _ ndip ] ;
91 MACRO: nover ( n -- quot )
92 dup 1 + '[ _ npick ] n*quot ;
94 MACRO: noverd ( n depth dip -- quot' )
95 [ + ] [ 2drop ] [ [ + ] dip ] 3tri
96 '[ _ _ ndupd _ _ _ nrotated ] ;
98 MACRO: mntuckd ( ndup depth ndip -- quot )
99 { [ nip ] [ 2drop ] [ drop + ] [ 2nip ] } 3cleave
100 '[ _ _ ndupd _ _ _ -nrotated ] ;
103 dup '[ [ _ ndup ] dip _ ndip ] call ; inline
106 [ curry ] swap call-n ; inline
109 [ with ] swap call-n ; inline
111 : nbi ( quot1 quot2 n -- )
112 [ nip nkeep ] [ drop nip call ] 3bi ; inline
114 MACRO: ncleave ( quots n -- quot )
115 [ '[ _ '[ _ _ nkeep ] ] map [ ] join ] [ '[ _ ndrop ] ] bi
118 MACRO: nspread ( quots n -- quot )
119 over empty? [ 2drop [ ] ] [
123 '[ [ _ _ nspread ] _ ndip @ ]
126 MACRO: spread* ( n -- quot )
128 [1..b) [ '[ [ [ _ ndip ] curry ] dip compose ] ] map [ ] concat-as
132 MACRO: nspread* ( m n -- quot )
134 [ * 0 ] [ drop neg ] 2bi
135 <range> rest >array dup length <iota> <reversed>
136 [ '[ [ [ _ ndip ] curry ] _ ndip ] ] 2map
138 [ length 1 - [ compose ] <array> concat append ] bi
142 MACRO: cleave* ( n -- quot )
144 [ 1 - [ [ [ keep ] curry ] dip compose ] n*quot [ call ] compose ]
147 : napply ( quot n -- )
148 [ dupn ] [ spread* ] bi ; inline
150 : mnapply ( quot m n -- )
151 [ nip dupn ] [ nspread* ] 2bi ; inline
153 : apply-curry ( a... quot n -- )
154 [ currier ] dip napply ; inline
156 : cleave-curry ( a quot... n -- )
157 [ currier ] swap [ napply ] [ cleave* ] bi ; inline
159 : spread-curry ( a... quot... n -- )
160 [ currier ] swap [ napply ] [ spread* ] bi ; inline
162 MACRO: mnswap ( m n -- quot )
163 1 + '[ _ -nrot ] swap '[ _ _ napply ] ;
165 MACRO: nweave ( n -- quot )
166 [ dup <iota> <reversed> [ '[ _ _ mnswap ] ] with map ] keep
170 [ bi-curry ] swap call-n ; inline
172 MACRO: map-compose ( quots quot -- quot' )
173 '[ _ compose ] map '[ _ ] ;