1 ! (c)Joe Groff bsd license
2 USING: accessors arrays classes classes.tuple combinators
3 combinators.short-circuit definitions effects fry generalizations
4 hints math kernel kernel.private namespaces parser quotations
5 sequences slots words locals effects.parser
6 locals.parser macros stack-checker.dependencies
7 classes.maybe classes.algebra ;
8 FROM: classes.tuple.private => tuple-layout ;
11 ERROR: type-mismatch-error value expected-type word expected-types ;
12 ERROR: input-mismatch-error < type-mismatch-error ;
13 ERROR: output-mismatch-error < type-mismatch-error ;
14 ERROR: no-types-specified word effect ;
16 PREDICATE: typed-gensym < word "typed-gensym" word-prop >boolean ;
17 PREDICATE: typed-word < word "typed-word" word-prop >boolean ;
21 : unboxable-tuple-class? ( type -- ? )
23 [ only-classoid? not ]
24 [ all-slots empty? not ]
25 [ immutable-tuple-class? ]
31 : typed-stack-effect? ( effect -- ? )
32 [ object = ] all? not ;
34 : add-depends-on-unboxing ( class -- )
35 [ dup tuple-layout add-depends-on-tuple-layout ]
36 [ add-depends-on-final ]
39 : (unboxer) ( type -- quot )
40 dup unboxable-tuple-class? [
41 dup add-depends-on-unboxing
43 [ name>> reader-word 1quotation ]
44 [ class>> (unboxer) ] bi compose
45 ] map [ cleave ] curry
48 :: unboxer ( error-quot word types type -- quot )
49 type word? [ type "coercer" word-prop ] [ f ] if [ ] or
50 type type word types error-quot '[ dup _ instance? [ _ _ _ @ ] unless ]
54 : make-unboxer ( error-quot word types -- quot )
55 dup [ unboxer ] 3 nwith
56 [ swap \ dip [ ] 2sequence prepend ] map-reduce ;
58 : (unboxed-types) ( type -- types )
59 dup unboxable-tuple-class?
61 dup add-depends-on-unboxing
62 all-slots [ class>> (unboxed-types) ] map concat
66 : unboxed-types ( types -- types' )
67 [ (unboxed-types) ] map concat ;
69 :: typed-inputs ( quot word types -- quot' )
70 types unboxed-types :> unboxed-types
72 [ throw-input-mismatch-error ] word types make-unboxer
73 unboxed-types quot '[ _ declare @ ]
78 :: typed-outputs ( quot word types -- quot' )
79 [ throw-output-mismatch-error ] word types make-unboxer
84 : boxer ( type -- quot )
85 dup unboxable-tuple-class?
87 dup add-depends-on-unboxing
88 [ all-slots [ class>> ] map make-boxer ]
94 : make-boxer ( types -- quot )
96 [ [ boxer ] [ swap '[ @ _ dip ] ] map-reduce ] if-empty ;
98 ! defining typed words
100 MACRO: (typed) ( word def effect -- quot )
103 nip effect-in-types swap
104 [ [ unboxed-types ] [ make-boxer ] bi ] dip
109 dup typed-stack-effect? [ typed-outputs ] [ 2drop ] if
112 : <typed-gensym> ( parent-word -- word )
113 [ name>> "( typed " " )" surround f <word> dup ]
114 [ "typed-gensym" set-word-prop ] bi ;
116 : unboxed-effect ( effect -- effect' )
117 [ effect-in-types unboxed-types [ "in" swap 2array ] map ]
118 [ effect-out-types unboxed-types [ "out" swap 2array ] map ] bi <effect> ;
120 M: typed-gensym stack-effect call-next-method unboxed-effect ;
121 M: typed-gensym parent-word "typed-gensym" word-prop ;
122 M: typed-gensym crossref? parent-word crossref? ;
123 M: typed-gensym where parent-word where ;
125 : define-typed-gensym ( word def effect -- gensym )
126 [ 2drop <typed-gensym> dup ]
127 [ [ (typed) ] 3curry ]
128 [ 2nip ] 3tri define-declared ;
130 MACRO: typed ( quot word effect -- quot' )
131 [ effect-in-types dup typed-stack-effect? [ typed-inputs ] [ 2drop ] if ]
133 nip effect-out-types dup typed-stack-effect?
134 [ [ unboxed-types ] [ make-boxer ] bi '[ @ _ declare @ ] ] [ drop ] if
137 : (typed-def) ( word def effect -- quot )
138 [ define-typed-gensym ] 3keep
139 [ drop [ swap "typed-word" set-word-prop ] [ [ 1quotation ] dip ] 2bi ] dip
142 : typed-def ( word def effect -- quot )
144 [ effect-in-types typed-stack-effect? ]
145 [ effect-out-types typed-stack-effect? ]
146 } 1|| [ (typed-def) ] [ nip throw-no-types-specified ] if ;
148 M: typed-word subwords
150 [ "typed-word" word-prop ] bi suffix ;
154 : define-typed ( word def effect -- )
155 [ [ 2drop ] [ typed-def ] [ 2nip ] 3tri define-inline ]
156 [ drop "typed-def" set-word-prop ]
157 [ 2drop "typed-word" word-prop set-last-word ] 3tri ;
166 { "typed" "prettyprint" } "typed.prettyprint" require-when
167 { "typed" "compiler.cfg.debugger" } "typed.debugger" require-when