1 ! (c)Joe Groff bsd license
2 USING: accessors arrays combinators combinators.short-circuit
3 definitions effects fry hints math kernel kernel.private namespaces
4 parser quotations see.private sequences words
5 locals locals.definitions locals.parser ;
8 ERROR: type-mismatch-error word expected-types ;
9 ERROR: input-mismatch-error < type-mismatch-error ;
10 ERROR: output-mismatch-error < type-mismatch-error ;
14 : typed-stack-effect? ( effect -- ? )
15 [ object = ] all? not ;
17 : input-mismatch-quot ( word types -- quot )
18 [ input-mismatch-error ] 2curry ;
20 : make-coercer ( types -- quot )
21 [ "coercer" word-prop [ ] or ]
22 [ swap \ dip [ ] 2sequence prepend ]
25 : typed-inputs ( quot word types -- quot' )
28 [ 2nip make-specializer ]
29 [ nip swap '[ _ declare @ ] ]
30 [ [ drop ] 2dip input-mismatch-quot ]
31 } 3cleave '[ @ @ _ _ if ] ;
35 : output-mismatch-quot ( word types -- quot )
36 [ output-mismatch-error ] 2curry ;
38 : typed-outputs ( quot word types -- quot' )
42 [ 2nip make-specializer ]
43 [ [ drop ] 2dip output-mismatch-quot ]
44 } 3cleave '[ @ @ @ _ unless ] ;
46 ! defining typed words
48 : typed-gensym-quot ( def word effect -- quot )
49 [ nip effect-in-types swap '[ _ declare @ ] ]
50 [ effect-out-types dup typed-stack-effect? [ typed-outputs ] [ 2drop ] if ] 2bi ;
52 : typed-gensym ( parent-word -- word )
53 name>> "( typed " " )" surround f <word> ;
55 : define-typed-gensym ( word def effect -- gensym )
56 [ 2drop typed-gensym dup ]
57 [ [ swap ] dip typed-gensym-quot ]
58 [ 2nip ] 3tri define-declared ;
60 PREDICATE: typed-standard-word < word "typed-word" word-prop ;
61 PREDICATE: typed-lambda-word < lambda-word "typed-word" word-prop ;
63 UNION: typed-word typed-standard-word typed-lambda-word ;
65 : typed-quot ( quot word effect -- quot' )
66 [ effect-in-types dup typed-stack-effect? [ typed-inputs ] [ 2drop ] if ]
67 [ nip effect-out-types dup typed-stack-effect? [ '[ @ _ declare ] ] [ drop ] if ] 2bi ;
69 : (typed-def) ( word def effect -- quot )
70 [ define-typed-gensym ] 3keep
71 [ drop [ swap "typed-word" set-word-prop ] [ [ 1quotation ] dip ] 2bi ] dip
74 : typed-def ( word def effect -- quot )
76 [ effect-in-types typed-stack-effect? ]
77 [ effect-out-types typed-stack-effect? ]
78 } 1|| [ (typed-def) ] [ drop nip ] if ;
80 : define-typed ( word def effect -- )
81 [ [ 2drop ] [ typed-def ] [ 2nip ] 3tri define-inline ]
82 [ drop "typed-def" set-word-prop ]
83 [ 2drop "typed-word" word-prop \ word set-global ] 3tri ;
90 M: typed-standard-word definer drop \ TYPED: \ ; ;
91 M: typed-lambda-word definer drop \ TYPED:: \ ; ;
93 M: typed-word definition "typed-def" word-prop ;
94 M: typed-word declarations. "typed-word" word-prop declarations. ;
96 M: typed-word subwords "typed-word" word-prop 1array ;