1 ! Copyright (C) 2008 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: fry vectors sequences assocs math accessors kernel
4 combinators quotations namespaces stack-checker.state
5 stack-checker.backend stack-checker.errors stack-checker.visitor
7 IN: stack-checker.branches
9 : balanced? ( pairs -- ? )
10 [ second ] filter [ first2 length - ] map all-equal? ;
14 : unify-inputs ( max-d-in d-in meta-d -- new-meta-d )
15 dup [ [ - +bottom+ <repetition> ] dip append ] [ 3drop f ] if ;
17 : pad-with-bottom ( seq -- newseq )
19 dup [ length ] map supremum
20 '[ , +bottom+ pad-left ] map
23 : phi-inputs ( max-d-in pairs -- newseq )
25 swap '[ [ , ] dip first2 unify-inputs ] map
29 : remove-bottom ( seq -- seq' )
30 +bottom+ swap remove ;
32 : unify-values ( values -- phi-out )
35 [ known ] map dup all-eq?
36 [ first make-known ] [ drop <value> ] if
39 : phi-outputs ( phi-in -- stack )
40 flip [ unify-values ] map ;
44 : unify-branches ( ins stacks -- in phi-in phi-out )
46 [ keys supremum ] [ ] [ balanced? ] tri
47 [ dupd phi-inputs dup phi-outputs ]
48 [ quotations get unbalanced-branches-error ]
52 : branch-variable ( seq symbol -- seq )
53 '[ [ , ] dip at ] map ;
55 : active-variable ( seq symbol -- seq )
56 [ [ terminated? over at [ drop f ] when ] map ] dip
59 : datastack-phi ( seq -- phi-in phi-out )
60 [ d-in branch-variable ] [ meta-d active-variable ] bi
62 [ d-in set ] [ ] [ dup >vector meta-d set ] tri* ;
64 : terminated-phi ( seq -- terminated )
65 terminated? branch-variable ;
67 : terminate-branches ( seq -- )
68 [ terminated? swap at ] all? [ terminate ] when ;
70 : compute-phi-function ( seq -- )
71 [ quotation active-variable sift quotations set ]
72 [ [ datastack-phi ] [ terminated-phi ] bi #phi, ]
73 [ terminate-branches ]
76 : copy-inference ( -- )
77 meta-d [ clone ] change
81 : infer-branch ( literal -- namespace )
85 [ value>> quotation set ] [ infer-literal-quot ] bi
87 ] H{ } make-assoc ; inline
89 : infer-branches ( branches -- input children data )
92 [ stack-visitor branch-variable ] keep ;
94 : (infer-if) ( branches -- )
95 infer-branches [ first2 #if, ] dip compute-phi-function ;
99 dup [ known [ curried? ] [ composed? ] bi or ] contains? [
101 [ rot [ drop call ] [ nip call ] if ]
102 recursive-state get infer-quot
104 [ #drop, ] [ [ literal ] map (infer-if) ] bi
107 : infer-dispatch ( -- )
108 pop-literal nip [ <literal> ] map
109 infer-branches [ #dispatch, ] dip compute-phi-function ;