: unswons ( [ car | cdr ] -- cdr car )
#! Push both the head and tail of a list.
dup cdr swap car ; inline
+
+: 2car ( cons cons -- car car )
+ swap car swap car ;
+
+: 2cdr ( cons cons -- car car )
+ swap cdr swap cdr ;
: count ( n -- [ 0 ... n-1 ] )
[ ] (count) ;
-: car= swap car swap car = ;
-: cdr= swap cdr swap cdr = ;
-
: cons= ( obj cons -- ? )
2dup eq? [
2drop t
] [
- over cons? [ 2dup car= >r cdr= r> and ] [ 2drop f ] ifte
+ over cons? [
+ 2dup 2car = >r 2cdr = r> and
+ ] [
+ 2drop f
+ ] ifte
] ifte ;
: (cons-hashcode) ( cons count -- hash )
IN: scratchpad
USE: test
USE: inference
+USE: math
USE: stack
USE: combinators
USE: vectors
] ifte
] infer
] unit-test
+
+[ [ 1 | 1 ] ] [ [ dup [ ] when ] infer ] unit-test
+[ [ 1 | 1 ] ] [ [ dup [ dup fixnum* ] when ] infer ] unit-test
+[ [ 2 | 1 ] ] [ [ [ dup fixnum* ] when ] infer ] unit-test
+
+[ [ 1 | 0 ] ] [ [ [ drop ] when* ] infer ] unit-test
+[ [ 1 | 1 ] ] [ [ [ { { [ ] } } ] unless* ] infer ] unit-test
drop dup compound? [
word-parameter (infer)
] [
- drop no-effect
+ no-effect
] ifte
] ifte ;
#! Stack effect of a quotation.
[ init-inference (infer) effect ] with-scope ;
-: infer-branch ( quot -- in-d datastack )
+: infer-branch ( quot -- [ in-d | datastack ] )
[
copy-interpreter (infer)
- d-in get meta-d get
+ d-in get meta-d get cons
] with-scope ;
-: unify ( in stack in stack -- )
- swapd 2dup vector-length= [
- drop meta-d set
- 2dup = [
- drop d-in set
- ] [
- "Unbalanced ifte inputs" throw
- ] ifte
+: difference ( [ in | stack ] -- diff )
+ uncons vector-length - ;
+
+: balanced? ( [ in | stack ] [ in | stack ] -- ? )
+ difference swap difference = ;
+
+: unify-stacks ( stack stack -- stack )
+ swap vector-length swap vector-length max gensym-vector ;
+
+: unify ( [ in | stack ] [ in | stack ] -- )
+ 2dup balanced? [
+ 2dup 2car max d-in set 2cdr unify-stacks meta-d set
] [
- "Unbalanced ifte outputs" throw
+ "Unbalanced ifte branches" throw
] ifte ;
: infer-ifte ( -- )
\ rot t "meta-infer" set-word-property
\ rot [ 3 | 3 ] "infer-effect" set-word-property
+\ fixnum+ [ 2 | 1 ] "infer-effect" set-word-property
+\ fixnum- [ 2 | 1 ] "infer-effect" set-word-property
+\ fixnum* [ 2 | 1 ] "infer-effect" set-word-property
+
\ vector-nth [ 2 | 1 ] "infer-effect" set-word-property
\ set-vector-nth [ 3 | 0 ] "infer-effect" set-word-property
\ vector-length [ 1 | 1 ] "infer-effect" set-word-property