working on type inference
parent
869430fae0
commit
43cd7b171e
|
@ -90,6 +90,7 @@ parser prettyprint sequences io vectors words ;
|
||||||
"/library/inference/words.factor"
|
"/library/inference/words.factor"
|
||||||
"/library/inference/stack.factor"
|
"/library/inference/stack.factor"
|
||||||
"/library/inference/partial-eval.factor"
|
"/library/inference/partial-eval.factor"
|
||||||
|
"/library/inference/class-infer.factor"
|
||||||
"/library/inference/optimizer.factor"
|
"/library/inference/optimizer.factor"
|
||||||
"/library/inference/print-dataflow.factor"
|
"/library/inference/print-dataflow.factor"
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,6 @@ USING: alien assembler command-line compiler generic hashtables
|
||||||
kernel lists memory namespaces parser sequences io unparser
|
kernel lists memory namespaces parser sequences io unparser
|
||||||
words ;
|
words ;
|
||||||
|
|
||||||
\ fiber? t "inline" set-word-prop
|
|
||||||
|
|
||||||
: pull-in ( ? list -- )
|
: pull-in ( ? list -- )
|
||||||
swap [
|
swap [
|
||||||
[
|
[
|
||||||
|
|
|
@ -24,13 +24,9 @@ builtin 50 "priority" set-word-prop
|
||||||
! All builtin types are equivalent in ordering
|
! All builtin types are equivalent in ordering
|
||||||
builtin [ 2drop t ] "class<" set-word-prop
|
builtin [ 2drop t ] "class<" set-word-prop
|
||||||
|
|
||||||
: builtin-predicate ( class -- )
|
: builtin-predicate ( class predicate -- )
|
||||||
dup "predicate" word-prop car
|
2dup register-predicate
|
||||||
dup t "inline" set-word-prop
|
[ \ type , swap "builtin-type" word-prop , \ eq? , ] make-list
|
||||||
swap
|
|
||||||
[
|
|
||||||
\ type , "builtin-type" word-prop , \ eq? ,
|
|
||||||
] make-list
|
|
||||||
define-compound ;
|
define-compound ;
|
||||||
|
|
||||||
: register-builtin ( class -- )
|
: register-builtin ( class -- )
|
||||||
|
@ -41,8 +37,7 @@ builtin [ 2drop t ] "class<" set-word-prop
|
||||||
dup intern-symbol
|
dup intern-symbol
|
||||||
dup r> "builtin-type" set-word-prop
|
dup r> "builtin-type" set-word-prop
|
||||||
dup builtin define-class
|
dup builtin define-class
|
||||||
dup r> unit "predicate" set-word-prop
|
dup r> builtin-predicate
|
||||||
dup builtin-predicate
|
|
||||||
dup r> intern-slots 2dup "slots" set-word-prop
|
dup r> intern-slots 2dup "slots" set-word-prop
|
||||||
define-slots
|
define-slots
|
||||||
register-builtin ;
|
register-builtin ;
|
||||||
|
|
|
@ -8,23 +8,12 @@ math-internals ;
|
||||||
! A simple single-dispatch generic word system.
|
! A simple single-dispatch generic word system.
|
||||||
|
|
||||||
: predicate-word ( word -- word )
|
: predicate-word ( word -- word )
|
||||||
word-name "?" append create-in
|
word-name "?" append create-in ;
|
||||||
dup t "inline" set-word-prop ;
|
|
||||||
|
|
||||||
! Terminology:
|
: register-predicate ( class predicate -- )
|
||||||
! - type: a datatype built in to the runtime, eg fixnum, word
|
2dup unit "predicate" set-word-prop
|
||||||
! cons. All objects have exactly one type, new types cannot be
|
swap "predicating" set-word-prop ;
|
||||||
! defined, and types are disjoint.
|
|
||||||
! - class: a user defined way of differentiating objects, either
|
|
||||||
! based on type, or some combination of type, predicate, or
|
|
||||||
! method map.
|
|
||||||
! - metaclass: a metaclass is a symbol with a handful of word
|
|
||||||
! properties: "builtin-supertypes" "priority" "add-method"
|
|
||||||
! "class<"
|
|
||||||
|
|
||||||
! So far, only tuples can have delegates, which also must be
|
|
||||||
! tuples (the UI uses numbers as delegates in a couple of places
|
|
||||||
! but this is Unsupported(tm)).
|
|
||||||
GENERIC: delegate
|
GENERIC: delegate
|
||||||
GENERIC: set-delegate
|
GENERIC: set-delegate
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,6 @@ hashtables errors sequences vectors ;
|
||||||
#! specifying an incorrect size.
|
#! specifying an incorrect size.
|
||||||
<tuple> [ 2 set-slot ] keep ;
|
<tuple> [ 2 set-slot ] keep ;
|
||||||
|
|
||||||
: class-tuple 2 slot ; inline
|
|
||||||
|
|
||||||
IN: generic
|
IN: generic
|
||||||
|
|
||||||
DEFER: tuple?
|
DEFER: tuple?
|
||||||
|
@ -30,18 +28,15 @@ M: tuple set-delegate 3 set-slot ;
|
||||||
|
|
||||||
: class ( obj -- class )
|
: class ( obj -- class )
|
||||||
#! The class of an object.
|
#! The class of an object.
|
||||||
dup tuple? [ class-tuple ] [ type builtin-type ] ifte ;
|
dup tuple? [ 2 slot ] [ type builtin-type ] ifte ; inline
|
||||||
|
|
||||||
: tuple-predicate ( word -- )
|
: tuple-predicate ( word -- )
|
||||||
#! Make a foo? word for testing the tuple class at the top
|
#! Make a foo? word for testing the tuple class at the top
|
||||||
#! of the stack.
|
#! of the stack.
|
||||||
dup predicate-word 2dup unit "predicate" set-word-prop
|
dup predicate-word
|
||||||
swap [
|
2dup register-predicate
|
||||||
[ dup tuple? ] %
|
swap [ \ class , literal, \ eq? , ] make-list
|
||||||
[ \ class-tuple , literal, \ eq? , ] make-list ,
|
define-compound ;
|
||||||
[ drop f ] ,
|
|
||||||
\ ifte ,
|
|
||||||
] make-list define-compound ;
|
|
||||||
|
|
||||||
: forget-tuple ( class -- )
|
: forget-tuple ( class -- )
|
||||||
dup forget "predicate" word-prop car [ forget ] when* ;
|
dup forget "predicate" word-prop car [ forget ] when* ;
|
||||||
|
@ -136,7 +131,7 @@ M: tuple set-delegate 3 set-slot ;
|
||||||
#! for methods defined on the given generic.
|
#! for methods defined on the given generic.
|
||||||
dup default-tuple-method \ drop swons
|
dup default-tuple-method \ drop swons
|
||||||
over tuple-methods hash>quot
|
over tuple-methods hash>quot
|
||||||
>r "picker" word-prop [ class-tuple ] r> append3 ;
|
>r "picker" word-prop [ class ] r> append3 ;
|
||||||
|
|
||||||
: add-tuple-dispatch ( word vtable -- )
|
: add-tuple-dispatch ( word vtable -- )
|
||||||
>r tuple-dispatch-quot tuple r> set-vtable ;
|
>r tuple-dispatch-quot tuple r> set-vtable ;
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
! Copyright (C) 2004, 2005 Slava Pestov.
|
! Copyright (C) 2004, 2005 Slava Pestov.
|
||||||
! See http://factor.sf.net/license.txt for BSD license.
|
! See http://factor.sf.net/license.txt for BSD license.
|
||||||
IN: inference
|
IN: inference
|
||||||
USING: generic hashtables kernel namespaces sequences words ;
|
USING: generic hashtables kernel namespaces sequences vectors
|
||||||
|
words ;
|
||||||
|
|
||||||
! Infer possible classes of values in a dataflow IR.
|
! Infer possible classes of values in a dataflow IR.
|
||||||
|
|
||||||
|
@ -10,54 +11,121 @@ USING: generic hashtables kernel namespaces sequences words ;
|
||||||
! Current value --> class mapping
|
! Current value --> class mapping
|
||||||
SYMBOL: value-classes
|
SYMBOL: value-classes
|
||||||
|
|
||||||
TUPLE: possibility value class ;
|
! Current value --> literal mapping
|
||||||
|
SYMBOL: value-literals
|
||||||
|
|
||||||
! Maps possibilities to possibilities.
|
GENERIC: apply-tie ( tie -- )
|
||||||
SYMBOL: possible-classes
|
|
||||||
|
M: f apply-tie ( f -- ) drop ;
|
||||||
|
|
||||||
|
TUPLE: class-tie value class ;
|
||||||
|
|
||||||
|
: set-value-class ( class value -- )
|
||||||
|
2dup swap <class-tie> ties get hash [ apply-tie ] when*
|
||||||
|
value-classes get set-hash ;
|
||||||
|
|
||||||
|
M: class-tie apply-tie ( tie -- )
|
||||||
|
dup class-tie-class swap class-tie-value
|
||||||
|
set-value-class ;
|
||||||
|
|
||||||
|
TUPLE: literal-tie value literal ;
|
||||||
|
|
||||||
|
: set-value-literal ( literal value -- )
|
||||||
|
over class over set-value-class
|
||||||
|
2dup swap <literal-tie> ties get hash [ apply-tie ] when*
|
||||||
|
value-literals get set-hash ;
|
||||||
|
|
||||||
|
M: literal-tie apply-tie ( tie -- )
|
||||||
|
dup literal-tie-literal swap literal-tie-value
|
||||||
|
set-value-literal ;
|
||||||
|
|
||||||
|
! Maps ties to ties
|
||||||
|
SYMBOL: ties
|
||||||
|
|
||||||
GENERIC: infer-classes* ( node -- )
|
GENERIC: infer-classes* ( node -- )
|
||||||
|
|
||||||
|
M: node infer-classes* ( node -- ) drop ;
|
||||||
|
|
||||||
|
! For conditionals, a map of child node # --> possibility
|
||||||
|
GENERIC: child-ties ( node -- seq )
|
||||||
|
|
||||||
|
M: node child-ties ( node -- seq )
|
||||||
|
node-children length f <repeated> ;
|
||||||
|
|
||||||
: value-class ( value -- class )
|
: value-class ( value -- class )
|
||||||
value-classes get hash [ object ] unless* ;
|
value-classes get hash [ object ] unless* ;
|
||||||
|
|
||||||
|
: value-literal ( value -- class )
|
||||||
|
value-literals get hash ;
|
||||||
|
|
||||||
: annotate-node ( node -- )
|
: annotate-node ( node -- )
|
||||||
#! Annotate the node with the currently-inferred set of
|
#! Annotate the node with the currently-inferred set of
|
||||||
#! value classes.
|
#! value classes.
|
||||||
dup node-values [ value-class ] map>hash
|
dup node-values ( 2dup )
|
||||||
swap set-node-classes ;
|
[ value-class ] map>hash swap set-node-classes
|
||||||
|
( [ value-literal ] map>hash swap set-node-literals ) ;
|
||||||
M: node infer-classes* ( node -- ) drop ;
|
|
||||||
|
|
||||||
: assume-classes ( classes values -- )
|
: assume-classes ( classes values -- )
|
||||||
[ value-classes get set-hash ] 2each ;
|
[ set-value-class ] 2each ;
|
||||||
|
|
||||||
|
: assume-literals ( literals values -- )
|
||||||
|
[ set-value-literal ] 2each ;
|
||||||
|
|
||||||
: intersect-classes ( classes values -- )
|
: intersect-classes ( classes values -- )
|
||||||
[ [ value-class class-and ] 2map ] keep assume-classes ;
|
[ [ value-class class-and ] 2map ] keep assume-classes ;
|
||||||
|
|
||||||
|
: create-ties ( #call -- )
|
||||||
|
#! If the node is calling a class test predicate, create a
|
||||||
|
#! tie.
|
||||||
|
dup node-param "predicating" word-prop dup [
|
||||||
|
>r dup node-in-d first r> <class-tie>
|
||||||
|
swap node-out-d first general-t <class-tie>
|
||||||
|
ties get set-hash
|
||||||
|
] [
|
||||||
|
2drop
|
||||||
|
] ifte ;
|
||||||
|
|
||||||
M: #call infer-classes* ( node -- )
|
M: #call infer-classes* ( node -- )
|
||||||
|
dup create-ties
|
||||||
dup node-param "infer-effect" word-prop 2unseq
|
dup node-param "infer-effect" word-prop 2unseq
|
||||||
pick node-out-d assume-classes
|
pick node-out-d assume-classes
|
||||||
swap node-in-d intersect-classes ;
|
swap node-in-d intersect-classes ;
|
||||||
|
|
||||||
M: #push infer-classes* ( node -- )
|
M: #push infer-classes* ( node -- )
|
||||||
node-out-d [
|
node-out-d [ safe-literal? ] subset
|
||||||
dup safe-literal? [
|
dup [ literal-value ] map
|
||||||
[ literal-value class ] keep
|
swap assume-literals ;
|
||||||
value-classes get set-hash
|
|
||||||
] [
|
M: #ifte child-ties ( node -- seq )
|
||||||
drop
|
node-in-d first dup general-t <class-tie>
|
||||||
] ifte
|
swap f <literal-tie> 2vector ;
|
||||||
] each ;
|
|
||||||
|
M: #dispatch child-ties ( node -- seq )
|
||||||
|
dup node-in-d first
|
||||||
|
swap node-children length [ <literal-tie> ] map-with ;
|
||||||
|
|
||||||
|
DEFER: (infer-classes)
|
||||||
|
|
||||||
|
: infer-children ( node -- )
|
||||||
|
dup node-children swap child-ties [
|
||||||
|
[
|
||||||
|
value-classes [ clone ] change
|
||||||
|
ties [ clone ] change
|
||||||
|
apply-tie
|
||||||
|
(infer-classes)
|
||||||
|
] with-scope
|
||||||
|
] 2each ;
|
||||||
|
|
||||||
: (infer-classes) ( node -- )
|
: (infer-classes) ( node -- )
|
||||||
dup infer-classes*
|
dup infer-classes*
|
||||||
dup annotate-node
|
dup annotate-node
|
||||||
dup node-children [ (infer-classes) ] each
|
dup infer-children
|
||||||
node-successor [ (infer-classes) ] when* ;
|
node-successor [ (infer-classes) ] when* ;
|
||||||
|
|
||||||
: infer-classes ( node -- )
|
: infer-classes ( node -- )
|
||||||
[
|
[
|
||||||
<namespace> value-classes set
|
<namespace> value-classes set
|
||||||
<namespace> possible-classes set
|
<namespace> value-literals set
|
||||||
|
<namespace> ties set
|
||||||
(infer-classes)
|
(infer-classes)
|
||||||
] with-scope ;
|
] with-scope ;
|
||||||
|
|
|
@ -9,12 +9,12 @@ sequences vectors words ;
|
||||||
! code with stack flow information and types.
|
! code with stack flow information and types.
|
||||||
|
|
||||||
TUPLE: node param in-d out-d in-r out-r
|
TUPLE: node param in-d out-d in-r out-r
|
||||||
classes successor children ;
|
classes literals successor children ;
|
||||||
|
|
||||||
M: node = eq? ;
|
M: node = eq? ;
|
||||||
|
|
||||||
: make-node ( param in-d out-d in-r out-r node -- node )
|
: make-node ( param in-d out-d in-r out-r node -- node )
|
||||||
[ >r f f f <node> r> set-delegate ] keep ;
|
[ >r f f f f <node> r> set-delegate ] keep ;
|
||||||
|
|
||||||
: param-node ( label) f f f f ;
|
: param-node ( label) f f f f ;
|
||||||
: in-d-node ( inputs) >r f r> f f f ;
|
: in-d-node ( inputs) >r f r> f f f ;
|
||||||
|
|
|
@ -92,7 +92,7 @@ M: f can-kill* ( literal node -- ? )
|
||||||
2drop t ;
|
2drop t ;
|
||||||
|
|
||||||
M: node can-kill* ( literal node -- ? )
|
M: node can-kill* ( literal node -- ? )
|
||||||
uses-value? ;
|
uses-value? not ;
|
||||||
|
|
||||||
M: node kill-node* ( literals node -- )
|
M: node kill-node* ( literals node -- )
|
||||||
2drop ;
|
2drop ;
|
||||||
|
|
|
@ -14,7 +14,7 @@ M: annotation prettyprint* ( ann -- )
|
||||||
swap annotation-node object. ;
|
swap annotation-node object. ;
|
||||||
|
|
||||||
: value-str ( classes values -- str )
|
: value-str ( classes values -- str )
|
||||||
[ swap ?hash [ [ object ] ] unless* ] map-with
|
[ swap ?hash [ object ] unless* ] map-with
|
||||||
[ word-name ] map
|
[ word-name ] map
|
||||||
" " join ;
|
" " join ;
|
||||||
|
|
||||||
|
|
|
@ -5,18 +5,18 @@ USING: gadgets namespaces styles test ;
|
||||||
0 x set
|
0 x set
|
||||||
0 y set
|
0 y set
|
||||||
|
|
||||||
[ [ 255 0 0 ] ] [ { 1 0 0 } red green <gradient> 0 gradient-color ] unit-test
|
[ { 255 0 0 } ] [ { 1 0 0 } red green <gradient> 0 gradient-color ] unit-test
|
||||||
[ [ 0 255 0 ] ] [ { 1 0 0 } red green <gradient> 1 gradient-color ] unit-test
|
[ { 0 255 0 } ] [ { 1 0 0 } red green <gradient> 1 gradient-color ] unit-test
|
||||||
|
|
||||||
[ 0 100 0 [ 255 0 0 ] ]
|
[ 0 100 0 { 255 0 0 } ]
|
||||||
[ { 0 1 0 } red green <gradient> { 100 200 0 } 0 (gradient-x) ] unit-test
|
[ { 0 1 0 } red green <gradient> { 100 200 0 } 0 (gradient-x) ] unit-test
|
||||||
|
|
||||||
[ 0 100 100 [ 255/2 255/2 0 ] ]
|
[ 0 100 100 [ 255/2 255/2 0 ] ]
|
||||||
[ { 0 1 0 } red green <gradient> { 100 200 0 } 100 (gradient-x) ] unit-test
|
[ { 0 1 0 } red green <gradient> { 100 200 0 } 100 (gradient-x) ] unit-test
|
||||||
|
|
||||||
[ 0 0 200 [ 255 0 0 ] ]
|
[ 0 0 200 { 255 0 0 } ]
|
||||||
[ { 1 0 0 } red green <gradient> { 100 200 0 } 0 (gradient-y) ] unit-test
|
[ { 1 0 0 } red green <gradient> { 100 200 0 } 0 (gradient-y) ] unit-test
|
||||||
|
|
||||||
[ 50 0 200 [ 255/2 255/2 0 ] ]
|
[ 50 0 200 { 255/2 255/2 0 } ]
|
||||||
[ { 1 0 0 } red green <gradient> { 100 200 0 } 50 (gradient-y) ] unit-test
|
[ { 1 0 0 } red green <gradient> { 100 200 0 } 50 (gradient-y) ] unit-test
|
||||||
] with-scope
|
] with-scope
|
||||||
|
|
|
@ -8,7 +8,6 @@ USE: strings
|
||||||
USE: sequences
|
USE: sequences
|
||||||
|
|
||||||
[ { [ 3 2 1 ] [ 5 4 3 ] [ 6 ] } ]
|
[ { [ 3 2 1 ] [ 5 4 3 ] [ 6 ] } ]
|
||||||
[ [ 1 2 3 ] [ 3 4 5 ] [ 6 ] 3vector [ reverse ] map ] unit-test
|
|
||||||
|
|
||||||
[ [ "a" 43 [ ] ] ] [ [ "a" 43 43 43 [ ] 43 "a" [ ] ] prune ] unit-test
|
[ [ "a" 43 [ ] ] ] [ [ "a" 43 43 43 [ ] 43 "a" [ ] ] prune ] unit-test
|
||||||
|
|
||||||
|
|
|
@ -8,4 +8,4 @@ USE: test
|
||||||
: foo 1 2 3 ;
|
: foo 1 2 3 ;
|
||||||
|
|
||||||
[ 1 2 3 1 2 3 ] [ bar ] unit-test
|
[ 1 2 3 1 2 3 ] [ bar ] unit-test
|
||||||
[ [ [ ] [ fixnum fixnum fixnum ] ] ] [ [ foo ] infer ] unit-test
|
[ [ [ 0 3 ] ] ] [ [ foo ] infer ] unit-test
|
||||||
|
|
|
@ -69,3 +69,5 @@ unit-test
|
||||||
[ { 1 2 3 } ] [ 1 2 3 3vector ] unit-test
|
[ { 1 2 3 } ] [ 1 2 3 3vector ] unit-test
|
||||||
|
|
||||||
[ { } ] [ { } seq-transpose ] unit-test
|
[ { } ] [ { } seq-transpose ] unit-test
|
||||||
|
|
||||||
|
[ [ 1 2 3 ] [ 3 4 5 ] [ 6 ] 3vector [ reverse ] map ] unit-test
|
||||||
|
|
Loading…
Reference in New Issue