1 ! Copyright (C) 2004, 2006 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
4 USING: arrays alien assembler errors generic hashtables
5 hashtables-internals io io-internals kernel
6 kernel-internals math math-internals memory parser
7 sequences strings vectors words prettyprint namespaces ;
14 [ 2dup set-node-in-d set-node-out-d ] keep
16 ] "infer" set-word-prop
17 \ declare { object } { } <effect> "inferred-effect" set-word-prop
19 \ fixnum< { fixnum fixnum } { object } <effect> "inferred-effect" set-word-prop
20 \ fixnum< t "foldable" set-word-prop
22 \ fixnum<= { fixnum fixnum } { object } <effect> "inferred-effect" set-word-prop
23 \ fixnum<= t "foldable" set-word-prop
25 \ fixnum> { fixnum fixnum } { object } <effect> "inferred-effect" set-word-prop
26 \ fixnum> t "foldable" set-word-prop
28 \ fixnum>= { fixnum fixnum } { object } <effect> "inferred-effect" set-word-prop
29 \ fixnum>= t "foldable" set-word-prop
31 \ eq? { object object } { object } <effect> "inferred-effect" set-word-prop
32 \ eq? t "foldable" set-word-prop
34 ! Primitive combinators
35 \ call { object } { } <effect> "inferred-effect" set-word-prop
37 \ call [ pop-literal infer-quot-value ] "infer" set-word-prop
39 \ execute { word } { } <effect> "inferred-effect" set-word-prop
41 \ execute [ pop-literal nip apply-word ] "infer" set-word-prop
43 \ if { object object object } { } <effect> "inferred-effect" set-word-prop
46 2 #drop node, pop-d pop-d swap 2array
47 #if pop-d drop infer-branches
48 ] "infer" set-word-prop
50 \ cond { object } { } <effect> "inferred-effect" set-word-prop
53 pop-literal <reversed>
54 [ no-cond ] swap alist>quot infer-quot-value
55 ] "infer" set-word-prop
57 \ dispatch { fixnum array } { } <effect> "inferred-effect" set-word-prop
60 pop-literal nip [ <value> ] map
61 #dispatch pop-d drop infer-branches
62 ] "infer" set-word-prop
64 ! Non-standard control flow
65 \ throw { object } { } <effect>
66 t over set-effect-terminated?
67 "inferred-effect" set-word-prop
69 ! Stack effects for all primitives
70 \ rehash-string { string } { } <effect> "inferred-effect" set-word-prop
72 \ string>sbuf { string } { sbuf } <effect> "inferred-effect" set-word-prop
74 \ bignum>fixnum { bignum } { fixnum } <effect> "inferred-effect" set-word-prop
75 \ bignum>fixnum t "foldable" set-word-prop
77 \ float>fixnum { float } { fixnum } <effect> "inferred-effect" set-word-prop
78 \ bignum>fixnum t "foldable" set-word-prop
80 \ fixnum>bignum { fixnum } { bignum } <effect> "inferred-effect" set-word-prop
81 \ fixnum>bignum t "foldable" set-word-prop
83 \ float>bignum { float } { bignum } <effect> "inferred-effect" set-word-prop
84 \ float>bignum t "foldable" set-word-prop
86 \ fixnum>float { fixnum } { float } <effect> "inferred-effect" set-word-prop
87 \ fixnum>float t "foldable" set-word-prop
89 \ bignum>float { bignum } { float } <effect> "inferred-effect" set-word-prop
90 \ bignum>float t "foldable" set-word-prop
92 \ (fraction>) { integer integer } { rational } <effect> "inferred-effect" set-word-prop
93 \ (fraction>) t "foldable" set-word-prop
95 \ string>float { string } { float } <effect> "inferred-effect" set-word-prop
96 \ string>float t "foldable" set-word-prop
98 \ float>string { float } { string } <effect> "inferred-effect" set-word-prop
99 \ float>string t "foldable" set-word-prop
101 \ float>bits { real } { integer } <effect> "inferred-effect" set-word-prop
102 \ float>bits t "foldable" set-word-prop
104 \ double>bits { real } { integer } <effect> "inferred-effect" set-word-prop
105 \ double>bits t "foldable" set-word-prop
107 \ bits>float { integer } { float } <effect> "inferred-effect" set-word-prop
108 \ bits>float t "foldable" set-word-prop
110 \ bits>double { integer } { float } <effect> "inferred-effect" set-word-prop
111 \ bits>double t "foldable" set-word-prop
113 \ <complex> { real real } { number } <effect> "inferred-effect" set-word-prop
114 \ <complex> t "foldable" set-word-prop
116 \ fixnum+ { fixnum fixnum } { integer } <effect> "inferred-effect" set-word-prop
117 \ fixnum+ t "foldable" set-word-prop
119 \ fixnum+fast { fixnum fixnum } { fixnum } <effect> "inferred-effect" set-word-prop
120 \ fixnum+fast t "foldable" set-word-prop
122 \ fixnum- { fixnum fixnum } { integer } <effect> "inferred-effect" set-word-prop
123 \ fixnum- t "foldable" set-word-prop
125 \ fixnum-fast { fixnum fixnum } { fixnum } <effect> "inferred-effect" set-word-prop
126 \ fixnum-fast t "foldable" set-word-prop
128 \ fixnum* { fixnum fixnum } { integer } <effect> "inferred-effect" set-word-prop
129 \ fixnum* t "foldable" set-word-prop
131 \ fixnum/i { fixnum fixnum } { integer } <effect> "inferred-effect" set-word-prop
132 \ fixnum/i t "foldable" set-word-prop
134 \ fixnum-mod { fixnum fixnum } { fixnum } <effect> "inferred-effect" set-word-prop
135 \ fixnum-mod t "foldable" set-word-prop
137 \ fixnum/mod { fixnum fixnum } { integer fixnum } <effect> "inferred-effect" set-word-prop
138 \ fixnum/mod t "foldable" set-word-prop
140 \ fixnum-bitand { fixnum fixnum } { fixnum } <effect> "inferred-effect" set-word-prop
141 \ fixnum-bitand t "foldable" set-word-prop
143 \ fixnum-bitor { fixnum fixnum } { fixnum } <effect> "inferred-effect" set-word-prop
144 \ fixnum-bitor t "foldable" set-word-prop
146 \ fixnum-bitxor { fixnum fixnum } { fixnum } <effect> "inferred-effect" set-word-prop
147 \ fixnum-bitxor t "foldable" set-word-prop
149 \ fixnum-bitnot { fixnum } { fixnum } <effect> "inferred-effect" set-word-prop
150 \ fixnum-bitnot t "foldable" set-word-prop
152 \ fixnum-shift { fixnum fixnum } { integer } <effect> "inferred-effect" set-word-prop
153 \ fixnum-shift t "foldable" set-word-prop
155 \ bignum= { bignum bignum } { object } <effect> "inferred-effect" set-word-prop
156 \ bignum= t "foldable" set-word-prop
158 \ bignum+ { bignum bignum } { bignum } <effect> "inferred-effect" set-word-prop
159 \ bignum+ t "foldable" set-word-prop
161 \ bignum- { bignum bignum } { bignum } <effect> "inferred-effect" set-word-prop
162 \ bignum- t "foldable" set-word-prop
164 \ bignum* { bignum bignum } { bignum } <effect> "inferred-effect" set-word-prop
165 \ bignum* t "foldable" set-word-prop
167 \ bignum/i { bignum bignum } { bignum } <effect> "inferred-effect" set-word-prop
168 \ bignum/i t "foldable" set-word-prop
170 \ bignum-mod { bignum bignum } { bignum } <effect> "inferred-effect" set-word-prop
171 \ bignum-mod t "foldable" set-word-prop
173 \ bignum/mod { bignum bignum } { bignum bignum } <effect> "inferred-effect" set-word-prop
174 \ bignum/mod t "foldable" set-word-prop
176 \ bignum-bitand { bignum bignum } { bignum } <effect> "inferred-effect" set-word-prop
177 \ bignum-bitand t "foldable" set-word-prop
179 \ bignum-bitor { bignum bignum } { bignum } <effect> "inferred-effect" set-word-prop
180 \ bignum-bitor t "foldable" set-word-prop
182 \ bignum-bitxor { bignum bignum } { bignum } <effect> "inferred-effect" set-word-prop
183 \ bignum-bitxor t "foldable" set-word-prop
185 \ bignum-bitnot { bignum } { bignum } <effect> "inferred-effect" set-word-prop
186 \ bignum-bitnot t "foldable" set-word-prop
188 \ bignum-shift { bignum bignum } { bignum } <effect> "inferred-effect" set-word-prop
189 \ bignum-shift t "foldable" set-word-prop
191 \ bignum< { bignum bignum } { object } <effect> "inferred-effect" set-word-prop
192 \ bignum< t "foldable" set-word-prop
194 \ bignum<= { bignum bignum } { object } <effect> "inferred-effect" set-word-prop
195 \ bignum<= t "foldable" set-word-prop
197 \ bignum> { bignum bignum } { object } <effect> "inferred-effect" set-word-prop
198 \ bignum> t "foldable" set-word-prop
200 \ bignum>= { bignum bignum } { object } <effect> "inferred-effect" set-word-prop
201 \ bignum>= t "foldable" set-word-prop
203 \ float+ { float float } { float } <effect> "inferred-effect" set-word-prop
204 \ float+ t "foldable" set-word-prop
206 \ float- { float float } { float } <effect> "inferred-effect" set-word-prop
207 \ float- t "foldable" set-word-prop
209 \ float* { float float } { float } <effect> "inferred-effect" set-word-prop
210 \ float* t "foldable" set-word-prop
212 \ float/f { float float } { float } <effect> "inferred-effect" set-word-prop
213 \ float/f t "foldable" set-word-prop
215 \ float< { float float } { object } <effect> "inferred-effect" set-word-prop
216 \ float< t "foldable" set-word-prop
218 \ float-mod { float float } { float } <effect> "inferred-effect" set-word-prop
219 \ float-mod t "foldable" set-word-prop
221 \ float<= { float float } { object } <effect> "inferred-effect" set-word-prop
222 \ float<= t "foldable" set-word-prop
224 \ float> { float float } { object } <effect> "inferred-effect" set-word-prop
225 \ float> t "foldable" set-word-prop
227 \ float>= { float float } { object } <effect> "inferred-effect" set-word-prop
228 \ float>= t "foldable" set-word-prop
230 \ (word) { object object } { word } <effect> "inferred-effect" set-word-prop
232 \ update-xt { word } { } <effect> "inferred-effect" set-word-prop
234 \ word-xt { word } { integer } <effect> "inferred-effect" set-word-prop
236 \ getenv { fixnum } { object } <effect> "inferred-effect" set-word-prop
237 \ setenv { object fixnum } { } <effect> "inferred-effect" set-word-prop
238 \ stat { string } { object object object object } <effect> "inferred-effect" set-word-prop
239 \ (directory) { string } { array } <effect> "inferred-effect" set-word-prop
240 \ data-gc { integer } { } <effect> "inferred-effect" set-word-prop
242 ! code-gc does not declare a stack effect since it might be
243 ! called from a compiled word which becomes unreachable during
244 ! the course of its execution, resulting in a crash
246 \ gc-time { } { integer } <effect> "inferred-effect" set-word-prop
247 \ save-image { string } { } <effect> "inferred-effect" set-word-prop
248 \ exit { integer } { } <effect> "inferred-effect" set-word-prop
249 \ data-room { } { integer integer array } <effect> "inferred-effect" set-word-prop
250 \ code-room { } { integer integer } <effect> "inferred-effect" set-word-prop
251 \ os-env { string } { object } <effect> "inferred-effect" set-word-prop
252 \ millis { } { integer } <effect> "inferred-effect" set-word-prop
254 \ type { object } { fixnum } <effect> "inferred-effect" set-word-prop
255 \ type t "foldable" set-word-prop
257 \ tag { object } { fixnum } <effect> "inferred-effect" set-word-prop
258 \ tag t "foldable" set-word-prop
260 \ cwd { } { string } <effect> "inferred-effect" set-word-prop
261 \ cd { string } { } <effect> "inferred-effect" set-word-prop
263 \ dlopen { string } { dll } <effect> "inferred-effect" set-word-prop
264 \ dlsym { string object } { integer } <effect> "inferred-effect" set-word-prop
265 \ dlclose { dll } { } <effect> "inferred-effect" set-word-prop
267 \ <byte-array> { integer } { byte-array } <effect> "inferred-effect" set-word-prop
269 \ <displaced-alien> { integer c-ptr } { c-ptr } <effect> "inferred-effect" set-word-prop
271 \ alien-signed-cell { c-ptr integer } { integer } <effect> "inferred-effect" set-word-prop
273 \ set-alien-signed-cell { integer c-ptr integer } { } <effect> "inferred-effect" set-word-prop
274 \ alien-unsigned-cell { c-ptr integer } { integer } <effect> "inferred-effect" set-word-prop
276 \ set-alien-unsigned-cell { integer c-ptr integer } { } <effect> "inferred-effect" set-word-prop
277 \ alien-signed-8 { c-ptr integer } { integer } <effect> "inferred-effect" set-word-prop
279 \ set-alien-signed-8 { integer c-ptr integer } { } <effect> "inferred-effect" set-word-prop
280 \ alien-unsigned-8 { c-ptr integer } { integer } <effect> "inferred-effect" set-word-prop
282 \ set-alien-unsigned-8 { integer c-ptr integer } { } <effect> "inferred-effect" set-word-prop
283 \ alien-signed-4 { c-ptr integer } { integer } <effect> "inferred-effect" set-word-prop
285 \ set-alien-signed-4 { integer c-ptr integer } { } <effect> "inferred-effect" set-word-prop
286 \ alien-unsigned-4 { c-ptr integer } { integer } <effect> "inferred-effect" set-word-prop
288 \ set-alien-unsigned-4 { integer c-ptr integer } { } <effect> "inferred-effect" set-word-prop
289 \ alien-signed-2 { c-ptr integer } { integer } <effect> "inferred-effect" set-word-prop
291 \ set-alien-signed-2 { integer c-ptr integer } { } <effect> "inferred-effect" set-word-prop
292 \ alien-unsigned-2 { c-ptr integer } { integer } <effect> "inferred-effect" set-word-prop
294 \ set-alien-unsigned-2 { integer c-ptr integer } { } <effect> "inferred-effect" set-word-prop
295 \ alien-signed-1 { c-ptr integer } { integer } <effect> "inferred-effect" set-word-prop
297 \ set-alien-signed-1 { integer c-ptr integer } { } <effect> "inferred-effect" set-word-prop
298 \ alien-unsigned-1 { c-ptr integer } { integer } <effect> "inferred-effect" set-word-prop
300 \ set-alien-unsigned-1 { integer c-ptr integer } { } <effect> "inferred-effect" set-word-prop
301 \ alien-float { c-ptr integer } { float } <effect> "inferred-effect" set-word-prop
303 \ set-alien-float { float c-ptr integer } { } <effect> "inferred-effect" set-word-prop
304 \ alien-float { c-ptr integer } { float } <effect> "inferred-effect" set-word-prop
306 \ set-alien-double { float c-ptr integer } { } <effect> "inferred-effect" set-word-prop
307 \ alien-double { c-ptr integer } { float } <effect> "inferred-effect" set-word-prop
309 \ alien>char-string { c-ptr } { string } <effect> "inferred-effect" set-word-prop
311 \ string>char-alien { string } { byte-array } <effect> "inferred-effect" set-word-prop
313 \ alien>u16-string { c-ptr } { string } <effect> "inferred-effect" set-word-prop
315 \ string>u16-alien { string } { byte-array } <effect> "inferred-effect" set-word-prop
317 \ string>memory { string integer } { } <effect> "inferred-effect" set-word-prop
318 \ memory>string { integer integer } { string } <effect> "inferred-effect" set-word-prop
320 \ alien-address { alien } { integer } <effect> "inferred-effect" set-word-prop
322 \ slot { object fixnum } { object } <effect> "inferred-effect" set-word-prop
324 \ set-slot { object object fixnum } { } <effect> "inferred-effect" set-word-prop
326 \ char-slot { fixnum object } { fixnum } <effect> "inferred-effect" set-word-prop
328 \ set-char-slot { fixnum fixnum object } { } <effect> "inferred-effect" set-word-prop
329 \ resize-array { integer array } { array } <effect> "inferred-effect" set-word-prop
330 \ resize-string { integer string } { string } <effect> "inferred-effect" set-word-prop
332 \ (hashtable) { } { hashtable } <effect> "inferred-effect" set-word-prop
334 \ <array> { integer object } { array } <effect> "inferred-effect" set-word-prop
336 \ begin-scan { } { } <effect> "inferred-effect" set-word-prop
337 \ next-object { } { object } <effect> "inferred-effect" set-word-prop
338 \ end-scan { } { } <effect> "inferred-effect" set-word-prop
340 \ size { object } { fixnum } <effect> "inferred-effect" set-word-prop
342 \ die { } { } <effect> "inferred-effect" set-word-prop
343 \ fopen { string string } { alien } <effect> "inferred-effect" set-word-prop
344 \ fgetc { alien } { object } <effect> "inferred-effect" set-word-prop
345 \ fwrite { string alien } { } <effect> "inferred-effect" set-word-prop
346 \ fflush { alien } { } <effect> "inferred-effect" set-word-prop
347 \ fclose { alien } { } <effect> "inferred-effect" set-word-prop
348 \ expired? { object } { object } <effect> "inferred-effect" set-word-prop
350 \ <wrapper> { object } { wrapper } <effect> "inferred-effect" set-word-prop
351 \ <wrapper> t "foldable" set-word-prop
353 \ (clone) { object } { object } <effect> "inferred-effect" set-word-prop
355 \ become { object fixnum } { object } <effect> "inferred-effect" set-word-prop
357 \ array>vector { array } { vector } <effect> "inferred-effect" set-word-prop
359 \ finalize-compile { array } { } <effect> "inferred-effect" set-word-prop
361 \ <string> { integer integer } { string } <effect> "inferred-effect" set-word-prop
363 \ <quotation> { integer } { quotation } <effect> "inferred-effect" set-word-prop
365 \ xt-map { } { array } <effect> "inferred-effect" set-word-prop
367 ! Dynamic scope inference
368 : if-tos-literal ( quot -- )
369 peek-d dup value? [ value-literal swap call ] [ 2drop ] if ;
372 \ >n [ H{ } clone push-n ] "infer-vars" set-word-prop
374 \ >n { object } { } <effect> "inferred-effect" set-word-prop
380 <too-many-n>> inference-error
385 \ n> [ apply-n> ] "infer-vars" set-word-prop
387 \ n> { } { object } <effect> "inferred-effect" set-word-prop
389 \ ndrop [ apply-n> ] "infer-vars" set-word-prop
391 \ ndrop { } { } <effect> "inferred-effect" set-word-prop
394 [ apply-var-read ] if-tos-literal
395 ] "infer-vars" set-word-prop
397 \ get { object } { object } <effect> "inferred-effect" set-word-prop
400 [ apply-var-write ] if-tos-literal
401 ] "infer-vars" set-word-prop
403 \ set { object object } { } <effect> "inferred-effect" set-word-prop
406 [ apply-global-read ]
408 ] "infer-vars" set-word-prop
410 \ get-global { object } { object } <effect> "inferred-effect" set-word-prop
413 [ apply-global-write ]
415 ] "infer-vars" set-word-prop
417 \ set-global { object object } { } <effect> "inferred-effect" set-word-prop