work on inferencer, and vector-2map combinator
parent
d7db4d1ccd
commit
df39f78f6d
|
|
@ -37,6 +37,7 @@ USE: vectors
|
|||
: dupd ( x y -- x x y ) >r dup r> ;
|
||||
: swapd ( x y z -- y x z ) >r swap r> ;
|
||||
: transp ( x y z -- z y x ) swap rot ;
|
||||
: 2swap ( x y z t -- z t x y ) rot >r rot r> ;
|
||||
|
||||
: clear ( -- )
|
||||
#! Clear the datastack. For interactive use only; invoking
|
||||
|
|
|
|||
|
|
@ -32,9 +32,6 @@ USE: lists
|
|||
USE: math
|
||||
USE: stack
|
||||
|
||||
: 2vector-nth ( n vec vec -- obj obj )
|
||||
>r over >r vector-nth r> r> vector-nth ;
|
||||
|
||||
: ?vector= ( n vec vec -- ? )
|
||||
#! Reached end?
|
||||
drop vector-length = ;
|
||||
|
|
|
|||
|
|
@ -5,9 +5,17 @@ USE: math
|
|||
USE: stack
|
||||
USE: combinators
|
||||
USE: vectors
|
||||
USE: kernel
|
||||
|
||||
[ 6 ] [ 6 gensym-vector vector-length ] unit-test
|
||||
|
||||
[ t ] [
|
||||
{ 1 2 } { 1 2 3 }
|
||||
unify-lengths swap vector-length swap vector-length =
|
||||
] unit-test
|
||||
|
||||
[ [ sq ] ] [ [ sq ] [ sq ] unify-result ] unit-test
|
||||
|
||||
[ [ 0 | 2 ] ] [ [ 2 "Hello" ] infer ] unit-test
|
||||
[ [ 1 | 2 ] ] [ [ dup ] infer ] unit-test
|
||||
|
||||
|
|
@ -41,3 +49,11 @@ USE: vectors
|
|||
|
||||
[ [ 1 | 0 ] ] [ [ [ drop ] when* ] infer ] unit-test
|
||||
[ [ 1 | 1 ] ] [ [ [ { { [ ] } } ] unless* ] infer ] unit-test
|
||||
|
||||
[ [ 0 | 1 ] ] [
|
||||
[ [ 2 2 fixnum+ ] dup [ ] when call ] infer
|
||||
] unit-test
|
||||
|
||||
[
|
||||
[ [ 2 2 fixnum+ ] ] [ [ 2 2 fixnum* ] ] ifte call
|
||||
] unit-test-fails
|
||||
|
|
|
|||
|
|
@ -35,3 +35,11 @@ USE: vectors
|
|||
|
||||
[ { 1 2 3 4 5 6 } ]
|
||||
[ { 1 2 3 } vector-clone dup { 4 5 6 } vector-append ] unit-test
|
||||
|
||||
[ { 6 8 10 12 } ]
|
||||
[ { 1 2 3 4 } { 5 6 7 8 } [ + ] vector-2map ]
|
||||
unit-test
|
||||
|
||||
[ { [ 1 | 5 ] [ 2 | 6 ] [ 3 | 7 ] [ 4 | 8 ] } ]
|
||||
[ { 1 2 3 4 } { 5 6 7 8 } vector-zip ]
|
||||
unit-test
|
||||
|
|
|
|||
|
|
@ -53,19 +53,19 @@ SYMBOL: r-in
|
|||
|
||||
: inputs ( count stack -- stack )
|
||||
#! Add this many inputs to the given stack.
|
||||
>r dup d-in +@ gensym-vector dup r> vector-append ;
|
||||
>r gensym-vector dup r> vector-append ;
|
||||
|
||||
: ensure ( count stack -- stack )
|
||||
: ensure ( count stack -- count stack )
|
||||
#! Ensure stack has this many elements.
|
||||
2dup vector-length > [
|
||||
[ vector-length - ] keep inputs
|
||||
[ vector-length - dup ] keep inputs
|
||||
] [
|
||||
nip
|
||||
>r drop 0 r>
|
||||
] ifte ;
|
||||
|
||||
: ensure-d ( count -- )
|
||||
#! Ensure count of unknown results are on the stack.
|
||||
meta-d get ensure meta-d set ;
|
||||
meta-d get ensure meta-d set d-in +@ ;
|
||||
|
||||
: consume-d ( count -- )
|
||||
#! Remove count of elements.
|
||||
|
|
@ -76,6 +76,10 @@ SYMBOL: r-in
|
|||
[ gensym push-d ] times ;
|
||||
|
||||
: standard-effect ( word [ in | out ] -- )
|
||||
#! If a word does not have special inference behavior, we
|
||||
#! either execute the word in the meta interpreter (if it is
|
||||
#! side-effect-free and all parameters are literal), or
|
||||
#! simply apply its stack effect to the meta-interpreter.
|
||||
over "meta-infer" word-property [
|
||||
drop host-word
|
||||
] [
|
||||
|
|
@ -118,35 +122,61 @@ DEFER: (infer)
|
|||
d-in get meta-d get vector-length cons ;
|
||||
|
||||
: (infer) ( quot -- )
|
||||
#! Recursive calls to this word are made for nested
|
||||
#! quotations.
|
||||
[ dup word? [ apply-word ] [ push-d ] ifte ] each ;
|
||||
|
||||
: infer ( quot -- [ in | out ] )
|
||||
#! Stack effect of a quotation.
|
||||
[ init-inference (infer) effect ] with-scope ;
|
||||
|
||||
: infer-branch ( quot -- [ in-d | datastack ] )
|
||||
: infer-branch ( quot -- [ in-d | datastack ] )
|
||||
#! Infer the quotation's effect, restoring the meta
|
||||
#! interpreter state afterwards.
|
||||
[
|
||||
copy-interpreter (infer)
|
||||
d-in get meta-d get cons
|
||||
] with-scope ;
|
||||
|
||||
: difference ( [ in | stack ] -- diff )
|
||||
#! Stack height difference of infer-branch return value.
|
||||
uncons vector-length - ;
|
||||
|
||||
: balanced? ( [ in | stack ] [ in | stack ] -- ? )
|
||||
#! Check if two stack effects preserve stack height.
|
||||
difference swap difference = ;
|
||||
|
||||
: max-vector-length ( vector vector -- length )
|
||||
swap vector-length swap vector-length max ;
|
||||
|
||||
: unify-lengths ( stack stack -- stack stack )
|
||||
#! If one vector is shorter, pad it with unknown results at
|
||||
#! the bottom.
|
||||
2dup max-vector-length
|
||||
tuck swap ensure nip >r swap ensure nip r> ;
|
||||
|
||||
: unify-result ( obj obj -- obj )
|
||||
#! Replace values with unknown result if they differ,
|
||||
#! otherwise retain them.
|
||||
2dup = [ drop ] [ 2drop gensym ] ifte ;
|
||||
|
||||
: unify-stacks ( stack stack -- stack )
|
||||
swap vector-length swap vector-length max gensym-vector ;
|
||||
#! Replace differing literals in stacks with unknown
|
||||
#! results.
|
||||
unify-lengths [ unify-result ] vector-2map ;
|
||||
|
||||
: unify ( [ in | stack ] [ in | stack ] -- )
|
||||
#! Unify meta-interpreter state from two branches.
|
||||
2dup balanced? [
|
||||
2dup 2car max d-in set 2cdr unify-stacks meta-d set
|
||||
2dup
|
||||
2car max d-in set
|
||||
2cdr unify-stacks meta-d set
|
||||
] [
|
||||
"Unbalanced ifte branches" throw
|
||||
] ifte ;
|
||||
|
||||
: infer-ifte ( -- )
|
||||
#! Infer effects for both branches, unify.
|
||||
pop-d pop-d pop-d drop ( condition )
|
||||
>r infer-branch r> infer-branch unify ;
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
IN: vectors
|
||||
USE: combinators
|
||||
USE: kernel
|
||||
USE: lists
|
||||
USE: logic
|
||||
USE: math
|
||||
USE: stack
|
||||
|
|
@ -57,3 +58,26 @@ USE: stack
|
|||
: vector-append ( v1 v2 -- )
|
||||
#! Destructively append v2 to v1.
|
||||
[ over vector-push ] vector-each drop ;
|
||||
|
||||
: vector-collect ( n quot -- accum )
|
||||
#! Execute the quotation n times, passing the loop counter
|
||||
#! the quotation, and collect results in a new vector.
|
||||
over <vector> rot [
|
||||
-rot 2dup >r >r slip vector-push r> r>
|
||||
] times* nip ;
|
||||
|
||||
: vector-zip ( v1 v2 -- v )
|
||||
#! Make a new vector with each pair of elements from the
|
||||
#! first two in a pair.
|
||||
over vector-length [
|
||||
pick pick 2vector-nth cons
|
||||
] vector-collect nip nip ;
|
||||
|
||||
: vector-2map ( v1 v2 quot -- v )
|
||||
#! Apply a quotation with stack effect ( obj obj -- obj ) to
|
||||
#! each pair of elements from v1 and v2, collecting them
|
||||
#! into a new list. Behavior is undefined if vector lengths
|
||||
#! differ.
|
||||
-rot vector-zip [
|
||||
swap dup >r >r uncons r> call r> swap
|
||||
] vector-map nip ;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,9 @@ USE: lists
|
|||
USE: math
|
||||
USE: stack
|
||||
|
||||
: 2vector-nth ( n vec vec -- obj obj )
|
||||
>r over >r vector-nth r> r> vector-nth ;
|
||||
|
||||
: empty-vector ( len -- vec )
|
||||
#! Creates a vector with 'len' elements set to f. Unlike
|
||||
#! <vector>, which gives an empty vector with a certain
|
||||
|
|
|
|||
Loading…
Reference in New Issue