1 ! Copyright (C) 2004, 2006 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
4 USING: arrays errors generic io kernel
5 math namespaces parser prettyprint sequences strings
8 TUPLE: inference-error rstate major? ;
10 C: inference-error ( msg rstate important? -- error )
11 [ set-inference-error-major? ] keep
12 [ set-inference-error-rstate ] keep
13 [ set-delegate ] keep ;
15 : inference-error ( msg -- * )
16 recursive-state get t <inference-error> throw ;
18 : inference-warning ( msg -- * )
19 recursive-state get f <inference-error> throw ;
21 TUPLE: literal-expected ;
23 M: object value-literal
24 <literal-expected> inference-warning ;
26 : pop-literal ( -- rstate obj )
28 pop-d dup value-recursion swap value-literal ;
30 : value-vector ( n -- vector ) [ drop <computed> ] map >vector ;
32 : add-inputs ( seq stack -- n stack )
33 tuck [ length ] 2apply - dup 0 >
34 [ dup value-vector [ rot nappend ] keep ]
37 : ensure-values ( seq -- )
38 meta-d [ add-inputs ] change d-in [ + ] change ;
42 : current-effect ( -- effect )
43 d-in get meta-d get length <effect>
44 terminated? get over set-effect-terminated? ;
48 : init-inference ( recursive-state -- )
53 empty-vars inferred-vars set
59 GENERIC: apply-object ( obj -- )
61 : apply-literal ( obj -- )
64 1 d-tail swap set-node-out-d ;
66 M: object apply-object apply-literal ;
68 M: wrapper apply-object wrapped apply-literal ;
70 GENERIC: apply-word ( word -- )
72 M: word apply-object apply-word ;
75 terminated? on #terminate node, ;
77 GENERIC: infer-quot ( quot -- )
79 M: f infer-quot drop ;
81 M: quotation infer-quot
82 [ apply-object terminated? get not ] all? drop ;
84 : infer-quot-value ( rstate quot -- )
85 recursive-state get >r swap recursive-state set
86 infer-quot r> recursive-state set ;
92 <too-many->r> inference-error
99 <too-many-r>> inference-error
103 recorded get [ custom-infer? not ] subset [
105 f "inferred-vars" set-word-prop
106 f "inferred-effect" set-word-prop
109 : with-infer ( quot -- )
112 { } recursive-state set
113 V{ } clone recorded set
123 : infer ( quot -- effect infer-vars )
124 [ infer-quot inferred-vars get current-effect ] with-infer ;
126 : vars. ( seq str -- )
127 over empty? [ 2drop ] [ print [ . ] each ] if ;
131 "* Stack effect:" print effect>string print
132 dup inferred-vars-reads "* Reads free variables:" vars.
133 dup inferred-vars-writes "* Writes free variables:" vars.
134 dup inferred-vars-reads-globals "* Reads global variables:" vars.
135 inferred-vars-writes-globals "* Writes global variables:" vars. ;
137 : (dataflow) ( quot -- dataflow )
138 infer-quot f #return node, dataflow-graph get ;
140 : dataflow ( quot -- dataflow )
141 [ (dataflow) ] with-infer ;
143 : dataflow-with ( quot stack -- effect )
144 [ meta-d set (dataflow) ] with-infer ;