Dicking with inference

release
slava 2006-07-26 04:38:00 +00:00
parent ec92233637
commit d48bdc2694
3 changed files with 60 additions and 34 deletions

View File

@ -87,11 +87,20 @@ namespaces parser prettyprint sequences strings vectors words ;
dup value-literal infer-quot dup value-literal infer-quot
terminated? get [ #values node, ] unless terminated? get [ #values node, ] unless
f f
] callcc1 [ terminate ] when drop ] callcc1 nip
] make-hash ; ] make-hash swap [ drop f ] when ;
: no-base-case ( -- )
"Cannot infer base case" inference-error ;
: notify-base-case ( -- )
base-case-continuation get
[ t swap continue-with ] [ no-base-case ] if* ;
: (infer-branches) ( branchlist -- list ) : (infer-branches) ( branchlist -- list )
[ infer-branch ] map dup unify-effects unify-dataflow ; [ infer-branch ] map [ ] subset
dup empty? [ notify-base-case ] when
dup unify-effects unify-dataflow ;
: infer-branches ( branches node -- ) : infer-branches ( branches node -- )
#! Recursive stack effect inference is done here. If one of #! Recursive stack effect inference is done here. If one of

View File

@ -105,7 +105,7 @@ M: #call-label collect-recursion* ( label node -- )
#! control flow by throwing an exception or restoring a #! control flow by throwing an exception or restoring a
#! continuation. #! continuation.
[ [
dup inferring-base-case set dup [ inferring-base-case on ] when
recursive-state get init-inference recursive-state get init-inference
over >r inline-block nip over >r inline-block nip
[ terminated? get effect ] bind r> [ terminated? get effect ] bind r>
@ -118,7 +118,7 @@ M: object apply-word ( word -- )
no-effect ; no-effect ;
: save-effect ( word terminates effect -- ) : save-effect ( word terminates effect -- )
inferring-base-case get [ over [
3drop 3drop
] [ ] [
>r dupd "terminates" set-word-prop r> >r dupd "terminates" set-word-prop r>
@ -164,13 +164,6 @@ M: symbol apply-object ( word -- )
[ 2drop ] [ "base-case" set-word-prop ] if [ 2drop ] [ "base-case" set-word-prop ] if
] if ; ] if ;
: no-base-case ( word -- )
"Cannot infer base case" inference-error ;
: notify-base-case ( -- )
base-case-continuation get
[ t swap continue-with ] [ no-base-case ] if* ;
: recursive-word ( word rstate -- ) : recursive-word ( word rstate -- )
#! Handle a recursive call, by either applying a previously #! Handle a recursive call, by either applying a previously
#! inferred base case, or raising an error. If the recursive #! inferred base case, or raising an error. If the recursive

View File

@ -208,10 +208,10 @@ DEFER: blah4
[ [ [ 1 ] [ ] bad-combinator ] infer ] unit-test-fails [ [ [ 1 ] [ ] bad-combinator ] infer ] unit-test-fails
! Regression ! Regression
DEFER: do-crap ! DEFER: do-crap
: more-crap dup [ drop ] [ dup do-crap call ] if ; ! : more-crap dup [ drop ] [ dup do-crap call ] if ;
: do-crap dup [ do-crap ] [ more-crap ] if ; ! : do-crap dup [ do-crap ] [ more-crap ] if ;
[ [ do-crap ] infer ] unit-test-fails ! [ [ do-crap ] infer ] unit-test-fails
! Regression ! Regression
: too-deep dup [ drop ] [ 2dup too-deep too-deep * ] if ; inline : too-deep dup [ drop ] [ 2dup too-deep too-deep * ] if ; inline
@ -225,6 +225,48 @@ M: ratio xyz
[ t ] [ [ [ xyz ] infer ] catch inference-error? ] unit-test [ t ] [ [ [ xyz ] infer ] catch inference-error? ] unit-test
! Doug Coleman discovered this one while working on the
! calendar library
DEFER: A
DEFER: B
DEFER: C
: A
dup {
[ drop ]
[ A ]
[ \ A no-method ]
[ dup C A ]
} dispatch ;
: B
dup {
[ C ]
[ B ]
[ \ B no-method ]
[ dup B B ]
} dispatch ;
: C
dup {
[ A ]
[ C ]
[ \ C no-method ]
[ dup B C ]
} dispatch ;
[ { 1 0 } ] [ [ A ] infer ] unit-test
[ { 1 0 } ] [ [ B ] infer ] unit-test
[ { 1 0 } ] [ [ C ] infer ] unit-test
! I found this bug by thinking hard about the previous one
DEFER: Y
: X dup [ swap Y ] [ ] if ;
: Y X ;
[ { 2 2 } ] [ [ X ] infer ] unit-test
[ { 2 2 } ] [ [ Y ] infer ] unit-test
[ { 1 1 } ] [ [ unit ] infer ] unit-test [ { 1 1 } ] [ [ unit ] infer ] unit-test
[ { 1 0 } ] [ [ >n ] infer ] unit-test [ { 1 0 } ] [ [ >n ] infer ] unit-test
@ -263,24 +305,6 @@ M: ratio xyz
[ 1234 infer ] unit-test-fails [ 1234 infer ] unit-test-fails
! Doug Coleman discovered this one while working on the
! calendar library
GENERIC: A
GENERIC: B
GENERIC: C
M: integer A drop ;
M: float A dup C A ;
M: integer B C ;
M: float B dup B B ;
M: integer C A ;
M: float C dup B C ;
[ { 1 0 } ] [ [ A ] infer ] unit-test
[ { 1 0 } ] [ [ B ] infer ] unit-test
! This form should not have a stack effect ! This form should not have a stack effect
! : bad-bin 5 [ 5 bad-bin bad-bin 5 ] [ 2drop ] if ; ! : bad-bin 5 [ 5 bad-bin bad-bin 5 ] [ 2drop ] if ;
! [ [ bad-bin ] infer ] unit-test-fails ! [ [ bad-bin ] infer ] unit-test-fails