factor/basis/stack-checker/branches/branches.factor

123 lines
3.2 KiB
Factor
Raw Normal View History

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
stack-checker.values stack-checker.recursive-state ;
2008-07-20 05:24:37 -04:00
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
2008-09-10 23:11:40 -04:00
'[ _ +bottom+ pad-left ] map
2008-08-10 00:00:27 -04:00
] unless ;
2008-07-28 18:56:15 -04:00
: phi-inputs ( max-d-in pairs -- newseq )
dup empty? [ nip ] [
2008-09-10 23:11:40 -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 23:11:40 -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 )
2008-12-04 07:02:49 -05:00
[ d-in branch-variable ] [ \ meta-d active-variable ] bi
2008-07-20 05:24:37 -04:00
unify-branches
2008-12-04 07:02:49 -05:00
[ d-in set ] [ ] [ dup >vector \ meta-d set ] tri* ;
2008-07-20 05:24:37 -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 ]
[ [ 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 ( -- )
2008-12-04 07:02:49 -05:00
\ meta-d [ clone ] change
literals [ clone ] change
2008-08-18 21:08:45 -04:00
d-in [ ] change ;
2008-12-04 07:02:49 -05:00
GENERIC: infer-branch ( literal -- namespace )
M: literal infer-branch
2008-07-20 05:24:37 -04:00
[
copy-inference
nest-visitor
2008-10-12 17:46:59 -04:00
[ value>> quotation set ] [ infer-literal-quot ] bi
2008-12-04 07:02:49 -05:00
] H{ } make-assoc ;
M: callable infer-branch
[
copy-inference
nest-visitor
[ quotation set ] [ infer-quot-here ] bi
] H{ } make-assoc ;
2008-07-20 05:24:37 -04:00
2008-10-12 17:46:59 -04:00
: infer-branches ( branches -- input children data )
[ pop-d ] dip
[ infer-branch ] map
2008-10-08 04:51:44 -04:00
[ stack-visitor branch-variable ] keep ; inline
2008-07-20 05:24:37 -04:00
: (infer-if) ( branches -- )
2008-10-12 17:46:59 -04:00
infer-branches
2008-10-08 04:51:44 -04:00
[ first2 #if, ] dip compute-phi-function ;
2008-07-20 05:24:37 -04:00
: infer-if ( -- )
2008-12-04 07:02:49 -05:00
2 literals-available? [
(infer-if)
] [
2008-12-04 07:02:49 -05:00
drop 2 consume-d
dup [ known [ curried? ] [ composed? ] bi or ] contains? [
output-d
[ rot [ drop call ] [ nip call ] if ]
infer-quot-here
] [
[ #drop, ] [ [ literal ] map (infer-if) ] bi
] if
] if ;
: infer-dispatch ( -- )
2008-12-04 07:02:49 -05:00
pop-literal nip infer-branches
2008-10-08 04:51:44 -04:00
[ #dispatch, ] dip compute-phi-function ;