unbox read-only tuple arguments and box read-only tuple results to TYPED: words in the inlined wrapper code to avoid allocation of unboxable tuples
parent
c00963950d
commit
d5b4202f6a
|
@ -1,4 +1,4 @@
|
||||||
USING: kernel layouts math quotations tools.test typed ;
|
USING: accessors effects kernel layouts math quotations tools.test typed words ;
|
||||||
IN: typed.tests
|
IN: typed.tests
|
||||||
|
|
||||||
TYPED: f+ ( a: float b: float -- c: float )
|
TYPED: f+ ( a: float b: float -- c: float )
|
||||||
|
@ -35,3 +35,21 @@ TYPED:: f+locals ( a: float b: float -- c: float )
|
||||||
a b + ;
|
a b + ;
|
||||||
|
|
||||||
[ 3.5 ] [ 2 1+1/2 f+locals ] unit-test
|
[ 3.5 ] [ 2 1+1/2 f+locals ] unit-test
|
||||||
|
|
||||||
|
TUPLE: unboxable
|
||||||
|
{ x fixnum read-only }
|
||||||
|
{ y fixnum read-only } ;
|
||||||
|
|
||||||
|
TUPLE: unboxable2
|
||||||
|
{ u unboxable read-only }
|
||||||
|
{ xy fixnum read-only } ;
|
||||||
|
|
||||||
|
TYPED: unboxy ( in: unboxable -- out: unboxable2 )
|
||||||
|
dup [ x>> ] [ y>> ] bi - unboxable2 boa ;
|
||||||
|
|
||||||
|
[ (( in: fixnum in: fixnum -- out: fixnum out: fixnum out: fixnum )) ]
|
||||||
|
[ \ unboxy "typed-word" word-prop stack-effect ] unit-test
|
||||||
|
|
||||||
|
[ T{ unboxable2 { u T{ unboxable { x 12 } { y 3 } } } { xy 9 } } ]
|
||||||
|
[ T{ unboxable { x 12 } { y 3 } } unboxy ] unit-test
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,21 @@
|
||||||
! (c)Joe Groff bsd license
|
! (c)Joe Groff bsd license
|
||||||
USING: accessors arrays combinators combinators.short-circuit
|
USING: accessors arrays classes classes.tuple combinators
|
||||||
definitions effects fry hints math kernel kernel.private namespaces
|
combinators.short-circuit definitions effects fry hints
|
||||||
parser quotations see.private sequences words
|
math kernel kernel.private namespaces parser quotations
|
||||||
locals locals.definitions locals.parser ;
|
see.private sequences slots words locals locals.definitions
|
||||||
|
locals.parser ;
|
||||||
IN: typed
|
IN: typed
|
||||||
|
|
||||||
ERROR: type-mismatch-error word expected-types ;
|
ERROR: type-mismatch-error word expected-types ;
|
||||||
ERROR: input-mismatch-error < type-mismatch-error ;
|
ERROR: input-mismatch-error < type-mismatch-error ;
|
||||||
ERROR: output-mismatch-error < type-mismatch-error ;
|
ERROR: output-mismatch-error < type-mismatch-error ;
|
||||||
|
|
||||||
|
: unboxable-tuple-class? ( type -- ? )
|
||||||
|
{
|
||||||
|
[ all-slots empty? not ]
|
||||||
|
[ immutable-tuple-class? ]
|
||||||
|
} 1&& ;
|
||||||
|
|
||||||
! typed inputs
|
! typed inputs
|
||||||
|
|
||||||
: typed-stack-effect? ( effect -- ? )
|
: typed-stack-effect? ( effect -- ? )
|
||||||
|
@ -17,45 +24,79 @@ ERROR: output-mismatch-error < type-mismatch-error ;
|
||||||
: input-mismatch-quot ( word types -- quot )
|
: input-mismatch-quot ( word types -- quot )
|
||||||
[ input-mismatch-error ] 2curry ;
|
[ input-mismatch-error ] 2curry ;
|
||||||
|
|
||||||
: make-coercer ( types -- quot )
|
: (unboxer) ( type -- quot )
|
||||||
[ "coercer" word-prop [ ] or ]
|
dup unboxable-tuple-class? [
|
||||||
[ swap \ dip [ ] 2sequence prepend ]
|
all-slots [
|
||||||
map-reduce ;
|
[ name>> reader-word 1quotation ]
|
||||||
|
[ class>> (unboxer) ] bi compose
|
||||||
|
] map [ cleave ] curry
|
||||||
|
] [ drop [ ] ] if ;
|
||||||
|
|
||||||
: typed-inputs ( quot word types -- quot' )
|
:: unboxer ( error-quot word types type -- quot )
|
||||||
{
|
type "coercer" word-prop [ ] or
|
||||||
[ 2nip make-coercer ]
|
[ dup type instance? [ word types error-quot call ] unless ]
|
||||||
[ 2nip make-specializer ]
|
type (unboxer)
|
||||||
[ nip swap '[ _ declare @ ] ]
|
compose compose ;
|
||||||
[ [ drop ] 2dip input-mismatch-quot ]
|
|
||||||
} 3cleave '[ @ @ _ _ if ] ;
|
: make-unboxer ( error-quot word types -- quot )
|
||||||
|
dup [ unboxer ] with with with
|
||||||
|
[ swap \ dip [ ] 2sequence prepend ] map-reduce ;
|
||||||
|
|
||||||
|
: (unboxed-types) ( type -- types )
|
||||||
|
dup unboxable-tuple-class?
|
||||||
|
[ all-slots [ class>> (unboxed-types) ] map concat ]
|
||||||
|
[ 1array ] if ;
|
||||||
|
|
||||||
|
: unboxed-types ( types -- types' )
|
||||||
|
[ (unboxed-types) ] map concat ;
|
||||||
|
|
||||||
|
:: typed-inputs ( quot word types -- quot' )
|
||||||
|
types unboxed-types :> unboxed-types
|
||||||
|
|
||||||
|
[ input-mismatch-error ] word types make-unboxer
|
||||||
|
unboxed-types quot '[ _ declare @ ]
|
||||||
|
compose ;
|
||||||
|
|
||||||
! typed outputs
|
! typed outputs
|
||||||
|
|
||||||
: output-mismatch-quot ( word types -- quot )
|
: output-mismatch-quot ( word types -- quot )
|
||||||
[ output-mismatch-error ] 2curry ;
|
[ output-mismatch-error ] 2curry ;
|
||||||
|
|
||||||
: typed-outputs ( quot word types -- quot' )
|
:: typed-outputs ( quot word types -- quot' )
|
||||||
{
|
[ output-mismatch-error ] word types make-unboxer
|
||||||
[ 2drop ]
|
quot prepose ;
|
||||||
[ 2nip make-coercer ]
|
|
||||||
[ 2nip make-specializer ]
|
DEFER: make-boxer
|
||||||
[ [ drop ] 2dip output-mismatch-quot ]
|
|
||||||
} 3cleave '[ @ @ @ _ unless ] ;
|
: boxer ( type -- quot )
|
||||||
|
dup unboxable-tuple-class?
|
||||||
|
[ [ all-slots [ class>> ] map make-boxer ] [ [ boa ] curry ] bi compose ]
|
||||||
|
[ drop [ ] ] if ;
|
||||||
|
|
||||||
|
: make-boxer ( types -- quot )
|
||||||
|
[ boxer ] [ swap '[ @ _ dip ] ] map-reduce ;
|
||||||
|
|
||||||
! defining typed words
|
! defining typed words
|
||||||
|
|
||||||
: typed-gensym-quot ( def word effect -- quot )
|
: typed-gensym-quot ( def word effect -- quot )
|
||||||
[ nip effect-in-types swap '[ _ declare @ ] ]
|
[
|
||||||
|
nip effect-in-types swap
|
||||||
|
[ [ unboxed-types ] [ make-boxer ] bi ] dip
|
||||||
|
'[ _ declare @ @ ]
|
||||||
|
]
|
||||||
[ effect-out-types dup typed-stack-effect? [ typed-outputs ] [ 2drop ] if ] 2bi ;
|
[ effect-out-types dup typed-stack-effect? [ typed-outputs ] [ 2drop ] if ] 2bi ;
|
||||||
|
|
||||||
: typed-gensym ( parent-word -- word )
|
: typed-gensym ( parent-word -- word )
|
||||||
name>> "( typed " " )" surround f <word> ;
|
name>> "( typed " " )" surround f <word> ;
|
||||||
|
|
||||||
|
: unboxed-effect ( effect -- effect' )
|
||||||
|
[ effect-in-types unboxed-types [ "in" swap 2array ] map ]
|
||||||
|
[ effect-out-types unboxed-types [ "out" swap 2array ] map ] bi <effect> ;
|
||||||
|
|
||||||
: define-typed-gensym ( word def effect -- gensym )
|
: define-typed-gensym ( word def effect -- gensym )
|
||||||
[ 2drop typed-gensym dup ]
|
[ 2drop typed-gensym dup ]
|
||||||
[ [ swap ] dip typed-gensym-quot ]
|
[ [ swap ] dip typed-gensym-quot ]
|
||||||
[ 2nip ] 3tri define-declared ;
|
[ 2nip unboxed-effect ] 3tri define-declared ;
|
||||||
|
|
||||||
PREDICATE: typed-standard-word < word "typed-word" word-prop ;
|
PREDICATE: typed-standard-word < word "typed-word" word-prop ;
|
||||||
PREDICATE: typed-lambda-word < lambda-word "typed-word" word-prop ;
|
PREDICATE: typed-lambda-word < lambda-word "typed-word" word-prop ;
|
||||||
|
@ -64,7 +105,10 @@ UNION: typed-word typed-standard-word typed-lambda-word ;
|
||||||
|
|
||||||
: typed-quot ( quot word effect -- quot' )
|
: typed-quot ( quot word effect -- quot' )
|
||||||
[ effect-in-types dup typed-stack-effect? [ typed-inputs ] [ 2drop ] if ]
|
[ effect-in-types dup typed-stack-effect? [ typed-inputs ] [ 2drop ] if ]
|
||||||
[ nip effect-out-types dup typed-stack-effect? [ '[ @ _ declare ] ] [ drop ] if ] 2bi ;
|
[
|
||||||
|
nip effect-out-types dup typed-stack-effect?
|
||||||
|
[ [ unboxed-types ] [ make-boxer ] bi '[ @ _ declare @ ] ] [ drop ] if
|
||||||
|
] 2bi ;
|
||||||
|
|
||||||
: (typed-def) ( word def effect -- quot )
|
: (typed-def) ( word def effect -- quot )
|
||||||
[ define-typed-gensym ] 3keep
|
[ define-typed-gensym ] 3keep
|
||||||
|
|
Loading…
Reference in New Issue