reuse infer-call* for polymorphic inference, which handles curried quotations. tests can pass with real "each" etc. now
							parent
							
								
									c9162c5e31
								
							
						
					
					
						commit
						26e4bb818a
					
				| 
						 | 
					@ -8,24 +8,6 @@ stack-checker.state
 | 
				
			||||||
stack-checker.values ;
 | 
					stack-checker.values ;
 | 
				
			||||||
IN: stack-checker.row-polymorphism.tests
 | 
					IN: stack-checker.row-polymorphism.tests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: checked-each ( ..a seq quot: ( ..a x -- ..a ) -- ..a )
 | 
					 | 
				
			||||||
    curry call ; inline
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: checked-map ( ..a seq quot: ( ..a x -- ..a y ) -- ..a seq' )
 | 
					 | 
				
			||||||
    curry call f ; inline
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: checked-map-index ( ..a seq quot: ( ..a x index -- ..a y ) -- ..a seq' )
 | 
					 | 
				
			||||||
    0 swap 2curry call f ; inline
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: checked-if ( ..a x then: ( ..a -- ..b ) else: ( ..a -- ..b ) -- ..b )
 | 
					 | 
				
			||||||
    drop nip call ; inline
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: checked-if* ( ..a x then: ( ..a x -- ..b ) else: ( ..a -- ..b ) -- ..b )
 | 
					 | 
				
			||||||
    drop call ; inline
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: checked-with-variable ( ..a value key quot: ( ..a -- ..b ) -- ..b )
 | 
					 | 
				
			||||||
    2nip call ; inline
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: infer-polymorphic-quot ( quot -- vars )
 | 
					: infer-polymorphic-quot ( quot -- vars )
 | 
				
			||||||
    t infer-polymorphic? [
 | 
					    t infer-polymorphic? [
 | 
				
			||||||
        unclip-last [
 | 
					        unclip-last [
 | 
				
			||||||
| 
						 | 
					@ -43,51 +25,47 @@ IN: stack-checker.row-polymorphism.tests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: poly-infer-must-fail ( quot -- )
 | 
					: poly-infer-must-fail ( quot -- )
 | 
				
			||||||
    '[ _ infer-polymorphic-quot ] [ invalid-quotation-input? ] must-fail-with ; inline
 | 
					    '[ _ infer-polymorphic-quot ] [ invalid-quotation-input? ] must-fail-with ; inline
 | 
				
			||||||
: poly-infer-must-fail-bad-macro-input ( quot -- )
 | 
					: poly-infer-must-fail-unknown ( quot -- )
 | 
				
			||||||
    '[ _ infer-polymorphic-quot ] [ bad-macro-input? ] must-fail-with ; inline
 | 
					    '[ _ infer-polymorphic-quot ] [ unknown-macro-input? ] must-fail-with ; inline
 | 
				
			||||||
 | 
					
 | 
				
			||||||
H{ { "a" 0 } } [ [ write      ] checked-each ] test-poly-infer
 | 
					H{ { "." 0 } } [ [ write      ] each ] test-poly-infer
 | 
				
			||||||
H{ { "a" 1 } } [ [ append     ] checked-each ] test-poly-infer
 | 
					H{ { "." 1 } } [ [ append     ] each ] test-poly-infer
 | 
				
			||||||
H{ { "a" 0 } } [ [            ] checked-map  ] test-poly-infer
 | 
					H{ { "." 0 } } [ [            ] map  ] test-poly-infer
 | 
				
			||||||
H{ { "a" 0 } } [ [ reverse    ] checked-map  ] test-poly-infer
 | 
					H{ { "." 0 } } [ [ reverse    ] map  ] test-poly-infer
 | 
				
			||||||
H{ { "a" 1 } } [ [ append dup ] checked-map  ] test-poly-infer
 | 
					H{ { "." 1 } } [ [ append dup ] map  ] test-poly-infer
 | 
				
			||||||
H{ { "a" 1 } } [ [ swap nth suffix dup ] checked-map-index ] test-poly-infer
 | 
					H{ { "." 1 } } [ [ swap nth suffix dup ] map-index ] test-poly-infer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
H{ { "a" 3 } { "b" 1 } } [ [ 2drop ] [ 2nip    ] checked-if ] test-poly-infer
 | 
					H{ { "a" 3 } { "b" 1 } } [ [ 2drop ] [ 2nip    ] if ] test-poly-infer
 | 
				
			||||||
H{ { "a" 2 } { "b" 3 } } [ [ dup   ] [ over    ] checked-if ] test-poly-infer
 | 
					H{ { "a" 2 } { "b" 3 } } [ [ dup   ] [ over    ] if ] test-poly-infer
 | 
				
			||||||
H{ { "a" 0 } { "b" 1 } } [ [ os    ] [ cpu     ] checked-if ] test-poly-infer
 | 
					H{ { "a" 0 } { "b" 1 } } [ [ os    ] [ cpu     ] if ] test-poly-infer
 | 
				
			||||||
H{ { "a" 1 } { "b" 2 } } [ [ os    ] [ 1 + cpu ] checked-if ] test-poly-infer
 | 
					H{ { "a" 1 } { "b" 2 } } [ [ os    ] [ 1 + cpu ] if ] test-poly-infer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
H{ { "a" 0 } { "b" 0 } } [ [ write     ] [ "(f)" write ] checked-if* ] test-poly-infer
 | 
					H{ { "a" 0 } { "b" 0 } } [ [ write     ] [ "(f)" write ] if* ] test-poly-infer
 | 
				
			||||||
H{ { "a" 0 } { "b" 1 } } [ [           ] [ f           ] checked-if* ] test-poly-infer
 | 
					H{ { "a" 0 } { "b" 1 } } [ [           ] [ f           ] if* ] test-poly-infer
 | 
				
			||||||
H{ { "a" 1 } { "b" 1 } } [ [ nip       ] [ drop f      ] checked-if* ] test-poly-infer
 | 
					H{ { "a" 1 } { "b" 1 } } [ [ nip       ] [ drop f      ] if* ] test-poly-infer
 | 
				
			||||||
H{ { "a" 1 } { "b" 1 } } [ [ nip       ] [             ] checked-if* ] test-poly-infer
 | 
					H{ { "a" 1 } { "b" 1 } } [ [ nip       ] [             ] if* ] test-poly-infer
 | 
				
			||||||
H{ { "a" 2 } { "b" 2 } } [ [ 3append f ] [             ] checked-if* ] test-poly-infer
 | 
					H{ { "a" 2 } { "b" 2 } } [ [ 3append f ] [             ] if* ] test-poly-infer
 | 
				
			||||||
H{ { "a" 0 } { "b" 0 } } [ [ drop      ] [             ] checked-if* ] test-poly-infer
 | 
					H{ { "a" 0 } { "b" 0 } } [ [ drop      ] [             ] if* ] test-poly-infer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
H{ { "a" 1 } { "b" 0 } } [ [ write ] checked-with-variable ] test-poly-infer
 | 
					[ [ write write ] each      ] poly-infer-must-fail
 | 
				
			||||||
H{ { "a" 0 } { "b" 1 } } [ [ os    ] checked-with-variable ] test-poly-infer
 | 
					[ [             ] each      ] poly-infer-must-fail
 | 
				
			||||||
H{ { "a" 1 } { "b" 1 } } [ [ dup + ] checked-with-variable ] test-poly-infer
 | 
					[ [ dup         ] map       ] poly-infer-must-fail
 | 
				
			||||||
 | 
					[ [ drop        ] map       ] poly-infer-must-fail
 | 
				
			||||||
 | 
					[ [ 1 +         ] map-index ] poly-infer-must-fail
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[ [ write write ] checked-each      ] poly-infer-must-fail
 | 
					[ [ dup  ] [      ] if ] poly-infer-must-fail
 | 
				
			||||||
[ [             ] checked-each      ] poly-infer-must-fail
 | 
					[ [ 2dup ] [ over ] if ] poly-infer-must-fail
 | 
				
			||||||
[ [ dup         ] checked-map       ] poly-infer-must-fail
 | 
					[ [ drop ] [      ] if ] poly-infer-must-fail
 | 
				
			||||||
[ [ drop        ] checked-map       ] poly-infer-must-fail
 | 
					 | 
				
			||||||
[ [ 1 +         ] checked-map-index ] poly-infer-must-fail
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
[ [ dup  ] [      ] checked-if ] poly-infer-must-fail
 | 
					[ [      ] [       ] if* ] poly-infer-must-fail
 | 
				
			||||||
[ [ 2dup ] [ over ] checked-if ] poly-infer-must-fail
 | 
					[ [ dup  ] [       ] if* ] poly-infer-must-fail
 | 
				
			||||||
[ [ drop ] [      ] checked-if ] poly-infer-must-fail
 | 
					[ [ drop ] [ drop  ] if* ] poly-infer-must-fail
 | 
				
			||||||
 | 
					[ [      ] [ drop  ] if* ] poly-infer-must-fail
 | 
				
			||||||
 | 
					[ [      ] [ 2dup  ] if* ] poly-infer-must-fail
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[ [      ] [       ] checked-if* ] poly-infer-must-fail
 | 
					[ "derp" each ] poly-infer-must-fail
 | 
				
			||||||
[ [ dup  ] [       ] checked-if* ] poly-infer-must-fail
 | 
					[ each ] poly-infer-must-fail-unknown
 | 
				
			||||||
[ [ drop ] [ drop  ] checked-if* ] poly-infer-must-fail
 | 
					[ "derp" [ "derp" ] if ] poly-infer-must-fail
 | 
				
			||||||
[ [      ] [ drop  ] checked-if* ] poly-infer-must-fail
 | 
					[ [ "derp" ] "derp" if ] poly-infer-must-fail
 | 
				
			||||||
[ [      ] [ 2dup  ] checked-if* ] poly-infer-must-fail
 | 
					[ [ "derp" ] if ] poly-infer-must-fail-unknown
 | 
				
			||||||
 | 
					 | 
				
			||||||
[ "derp" checked-each ] poly-infer-must-fail
 | 
					 | 
				
			||||||
[ checked-each ] poly-infer-must-fail-bad-macro-input
 | 
					 | 
				
			||||||
[ "derp" [ "derp" ] checked-if ] poly-infer-must-fail
 | 
					 | 
				
			||||||
[ [ "derp" ] "derp" checked-if ] poly-infer-must-fail
 | 
					 | 
				
			||||||
[ [ "derp" ] checked-if ] poly-infer-must-fail-bad-macro-input
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,11 +5,13 @@ quotations sequences splitting
 | 
				
			||||||
stack-checker.backend
 | 
					stack-checker.backend
 | 
				
			||||||
stack-checker.errors
 | 
					stack-checker.errors
 | 
				
			||||||
stack-checker.known-words
 | 
					stack-checker.known-words
 | 
				
			||||||
stack-checker.values ;
 | 
					stack-checker.state
 | 
				
			||||||
 | 
					stack-checker.values
 | 
				
			||||||
 | 
					stack-checker.visitor ;
 | 
				
			||||||
IN: stack-checker.row-polymorphism
 | 
					IN: stack-checker.row-polymorphism
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<PRIVATE
 | 
					<PRIVATE
 | 
				
			||||||
SYMBOLS: current-effect-variables current-effect current-meta-d ;
 | 
					SYMBOLS: current-effect-variables current-word-effect current-meta-d ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: quotation-effect? ( in -- ? )
 | 
					: quotation-effect? ( in -- ? )
 | 
				
			||||||
    dup pair? [ second effect? ] [ drop f ] if ;
 | 
					    dup pair? [ second effect? ] [ drop f ] if ;
 | 
				
			||||||
| 
						 | 
					@ -32,7 +34,7 @@ M: curried >error-quot
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: abandon-check ( -- * )
 | 
					: abandon-check ( -- * )
 | 
				
			||||||
    current-word get
 | 
					    current-word get
 | 
				
			||||||
    current-effect get in>> current-meta-d get zip
 | 
					    current-word-effect get in>> current-meta-d get zip
 | 
				
			||||||
    [ first quotation-effect? ] filter
 | 
					    [ first quotation-effect? ] filter
 | 
				
			||||||
    >error-branches-and-quots
 | 
					    >error-branches-and-quots
 | 
				
			||||||
    invalid-quotation-input ;
 | 
					    invalid-quotation-input ;
 | 
				
			||||||
| 
						 | 
					@ -65,23 +67,12 @@ M: curried >error-quot
 | 
				
			||||||
        abandon-check
 | 
					        abandon-check
 | 
				
			||||||
    ] if ;
 | 
					    ] if ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GENERIC: (infer-known) ( known -- effect )
 | 
					: infer-value ( value -- effect )
 | 
				
			||||||
 | 
					    dup known [ nest-visitor init-inference infer-call* current-effect ] with-scope ; inline
 | 
				
			||||||
M: object (infer-known)
 | 
					 | 
				
			||||||
    current-word get bad-macro-input ;
 | 
					 | 
				
			||||||
M: literal (infer-known)
 | 
					 | 
				
			||||||
    value>> dup callable? [ (infer) ] [ abandon-check ] if ;
 | 
					 | 
				
			||||||
M: composed (infer-known)
 | 
					 | 
				
			||||||
    [ quot1>> known (infer-known) ] [ quot2>> known (infer-known) ] bi compose-effects ;
 | 
					 | 
				
			||||||
M: curried (infer-known)
 | 
					 | 
				
			||||||
    (( -- x )) swap quot>> known (infer-known) compose-effects ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: infer-known ( value -- effect )
 | 
					 | 
				
			||||||
    (infer-known) ; inline
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
: check-input ( in value -- )
 | 
					: check-input ( in value -- )
 | 
				
			||||||
    over quotation-effect? [
 | 
					    over quotation-effect? [
 | 
				
			||||||
        [ second ] dip known infer-known (check-input)
 | 
					        [ second ] dip infer-value (check-input)
 | 
				
			||||||
    ] [ 2drop ] if ;
 | 
					    ] [ 2drop ] if ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: normalize-variables ( -- variables' )
 | 
					: normalize-variables ( -- variables' )
 | 
				
			||||||
| 
						 | 
					@ -94,14 +85,16 @@ PRIVATE>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: infer-polymorphic-vars ( effect -- variables )
 | 
					: infer-polymorphic-vars ( effect -- variables )
 | 
				
			||||||
    H{ } clone current-effect-variables set
 | 
					    H{ } clone current-effect-variables set
 | 
				
			||||||
    dup current-effect set
 | 
					    dup current-word-effect set
 | 
				
			||||||
    in>> dup length ensure-d dup current-meta-d set
 | 
					    in>> dup length ensure-d dup current-meta-d set
 | 
				
			||||||
    [ check-input ] 2each
 | 
					    [ check-input ] 2each
 | 
				
			||||||
    normalize-variables ;
 | 
					    normalize-variables ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: check-polymorphic-effect ( word -- )
 | 
					: check-polymorphic-effect ( word -- )
 | 
				
			||||||
    current-word get [
 | 
					    current-word get [
 | 
				
			||||||
        dup current-word set stack-effect infer-polymorphic-vars drop
 | 
					        dup current-word set stack-effect
 | 
				
			||||||
 | 
					        dup { [ in-var>> ] [ out-var>> ] } 1||
 | 
				
			||||||
 | 
					        [ infer-polymorphic-vars ] when drop
 | 
				
			||||||
    ] dip current-word set ;
 | 
					    ] dip current-word set ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SYMBOL: infer-polymorphic?
 | 
					SYMBOL: infer-polymorphic?
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue