2008-07-20 05:24:37 -04:00
|
|
|
! Copyright (C) 2008 Slava Pestov.
|
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
|
|
|
USING: fry vectors sequences assocs math accessors kernel
|
|
|
|
combinators quotations namespaces stack-checker.state
|
|
|
|
stack-checker.backend stack-checker.errors stack-checker.visitor
|
|
|
|
;
|
|
|
|
IN: stack-checker.branches
|
|
|
|
|
2008-07-28 18:56:15 -04:00
|
|
|
: balanced? ( pairs -- ? )
|
2008-07-25 03:07:45 -04:00
|
|
|
[ second ] filter [ first2 length - ] map all-equal? ;
|
2008-07-20 05:24:37 -04:00
|
|
|
|
2008-08-10 00:00:27 -04:00
|
|
|
SYMBOL: +bottom+
|
|
|
|
|
2008-07-28 18:56:15 -04:00
|
|
|
: unify-inputs ( max-d-in d-in meta-d -- new-meta-d )
|
2008-08-10 00:00:27 -04:00
|
|
|
dup [ [ - +bottom+ <repetition> ] dip append ] [ 3drop f ] if ;
|
2008-07-28 18:56:15 -04:00
|
|
|
|
2008-08-10 00:00:27 -04:00
|
|
|
: pad-with-bottom ( seq -- newseq )
|
|
|
|
dup empty? [
|
|
|
|
dup [ length ] map supremum
|
|
|
|
'[ , +bottom+ pad-left ] map
|
|
|
|
] unless ;
|
2008-07-30 04:38:10 -04:00
|
|
|
|
2008-07-28 18:56:15 -04:00
|
|
|
: phi-inputs ( max-d-in pairs -- newseq )
|
|
|
|
dup empty? [ nip ] [
|
2008-09-10 21:07:00 -04:00
|
|
|
swap '[ [ , ] dip first2 unify-inputs ] map
|
2008-08-10 00:00:27 -04:00
|
|
|
pad-with-bottom
|
2008-07-28 18:56:15 -04:00
|
|
|
] if ;
|
2008-07-20 05:24:37 -04:00
|
|
|
|
2008-08-10 00:00:27 -04:00
|
|
|
: remove-bottom ( seq -- seq' )
|
|
|
|
+bottom+ swap remove ;
|
|
|
|
|
2008-07-20 05:24:37 -04:00
|
|
|
: unify-values ( values -- phi-out )
|
2008-08-10 00:00:27 -04:00
|
|
|
remove-bottom
|
2008-09-06 20:13:59 -04:00
|
|
|
[ <value> ] [
|
2008-07-28 18:56:15 -04:00
|
|
|
[ known ] map dup all-eq?
|
|
|
|
[ first make-known ] [ drop <value> ] if
|
2008-09-06 20:13:59 -04:00
|
|
|
] if-empty ;
|
2008-07-20 05:24:37 -04:00
|
|
|
|
|
|
|
: phi-outputs ( phi-in -- stack )
|
2008-08-14 00:52:49 -04:00
|
|
|
flip [ unify-values ] map ;
|
2008-07-20 05:24:37 -04:00
|
|
|
|
|
|
|
SYMBOL: quotations
|
|
|
|
|
|
|
|
: unify-branches ( ins stacks -- in phi-in phi-out )
|
2008-09-06 20:13:59 -04:00
|
|
|
zip [ 0 { } { } ] [
|
2008-07-28 18:56:15 -04:00
|
|
|
[ keys supremum ] [ ] [ balanced? ] tri
|
|
|
|
[ dupd phi-inputs dup phi-outputs ]
|
2008-07-20 05:24:37 -04:00
|
|
|
[ quotations get unbalanced-branches-error ]
|
|
|
|
if
|
2008-09-06 20:13:59 -04:00
|
|
|
] if-empty ;
|
2008-07-20 05:24:37 -04:00
|
|
|
|
|
|
|
: branch-variable ( seq symbol -- seq )
|
2008-09-10 21:07:00 -04:00
|
|
|
'[ [ , ] dip at ] map ;
|
2008-07-20 05:24:37 -04:00
|
|
|
|
|
|
|
: active-variable ( seq symbol -- seq )
|
|
|
|
[ [ terminated? over at [ drop f ] when ] map ] dip
|
|
|
|
branch-variable ;
|
|
|
|
|
|
|
|
: datastack-phi ( seq -- phi-in phi-out )
|
|
|
|
[ d-in branch-variable ] [ meta-d active-variable ] bi
|
|
|
|
unify-branches
|
|
|
|
[ d-in set ] [ ] [ dup >vector meta-d set ] tri* ;
|
|
|
|
|
2008-08-01 21:04:36 -04:00
|
|
|
: terminated-phi ( seq -- terminated )
|
|
|
|
terminated? branch-variable ;
|
|
|
|
|
2008-08-19 18:11:33 -04:00
|
|
|
: terminate-branches ( seq -- )
|
|
|
|
[ terminated? swap at ] all? [ terminate ] when ;
|
|
|
|
|
2008-07-20 05:24:37 -04:00
|
|
|
: compute-phi-function ( seq -- )
|
|
|
|
[ quotation active-variable sift quotations set ]
|
2008-08-18 21:49:03 -04:00
|
|
|
[ [ datastack-phi ] [ terminated-phi ] bi #phi, ]
|
2008-08-19 18:11:33 -04:00
|
|
|
[ terminate-branches ]
|
2008-07-20 05:24:37 -04:00
|
|
|
tri ;
|
|
|
|
|
2008-08-18 21:08:45 -04:00
|
|
|
: copy-inference ( -- )
|
|
|
|
meta-d [ clone ] change
|
|
|
|
V{ } clone meta-r set
|
|
|
|
d-in [ ] change ;
|
|
|
|
|
2008-07-20 05:24:37 -04:00
|
|
|
: infer-branch ( literal -- namespace )
|
|
|
|
[
|
|
|
|
copy-inference
|
|
|
|
nest-visitor
|
|
|
|
[ value>> quotation set ] [ infer-literal-quot ] bi
|
2008-08-18 21:08:45 -04:00
|
|
|
check->r
|
2008-07-20 05:24:37 -04:00
|
|
|
] H{ } make-assoc ; inline
|
|
|
|
|
|
|
|
: infer-branches ( branches -- input children data )
|
|
|
|
[ pop-d ] dip
|
|
|
|
[ infer-branch ] map
|
2008-07-24 00:50:21 -04:00
|
|
|
[ stack-visitor branch-variable ] keep ;
|
2008-07-20 05:24:37 -04:00
|
|
|
|
2008-07-23 01:17:08 -04:00
|
|
|
: (infer-if) ( branches -- )
|
2008-07-20 05:24:37 -04:00
|
|
|
infer-branches [ first2 #if, ] dip compute-phi-function ;
|
|
|
|
|
2008-07-23 01:17:08 -04:00
|
|
|
: infer-if ( -- )
|
|
|
|
2 consume-d
|
2008-07-28 18:56:15 -04:00
|
|
|
dup [ known [ curried? ] [ composed? ] bi or ] contains? [
|
2008-07-23 01:17:08 -04:00
|
|
|
output-d
|
|
|
|
[ rot [ drop call ] [ nip call ] if ]
|
|
|
|
recursive-state get infer-quot
|
|
|
|
] [
|
|
|
|
[ #drop, ] [ [ literal ] map (infer-if) ] bi
|
|
|
|
] if ;
|
|
|
|
|
|
|
|
: infer-dispatch ( -- )
|
|
|
|
pop-literal nip [ <literal> ] map
|
2008-07-20 05:24:37 -04:00
|
|
|
infer-branches [ #dispatch, ] dip compute-phi-function ;
|