1 ! Copyright (C) 2004, 2009 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: fry arrays generic io io.streams.string kernel math namespaces
4 parser sequences strings vectors words quotations effects classes
5 continuations assocs combinators compiler.errors accessors math.order
6 definitions sets hints macros stack-checker.state
7 stack-checker.visitor stack-checker.errors stack-checker.values
8 stack-checker.recursive-state stack-checker.dependencies summary ;
9 FROM: namespaces => set ;
10 IN: stack-checker.backend
12 : push-d ( obj -- ) meta-d push ;
14 : introduce-values ( values -- )
15 [ [ [ input-parameter ] dip set-known ] each ]
16 [ length input-count +@ ]
21 meta-d [ <value> dup 1array introduce-values ] [ pop ] if-empty ;
23 : peek-d ( -- obj ) pop-d dup push-d ;
25 : make-values ( n -- values )
26 [ <value> ] replicate ;
28 : ensure-d ( n -- values )
29 meta-d 2dup length > [
31 [ nip >array ] [ length - make-values ] [ nip delete-all ] 2tri
32 [ introduce-values ] [ meta-d push-all ] bi
36 : shorten-by ( n seq -- )
37 [ length swap - ] keep shorten ; inline
39 : consume-d ( n -- seq )
40 [ ensure-d ] [ meta-d shorten-by ] bi ;
42 : output-d ( values -- ) meta-d push-all ;
44 : produce-d ( n -- values )
45 make-values dup meta-d push-all ;
47 : push-r ( obj -- ) meta-r push ;
51 [ too-many-r> ] [ pop ] if ;
53 : consume-r ( n -- seq )
56 [ swap tail* ] [ shorten-by ] 2bi ;
58 : output-r ( seq -- ) meta-r push-all ;
60 : push-literal ( obj -- )
63 : pop-literal ( -- rstate obj )
67 [ literal [ recursion>> ] [ value>> ] bi ] bi
68 ] [ pop recursive-state get swap ] if-empty ;
70 : literals-available? ( n -- literals ? )
71 literals get 2dup length <=
72 [ [ swap tail* ] [ shorten-by ] 2bi t ] [ 2drop f f ] if ;
74 GENERIC: apply-object ( obj -- )
76 M: wrapper apply-object
78 [ dup word? [ depends-on-effect ] [ drop ] if ]
82 M: object apply-object push-literal ;
85 terminated? on meta-d clone meta-r clone #terminate, ;
88 meta-r empty? [ too-many->r ] unless ;
90 : infer-quot-here ( quot -- )
92 V{ } clone \ meta-r set
93 [ apply-object terminated? get not ] all?
94 [ commit-literals check->r ] [ literals get delete-all ] if
97 : infer-quot ( quot rstate -- )
101 ] dip recursive-state set ;
103 : time-bomb ( error -- )
104 '[ _ throw ] infer-quot-here ;
106 ERROR: bad-call obj ;
109 drop "call must be given a callable" ;
111 : infer-literal-quot ( literal -- )
112 dup recursive-quotation? [
113 value>> recursive-quotation-error
115 dup value>> callable? [
117 [ [ recursion>> ] keep add-local-quotation ]
120 value>> \ bad-call boa time-bomb
125 consume-d dup copy-values [ nip output-r ] [ #>r, ] 2bi ;
128 consume-r dup copy-values [ nip output-d ] [ #r>, ] 2bi ;
130 : consume/produce ( effect quot: ( inputs outputs -- ) -- )
131 '[ [ in>> length consume-d ] [ out>> length produce-d ] bi @ ]
132 [ terminated?>> [ terminate ] when ]
135 : apply-word/effect ( word effect -- )
136 swap '[ _ #call, ] consume/produce ;
139 meta-d clone #return, ;
141 : required-stack-effect ( word -- effect )
142 dup stack-effect [ ] [ missing-effect ] ?if ;
144 : infer-word ( word -- )
146 { [ dup macro? ] [ do-not-compile ] }
147 { [ dup "no-compile" word-prop ] [ do-not-compile ] }
148 [ dup required-stack-effect apply-word/effect ]
151 : with-infer ( quot -- effect visitor )
160 ] with-scope ; inline