]> gitweb.factorcode.org Git - factor.git/blob - core/kernel/kernel.factor
Move call( and execute( to core
[factor.git] / core / kernel / kernel.factor
1 ! Copyright (C) 2004, 2009 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: kernel.private slots.private math.private
4 classes.tuple.private ;
5 IN: kernel
6
7 DEFER: dip
8 DEFER: 2dip
9 DEFER: 3dip
10
11 ! Stack stuff
12 : spin ( x y z -- z y x ) swap rot ; inline
13
14 : roll ( x y z t -- y z t x ) [ rot ] dip swap ; inline
15
16 : -roll ( x y z t -- t x y z ) swap [ -rot ] dip ; inline
17
18 : 2over ( x y z -- x y z x y ) pick pick ; inline
19
20 : clear ( -- ) { } set-datastack ;
21
22 ! Combinators
23 GENERIC: call ( callable -- )
24
25 GENERIC: execute ( word -- )
26
27 DEFER: if
28
29 : ? ( ? true false -- true/false )
30     #! 'if' and '?' can be defined in terms of each other
31     #! because the JIT special-cases an 'if' preceeded by
32     #! two literal quotations.
33     rot [ drop ] [ nip ] if ; inline
34
35 : if ( ? true false -- ) ? call ;
36
37 ! Single branch
38 : unless ( ? false -- )
39     swap [ drop ] [ call ] if ; inline
40
41 : when ( ? true -- )
42     swap [ call ] [ drop ] if ; inline
43
44 ! Anaphoric
45 : if* ( ? true false -- )
46     pick [ drop call ] [ 2nip call ] if ; inline
47
48 : when* ( ? true -- )
49     over [ call ] [ 2drop ] if ; inline
50
51 : unless* ( ? false -- )
52     over [ drop ] [ nip call ] if ; inline
53
54 ! Default
55 : ?if ( default cond true false -- )
56     pick [ drop [ drop ] 2dip call ] [ 2nip call ] if ; inline
57
58 ! Slippers and dippers.
59 ! Not declared inline because the compiler special-cases them
60
61 : slip ( quot x -- x )
62     #! 'slip' and 'dip' can be defined in terms of each other
63     #! because the JIT special-cases a 'dip' preceeded by
64     #! a literal quotation.
65     [ call ] dip ;
66
67 : 2slip ( quot x y -- x y )
68     #! '2slip' and '2dip' can be defined in terms of each other
69     #! because the JIT special-cases a '2dip' preceeded by
70     #! a literal quotation.
71     [ call ] 2dip ;
72
73 : 3slip ( quot x y z -- x y z )
74     #! '3slip' and '3dip' can be defined in terms of each other
75     #! because the JIT special-cases a '3dip' preceeded by
76     #! a literal quotation.
77     [ call ] 3dip ;
78
79 : dip ( x quot -- x ) swap slip ;
80
81 : 2dip ( x y quot -- x y ) -rot 2slip ;
82
83 : 3dip ( x y z quot -- x y z ) -roll 3slip ;
84
85 : 4dip ( w x y z quot -- w x y z ) swap [ 3dip ] dip ; inline
86
87 ! Keepers
88 : keep ( x quot -- x ) over slip ; inline
89
90 : 2keep ( x y quot -- x y ) [ 2dup ] dip 2dip ; inline
91
92 : 3keep ( x y z quot -- x y z ) [ 3dup ] dip 3dip ; inline
93
94 ! Cleavers
95 : bi ( x p q -- )
96     [ keep ] dip call ; inline
97
98 : tri ( x p q r -- )
99     [ [ keep ] dip keep ] dip call ; inline
100
101 ! Double cleavers
102 : 2bi ( x y p q -- )
103     [ 2keep ] dip call ; inline
104
105 : 2tri ( x y p q r -- )
106     [ [ 2keep ] dip 2keep ] dip call ; inline
107
108 ! Triple cleavers
109 : 3bi ( x y z p q -- )
110     [ 3keep ] dip call ; inline
111
112 : 3tri ( x y z p q r -- )
113     [ [ 3keep ] dip 3keep ] dip call ; inline
114
115 ! Spreaders
116 : bi* ( x y p q -- )
117     [ dip ] dip call ; inline
118
119 : tri* ( x y z p q r -- )
120     [ [ 2dip ] dip dip ] dip call ; inline
121
122 ! Double spreaders
123 : 2bi* ( w x y z p q -- )
124     [ 2dip ] dip call ; inline
125
126 : 2tri* ( u v w x y z p q r -- )
127     [ 4dip ] 2dip 2bi* ; inline
128
129 ! Appliers
130 : bi@ ( x y quot -- )
131     dup bi* ; inline
132
133 : tri@ ( x y z quot -- )
134     dup dup tri* ; inline
135
136 ! Double appliers
137 : 2bi@ ( w x y z quot -- )
138     dup 2bi* ; inline
139
140 : 2tri@ ( u v w y x z quot -- )
141     dup dup 2tri* ; inline
142
143 ! Quotation building
144 : 2curry ( obj1 obj2 quot -- curry )
145     curry curry ; inline
146
147 : 3curry ( obj1 obj2 obj3 quot -- curry )
148     curry curry curry ; inline
149
150 : with ( param obj quot -- obj curry )
151     swapd [ swapd call ] 2curry ; inline
152
153 : prepose ( quot1 quot2 -- compose )
154     swap compose ; inline
155
156 ! Curried cleavers
157 <PRIVATE
158
159 : [curry] ( quot -- quot' ) [ curry ] curry ; inline
160
161 PRIVATE>
162
163 : bi-curry ( x p q -- p' q' ) [ [curry] ] bi@ bi ; inline
164
165 : tri-curry ( x p q r -- p' q' r' ) [ [curry] ] tri@ tri ; inline
166
167 : bi-curry* ( x y p q -- p' q' ) [ [curry] ] bi@ bi* ; inline
168
169 : tri-curry* ( x y z p q r -- p' q' r' ) [ [curry] ] tri@ tri* ; inline
170
171 : bi-curry@ ( x y q -- p' q' ) [curry] bi@ ; inline
172
173 : tri-curry@ ( x y z q -- p' q' r' ) [curry] tri@ ; inline
174
175 ! Booleans
176 : not ( obj -- ? ) [ f ] [ t ] if ; inline
177
178 : and ( obj1 obj2 -- ? ) over ? ; inline
179
180 : >boolean ( obj -- ? ) [ t ] [ f ] if ; inline
181
182 : or ( obj1 obj2 -- ? ) dupd ? ; inline
183
184 : xor ( obj1 obj2 -- ? ) [ f swap ? ] when* ; inline
185
186 : both? ( x y quot -- ? ) bi@ and ; inline
187
188 : either? ( x y quot -- ? ) bi@ or ; inline
189
190 : most ( x y quot -- z ) 2keep ? ; inline
191
192 ! Loops
193 : loop ( pred: ( -- ? ) -- )
194     [ call ] keep [ loop ] curry when ; inline recursive
195
196 : do ( pred body -- pred body )
197     dup 2dip ; inline
198
199 : while ( pred: ( -- ? ) body: ( -- ) -- )
200     swap do compose [ loop ] curry when ; inline
201
202 : until ( pred: ( -- ? ) body: ( -- ) -- )
203     [ [ not ] compose ] dip while ; inline
204
205 ! Object protocol
206 GENERIC: hashcode* ( depth obj -- code )
207
208 M: object hashcode* 2drop 0 ;
209
210 M: f hashcode* 2drop 31337 ;
211
212 : hashcode ( obj -- code ) 3 swap hashcode* ; inline
213
214 GENERIC: equal? ( obj1 obj2 -- ? )
215
216 M: object equal? 2drop f ;
217
218 TUPLE: identity-tuple ;
219
220 M: identity-tuple equal? 2drop f ;
221
222 : = ( obj1 obj2 -- ? )
223     2dup eq? [ 2drop t ] [
224         2dup both-fixnums? [ 2drop f ] [ equal? ] if
225     ] if ; inline
226
227 GENERIC: clone ( obj -- cloned )
228
229 M: object clone ;
230
231 M: callstack clone (clone) ;
232
233 ! Tuple construction
234 GENERIC: new ( class -- tuple )
235
236 GENERIC: boa ( ... class -- tuple )
237
238 ! Error handling -- defined early so that other files can
239 ! throw errors before continuations are loaded
240 GENERIC: throw ( error -- * )
241
242 ERROR: assert got expect ;
243
244 : assert= ( a b -- ) 2dup = [ 2drop ] [ assert ] if ;
245
246 <PRIVATE
247
248 : declare ( spec -- ) drop ;
249
250 : hi-tag ( obj -- n ) { hi-tag } declare 0 slot ; inline
251
252 : do-primitive ( number -- ) "Improper primitive call" throw ;
253
254 PRIVATE>