560 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Factor
		
	
	
		
		
			
		
	
	
			560 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Factor
		
	
	
|  | USING: arrays generic inference inference.backend | ||
|  | inference.dataflow kernel classes kernel.private math | ||
|  | math.parser math.private namespaces namespaces.private parser | ||
|  | sequences strings vectors words quotations effects tools.test | ||
|  | continuations generic.standard sorting assocs definitions | ||
|  | prettyprint io inspector bootstrap.image tuples | ||
|  | classes.union classes.predicate debugger bootstrap.image | ||
|  | bootstrap.image.private io.launcher threads.private | ||
|  | io.streams.string combinators.private ;
 | ||
|  | IN: temporary | ||
|  | 
 | ||
|  | : short-effect | ||
|  |     dup effect-in length swap effect-out length 2array ;
 | ||
|  | 
 | ||
|  | [ { 0 2 } ] [ [ 2 "Hello" ] infer short-effect ] unit-test | ||
|  | [ { 1 2 } ] [ [ dup ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | [ { 1 2 } ] [ [ [ dup ] call ] infer short-effect ] unit-test | ||
|  | [ [ call ] infer short-effect ] unit-test-fails | ||
|  | 
 | ||
|  | [ { 2 4 } ] [ [ 2dup ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | [ { 1 0 } ] [ [ [ ] [ ] if ] infer short-effect ] unit-test | ||
|  | [ [ if ] infer short-effect ] unit-test-fails | ||
|  | [ [ [ ] if ] infer short-effect ] unit-test-fails | ||
|  | [ [ [ 2 ] [ ] if ] infer short-effect ] unit-test-fails | ||
|  | [ { 4 3 } ] [ [ [ rot ] [ -rot ] if ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | [ { 4 3 } ] [ | ||
|  |     [ | ||
|  |         [ | ||
|  |             [ swap 3 ] [ nip 5 5 ] if
 | ||
|  |         ] [ | ||
|  |             -rot
 | ||
|  |         ] if
 | ||
|  |     ] infer short-effect | ||
|  | ] unit-test | ||
|  | 
 | ||
|  | [ { 1 1 } ] [ [ dup [ ] when ] infer short-effect ] unit-test | ||
|  | [ { 1 1 } ] [ [ dup [ dup fixnum* ] when ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ [ dup fixnum* ] when ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | [ { 1 0 } ] [ [ [ drop ] when* ] infer short-effect ] unit-test | ||
|  | [ { 1 1 } ] [ [ [ { { [ ] } } ] unless* ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | [ { 0 1 } ] [ | ||
|  |     [ [ 2 2 fixnum+ ] dup [ ] when call ] infer short-effect | ||
|  | ] unit-test | ||
|  | 
 | ||
|  | [ | ||
|  |     [ [ [ 2 2 fixnum+ ] ] [ [ 2 2 fixnum* ] ] if call ] infer | ||
|  | ] unit-test-fails | ||
|  | 
 | ||
|  | ! Test inference of termination of control flow | ||
|  | : termination-test-1 | ||
|  |     "foo" throw ;
 | ||
|  | 
 | ||
|  | : termination-test-2 [ termination-test-1 ] [ 3 ] if ;
 | ||
|  | 
 | ||
|  | [ { 1 1 } ] [ [ termination-test-2 ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | : infinite-loop infinite-loop ;
 | ||
|  | 
 | ||
|  | [ [ infinite-loop ] infer short-effect ] unit-test-fails | ||
|  | 
 | ||
|  | : no-base-case-1 dup [ no-base-case-1 ] [ no-base-case-1 ] if ;
 | ||
|  | [ [ no-base-case-1 ] infer short-effect ] unit-test-fails | ||
|  | 
 | ||
|  | : simple-recursion-1 ( obj -- obj )
 | ||
|  |     dup [ simple-recursion-1 ] [ ] if ;
 | ||
|  | 
 | ||
|  | [ { 1 1 } ] [ [ simple-recursion-1 ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | : simple-recursion-2 ( obj -- obj )
 | ||
|  |     dup [ ] [ simple-recursion-2 ] if ;
 | ||
|  | 
 | ||
|  | [ { 1 1 } ] [ [ simple-recursion-2 ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | : bad-recursion-2 ( obj -- obj )
 | ||
|  |     dup [ dup first swap second bad-recursion-2 ] [ ] if ;
 | ||
|  | 
 | ||
|  | [ [ bad-recursion-2 ] infer short-effect ] unit-test-fails | ||
|  | 
 | ||
|  | : funny-recursion ( obj -- obj )
 | ||
|  |     dup [ funny-recursion 1 ] [ 2 ] if drop ;
 | ||
|  | 
 | ||
|  | [ { 1 1 } ] [ [ funny-recursion ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | ! Simple combinators | ||
|  | [ { 1 2 } ] [ [ [ first ] keep second ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | ! Mutual recursion | ||
|  | DEFER: foe | ||
|  | 
 | ||
|  | : fie ( element obj -- ? )
 | ||
|  |     dup array? [ foe ] [ eq? ] if ;
 | ||
|  | 
 | ||
|  | : foe ( element tree -- ? )
 | ||
|  |     dup [ | ||
|  |         2dup first fie [ | ||
|  |             nip
 | ||
|  |         ] [ | ||
|  |             second dup array? [ | ||
|  |                 foe | ||
|  |             ] [ | ||
|  |                 fie | ||
|  |             ] if
 | ||
|  |         ] if
 | ||
|  |     ] [ | ||
|  |         2drop f
 | ||
|  |     ] if ;
 | ||
|  | 
 | ||
|  | [ { 2 1 } ] [ [ fie ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ foe ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | : nested-when ( -- )
 | ||
|  |     t [ | ||
|  |         t [ | ||
|  |             5 drop
 | ||
|  |         ] when
 | ||
|  |     ] when ;
 | ||
|  | 
 | ||
|  | [ { 0 0 } ] [ [ nested-when ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | : nested-when* ( obj -- )
 | ||
|  |     [ | ||
|  |         [ | ||
|  |             drop
 | ||
|  |         ] when*
 | ||
|  |     ] when* ;
 | ||
|  | 
 | ||
|  | [ { 1 0 } ] [ [ nested-when* ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | SYMBOL: sym-test | ||
|  | 
 | ||
|  | [ { 0 1 } ] [ [ sym-test ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | : terminator-branch | ||
|  |     dup [ | ||
|  |         length
 | ||
|  |     ] [ | ||
|  |         "foo" throw
 | ||
|  |     ] if ;
 | ||
|  | 
 | ||
|  | [ { 1 1 } ] [ [ terminator-branch ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | : recursive-terminator ( obj -- )
 | ||
|  |     dup [ | ||
|  |         recursive-terminator | ||
|  |     ] [ | ||
|  |         "Hi" throw
 | ||
|  |     ] if ;
 | ||
|  | 
 | ||
|  | [ { 1 0 } ] [ [ recursive-terminator ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | GENERIC: potential-hang ( obj -- obj )
 | ||
|  | M: fixnum potential-hang dup [ potential-hang ] when ;
 | ||
|  | 
 | ||
|  | [ ] [ [ 5 potential-hang ] infer short-effect drop ] unit-test | ||
|  | 
 | ||
|  | TUPLE: funny-cons car cdr ;
 | ||
|  | GENERIC: iterate ( obj -- )
 | ||
|  | M: funny-cons iterate funny-cons-cdr iterate ;
 | ||
|  | M: f iterate drop ;
 | ||
|  | M: real iterate drop ;
 | ||
|  | 
 | ||
|  | [ { 1 0 } ] [ [ iterate ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | ! Regression | ||
|  | : cat ( obj -- * ) dup [ throw ] [ throw ] if ;
 | ||
|  | : dog ( a b c -- ) dup [ cat ] [ 3drop ] if ;
 | ||
|  | [ { 3 0 } ] [ [ dog ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | ! Regression | ||
|  | DEFER: monkey | ||
|  | : friend ( a b c -- ) dup [ friend ] [ monkey ] if ;
 | ||
|  | : monkey ( a b c -- ) dup [ 3drop ] [ friend ] if ;
 | ||
|  | [ { 3 0 } ] [ [ friend ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | ! Regression -- same as above but we infer short-effect the second word first | ||
|  | DEFER: blah2 | ||
|  | : blah ( a b c -- ) dup [ blah ] [ blah2 ] if ;
 | ||
|  | : blah2 ( a b c -- ) dup [ blah ] [ 3drop ] if ;
 | ||
|  | [ { 3 0 } ] [ [ blah2 ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | ! Regression | ||
|  | DEFER: blah4 | ||
|  | : blah3 ( a b c -- )
 | ||
|  |     dup [ blah3 ] [ dup [ blah4 ] [ blah3 ] if ] if ;
 | ||
|  | : blah4 ( a b c -- )
 | ||
|  |     dup [ blah4 ] [ dup [ 3drop ] [ blah3 ] if ] if ;
 | ||
|  | [ { 3 0 } ] [ [ blah4 ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | ! Regression | ||
|  | : bad-combinator ( obj quot -- )
 | ||
|  |     over [ | ||
|  |         2drop
 | ||
|  |     ] [ | ||
|  |         [ swap slip ] keep swap bad-combinator | ||
|  |     ] if ; inline
 | ||
|  | 
 | ||
|  | [ [ [ 1 ] [ ] bad-combinator ] infer short-effect ] unit-test-fails | ||
|  | 
 | ||
|  | ! Regression | ||
|  | : bad-input# | ||
|  |     dup string? [ 2array throw ] unless
 | ||
|  |     over string? [ 2array throw ] unless ;
 | ||
|  | 
 | ||
|  | [ { 2 2 } ] [ [ bad-input# ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | ! Regression | ||
|  | 
 | ||
|  | ! This order of branches works | ||
|  | DEFER: do-crap | ||
|  | : more-crap ( obj -- ) dup [ drop ] [ dup do-crap call ] if ;
 | ||
|  | : do-crap ( obj -- ) dup [ more-crap ] [ do-crap ] if ;
 | ||
|  | [ [ do-crap ] infer short-effect ] unit-test-fails | ||
|  | 
 | ||
|  | ! This one does not | ||
|  | DEFER: do-crap* | ||
|  | : more-crap* ( obj -- ) dup [ drop ] [ dup do-crap* call ] if ;
 | ||
|  | : do-crap* ( obj -- ) dup [ do-crap* ] [ more-crap* ] if ;
 | ||
|  | [ [ do-crap* ] infer short-effect ] unit-test-fails | ||
|  | 
 | ||
|  | ! Regression | ||
|  | : too-deep ( a b -- c )
 | ||
|  |     dup [ drop ] [ 2dup too-deep too-deep * ] if ; inline
 | ||
|  | [ { 2 1 } ] [ [ too-deep ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | ! Error reporting is wrong | ||
|  | MATH: xyz | ||
|  | M: fixnum xyz 2array ;
 | ||
|  | M: ratio xyz  | ||
|  |     [ >fraction ] 2apply swapd >r 2array swap r> 2array swap ;
 | ||
|  | 
 | ||
|  | [ t ] [ [ [ xyz ] infer short-effect ] catch inference-error? ] unit-test | ||
|  | 
 | ||
|  | ! Doug Coleman discovered this one while working on the | ||
|  | ! calendar library | ||
|  | DEFER: A | ||
|  | DEFER: B | ||
|  | DEFER: C | ||
|  | 
 | ||
|  | : A ( a -- )
 | ||
|  |     dup { | ||
|  |         [ drop ] | ||
|  |         [ A ] | ||
|  |         [ \ A no-method ] | ||
|  |         [ dup C A ] | ||
|  |     } dispatch ;
 | ||
|  | 
 | ||
|  | : B ( b -- )
 | ||
|  |     dup { | ||
|  |         [ C ] | ||
|  |         [ B ] | ||
|  |         [ \ B no-method ] | ||
|  |         [ dup B B ] | ||
|  |     } dispatch ;
 | ||
|  | 
 | ||
|  | : C ( c -- )
 | ||
|  |     dup { | ||
|  |         [ A ] | ||
|  |         [ C ] | ||
|  |         [ \ C no-method ] | ||
|  |         [ dup B C ] | ||
|  |     } dispatch ;
 | ||
|  | 
 | ||
|  | [ { 1 0 } ] [ [ A ] infer short-effect ] unit-test | ||
|  | [ { 1 0 } ] [ [ B ] infer short-effect ] unit-test | ||
|  | [ { 1 0 } ] [ [ C ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | ! I found this bug by thinking hard about the previous one | ||
|  | DEFER: Y | ||
|  | : X ( a b -- c d ) dup [ swap Y ] [ ] if ;
 | ||
|  | : Y ( a b -- c d ) X ;
 | ||
|  | 
 | ||
|  | [ { 2 2 } ] [ [ X ] infer short-effect ] unit-test | ||
|  | [ { 2 2 } ] [ [ Y ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | ! This one comes from UI code | ||
|  | DEFER: #1 | ||
|  | : #2 ( a b -- ) dup [ call ] [ 2drop ] if ; inline
 | ||
|  | : #3 ( a -- ) [ #1 ] #2 ;
 | ||
|  | : #4 ( a -- ) dup [ drop ] [ dup #4 dup #3 call ] if ;
 | ||
|  | : #1 ( a -- ) dup [ dup #4 dup #3 ] [ ] if drop ;
 | ||
|  | 
 | ||
|  | [ \ #4 word-def infer short-effect ] unit-test-fails | ||
|  | [ [ #1 ] infer short-effect ] unit-test-fails | ||
|  | 
 | ||
|  | ! Similar | ||
|  | DEFER: bar | ||
|  | : foo ( a b -- c d ) dup [ 2drop f f bar ] [ ] if ;
 | ||
|  | : bar ( a b -- ) [ 2 2 + ] t foo drop call drop ;
 | ||
|  | 
 | ||
|  | [ [ foo ] infer short-effect ] unit-test-fails | ||
|  | 
 | ||
|  | [ 1234 infer short-effect ] unit-test-fails | ||
|  | 
 | ||
|  | ! This used to hang | ||
|  | [ t ] [ | ||
|  |     [ [ [ dup call ] dup call ] infer ] catch | ||
|  |     inference-error? | ||
|  | ] unit-test | ||
|  | 
 | ||
|  | : m dup call ; inline
 | ||
|  | 
 | ||
|  | [ t ] [ | ||
|  |     [ [ [ m ] m ] infer ] catch inference-error? | ||
|  | ] unit-test | ||
|  | 
 | ||
|  | : m' dup curry call ; inline
 | ||
|  | 
 | ||
|  | [ t ] [ | ||
|  |     [ [ [ m' ] m' ] infer ] catch inference-error? | ||
|  | ] unit-test | ||
|  | 
 | ||
|  | : m'' [ dup curry ] ; inline
 | ||
|  | 
 | ||
|  | : m''' m'' call call ; inline
 | ||
|  | 
 | ||
|  | [ t ] [ | ||
|  |     [ [ [ m''' ] m''' ] infer ] catch inference-error? | ||
|  | ] unit-test | ||
|  | 
 | ||
|  | : m-if t over if ; inline
 | ||
|  | 
 | ||
|  | [ t ] [ | ||
|  |     [ [ [ m-if ] m-if ] infer ] catch inference-error? | ||
|  | ] unit-test | ||
|  | 
 | ||
|  | ! This doesn't hang but it's also an example of the | ||
|  | ! undedicable case | ||
|  | [ t ] [ | ||
|  |     [ [ [ [ drop 3 ] swap call ] dup call ] infer ] catch | ||
|  |     inference-error? | ||
|  | ] unit-test | ||
|  | 
 | ||
|  | ! This form should not have a stack effect | ||
|  | 
 | ||
|  | : bad-recursion-1 ( a -- b )
 | ||
|  |     dup [ drop bad-recursion-1 5 ] [ ] if ;
 | ||
|  | 
 | ||
|  | [ [ bad-recursion-1 ] infer short-effect ] unit-test-fails | ||
|  | 
 | ||
|  | : bad-bin ( a b -- ) 5 [ 5 bad-bin bad-bin 5 ] [ 2drop ] if ;
 | ||
|  | [ [ bad-bin ] infer short-effect ] unit-test-fails | ||
|  | 
 | ||
|  | [ t ] [ [ [ r> ] infer short-effect ] catch inference-error? ] unit-test | ||
|  | 
 | ||
|  | ! Test some curry stuff | ||
|  | [ { 1 1 } ] [ [ 3 [ ] curry 4 [ ] curry if ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | [ { 2 1 } ] [ [ [ ] curry 4 [ ] curry if ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | [ [ 3 [ ] curry 1 2 [ ] 2curry if ] infer ] unit-test-fails | ||
|  | 
 | ||
|  | ! Test number protocol | ||
|  | [ { 2 1 } ] [ [ bitor ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ bitand ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ bitxor ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ mod ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ /i ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ /f ] infer short-effect ] unit-test | ||
|  | [ { 2 2 } ] [ [ /mod ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ + ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ - ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ * ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ / ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ < ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ <= ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ > ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ >= ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ number= ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | ! Test object protocol | ||
|  | [ { 2 1 } ] [ [ = ] infer short-effect ] unit-test | ||
|  | [ { 1 1 } ] [ [ clone ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ hashcode* ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | ! Test sequence protocol | ||
|  | [ { 1 1 } ] [ [ length ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ nth ] infer short-effect ] unit-test | ||
|  | [ { 2 0 } ] [ [ set-length ] infer short-effect ] unit-test | ||
|  | [ { 3 0 } ] [ [ set-nth ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ new ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ new-resizable ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ like ] infer short-effect ] unit-test | ||
|  | [ { 2 0 } ] [ [ lengthen ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | ! Test assoc protocol | ||
|  | [ { 2 2 } ] [ [ at* ] infer short-effect ] unit-test | ||
|  | [ { 3 0 } ] [ [ set-at ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ new-assoc ] infer short-effect ] unit-test | ||
|  | [ { 2 0 } ] [ [ delete-at ] infer short-effect ] unit-test | ||
|  | [ { 1 0 } ] [ [ clear-assoc ] infer short-effect ] unit-test | ||
|  | [ { 1 1 } ] [ [ assoc-size ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ assoc-like ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ assoc-clone-like ] infer short-effect ] unit-test | ||
|  | [ { 1 1 } ] [ [ >alist ] infer short-effect ] unit-test | ||
|  | [ { 1 3 } ] [ [ [ 2drop f ] assoc-find ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | ! Test some random library words | ||
|  | [ { 1 1 } ] [ [ 1quotation ] infer short-effect ] unit-test | ||
|  | [ { 1 1 } ] [ [ string>number ] infer short-effect ] unit-test | ||
|  | [ { 1 1 } ] [ [ get ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | [ { 2 0 } ] [ [ push ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ append ] infer short-effect ] unit-test | ||
|  | [ { 1 1 } ] [ [ peek ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | [ { 1 1 } ] [ [ reverse ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ member? ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ remove ] infer short-effect ] unit-test | ||
|  | [ { 1 1 } ] [ [ natural-sort ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | [ { 1 0 } ] [ [ forget ] infer short-effect ] unit-test | ||
|  | [ { 4 0 } ] [ [ define-class ] infer short-effect ] unit-test | ||
|  | [ { 2 0 } ] [ [ define-tuple-class ] infer short-effect ] unit-test | ||
|  | [ { 2 0 } ] [ [ define-union-class ] infer short-effect ] unit-test | ||
|  | [ { 3 0 } ] [ [ define-predicate-class ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | ! Test words with continuations | ||
|  | [ { 0 0 } ] [ [ [ drop ] callcc0 ] infer short-effect ] unit-test | ||
|  | [ { 0 1 } ] [ [ [ 4 swap continue-with ] callcc1 ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ [ + ] [ ] [ ] cleanup ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ [ + ] [ 3drop 0 ] recover ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | ! Test stream protocol | ||
|  | [ { 2 0 } ] [ [ set-timeout ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ stream-read ] infer short-effect ] unit-test | ||
|  | [ { 1 1 } ] [ [ stream-read1 ] infer short-effect ] unit-test | ||
|  | [ { 1 1 } ] [ [ stream-readln ] infer short-effect ] unit-test | ||
|  | [ { 2 2 } ] [ [ stream-read-until ] infer short-effect ] unit-test | ||
|  | [ { 2 0 } ] [ [ stream-write ] infer short-effect ] unit-test | ||
|  | [ { 2 0 } ] [ [ stream-write1 ] infer short-effect ] unit-test | ||
|  | [ { 1 0 } ] [ [ stream-nl ] infer short-effect ] unit-test | ||
|  | [ { 1 0 } ] [ [ stream-close ] infer short-effect ] unit-test | ||
|  | [ { 3 0 } ] [ [ stream-format ] infer short-effect ] unit-test | ||
|  | [ { 3 0 } ] [ [ stream-write-table ] infer short-effect ] unit-test | ||
|  | [ { 1 0 } ] [ [ stream-flush ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ make-span-stream ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ make-block-stream ] infer short-effect ] unit-test | ||
|  | [ { 2 1 } ] [ [ make-cell-stream ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | ! Test stream utilities | ||
|  | [ { 1 1 } ] [ [ lines ] infer short-effect ] unit-test | ||
|  | [ { 1 1 } ] [ [ contents ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | ! Test prettyprinting | ||
|  | [ { 1 0 } ] [ [ . ] infer short-effect ] unit-test | ||
|  | [ { 1 0 } ] [ [ short. ] infer short-effect ] unit-test | ||
|  | [ { 1 1 } ] [ [ unparse ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | [ { 1 0 } ] [ [ describe ] infer short-effect ] unit-test | ||
|  | [ { 1 0 } ] [ [ error. ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | ! Test odds and ends | ||
|  | [ { 1 1 } ] [ [ ' ] infer short-effect ] unit-test | ||
|  | [ { 2 0 } ] [ [ write-image ] infer short-effect ] unit-test | ||
|  | [ { 1 1 } ] [ [ <process-stream> ] infer short-effect ] unit-test | ||
|  | [ { 0 0 } ] [ [ idle-thread ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | ! Incorrect stack declarations on inline recursive words should | ||
|  | ! be caught | ||
|  | : fooxxx ( a b -- c ) over [ foo ] when ; inline
 | ||
|  | : barxxx fooxxx ;
 | ||
|  | 
 | ||
|  | [ [ barxxx ] infer ] unit-test-fails | ||
|  | 
 | ||
|  | ! A typo | ||
|  | [ { 1 0 } ] [ [ { [ ] } dispatch ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | DEFER: inline-recursive-2 | ||
|  | : inline-recursive-1 ( -- ) inline-recursive-2 ;
 | ||
|  | : inline-recursive-2 ( -- ) inline-recursive-1 ;
 | ||
|  | 
 | ||
|  | [ { 0 0 } ] [ [ inline-recursive-1 ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | ! Hooks | ||
|  | SYMBOL: my-var | ||
|  | HOOK: my-hook my-var ( -- x )
 | ||
|  | 
 | ||
|  | M: integer my-hook "an integer" ;
 | ||
|  | M: string my-hook "a string" ;
 | ||
|  | 
 | ||
|  | [ { 0 1 } ] [ [ my-hook ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | DEFER: deferred-word | ||
|  | 
 | ||
|  | : calls-deferred-word [ deferred-word ] [ 3 ] if ;
 | ||
|  | 
 | ||
|  | [ { 1 1 } ] [ [ calls-deferred-word ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | USE: inference.dataflow | ||
|  | 
 | ||
|  | [ { 1 0 } ] [ [ [ iterate-next ] iterate-nodes ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | [ { 1 0 } ] [ | ||
|  |     [ | ||
|  |         [ [ iterate-next ] iterate-nodes ] with-node-iterator | ||
|  |     ] infer short-effect | ||
|  | ] unit-test | ||
|  | 
 | ||
|  | : nilpotent ( quot -- )
 | ||
|  |     t [ [ call ] keep nilpotent ] [ drop ] if ; inline
 | ||
|  | 
 | ||
|  | : semisimple ( quot -- )
 | ||
|  |     [ call ] keep [ [ semisimple ] keep ] nilpotent drop ; inline
 | ||
|  | 
 | ||
|  | [ { 0 1 } ] [ | ||
|  |     [ [ ] [ call ] keep [ [ call ] keep ] nilpotent ] | ||
|  |     infer short-effect | ||
|  | ] unit-test | ||
|  | 
 | ||
|  | [ { 0 0 } ] [ [ [ ] semisimple ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | [ { 1 0 } ] [ [ [ drop ] each-node ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | DEFER: an-inline-word | ||
|  | 
 | ||
|  | : normal-word-3 ( -- )
 | ||
|  |     3 [ [ 2 + ] curry ] an-inline-word call drop ;
 | ||
|  | 
 | ||
|  | : normal-word-2 ( -- )
 | ||
|  |     normal-word-3 ;
 | ||
|  | 
 | ||
|  | : normal-word ( x -- x )
 | ||
|  |     dup [ normal-word-2 ] when ;
 | ||
|  | 
 | ||
|  | : an-inline-word ( obj quot -- )
 | ||
|  |     >r normal-word r> call ; inline
 | ||
|  | 
 | ||
|  | [ { 1 1 } ] [ [ [ 3 * ] an-inline-word ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | [ { 0 1 } ] [ [ [ 2 ] [ 2 ] [ + ] compose compose call ] infer short-effect ] unit-test | ||
|  | 
 | ||
|  | TUPLE: custom-error ;
 | ||
|  | 
 | ||
|  | [ T{ effect f 0 0 t } ] [ | ||
|  |     [ custom-error construct-boa throw ] infer | ||
|  | ] unit-test | ||
|  | 
 | ||
|  | : funny-throw throw ; inline
 | ||
|  | 
 | ||
|  | [ T{ effect f 0 0 t } ] [ | ||
|  |     [ 3 funny-throw ] infer | ||
|  | ] unit-test | ||
|  | 
 | ||
|  | [ T{ effect f 0 0 t } ] [ | ||
|  |     [ custom-error inference-error ] infer | ||
|  | ] unit-test | ||
|  | 
 | ||
|  | [ T{ effect f 1 1 t } ] [ | ||
|  |     [ dup >r 3 throw r> ] infer | ||
|  | ] unit-test | ||
|  | 
 | ||
|  | ! This was a false trigger of the undecidable quotation | ||
|  | ! recursion bug | ||
|  | [ { 2 1 } ] [ [ find-last-sep ] infer short-effect ] unit-test |