1 ! Copyright (C) 2008, 2009 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors arrays assocs classes.mixin classes.parser
4 classes.singleton classes.tuple classes.tuple.parser combinators
5 effects.parser fry functors.backend generic generic.parser
6 interpolate io.streams.string kernel lexer locals.parser
7 locals.types macros make namespaces parser quotations sequences
8 vocabs.parser words words.symbol ;
16 TUPLE: fake-call-next-method ;
18 TUPLE: fake-quotation seq ;
20 GENERIC: >fake-quotations ( quot -- fake )
22 M: callable >fake-quotations
23 >array >fake-quotations fake-quotation boa ;
25 M: array >fake-quotations [ >fake-quotations ] { } map-as ;
27 M: object >fake-quotations ;
29 GENERIC: (fake-quotations>) ( fake -- )
31 : fake-quotations> ( fake -- quot )
32 [ (fake-quotations>) ] [ ] make ;
34 M: fake-quotation (fake-quotations>)
35 [ seq>> [ (fake-quotations>) ] each ] [ ] make , ;
37 M: array (fake-quotations>)
38 [ [ (fake-quotations>) ] each ] { } make , ;
40 M: fake-call-next-method (fake-quotations>)
41 drop \ method get literalize , \ (call-next-method) , ;
43 M: object (fake-quotations>) , ;
45 : parse-definition* ( accum -- accum )
46 parse-definition >fake-quotations suffix!
47 [ fake-quotations> first ] append! ;
49 : parse-declared* ( accum -- accum )
51 [ parse-definition* ] dip
54 FUNCTOR-SYNTAX: TUPLE:
57 { ";" [ tuple suffix! f suffix! ] }
58 { "<" [ scan-param suffix! [ parse-tuple-slots ] { } make suffix! ] }
61 [ parse-slot-name [ parse-tuple-slots ] when ] { }
65 \ define-tuple-class* suffix! ;
68 [ last-word make-final ] append! ;
70 FUNCTOR-SYNTAX: SINGLETON:
72 \ define-singleton-class suffix! ;
74 FUNCTOR-SYNTAX: MIXIN:
76 \ define-mixin-class suffix! ;
81 [ create-method-in dup \ method set ] append!
89 [ [ boa ] curry ] append!
90 ] keep suffix! \ boa-effect suffix!
91 \ define-declared* suffix! ;
96 \ define-declared* suffix! ;
98 FUNCTOR-SYNTAX: SYMBOL:
100 \ define-symbol suffix! ;
102 FUNCTOR-SYNTAX: SYNTAX:
105 \ define-syntax suffix! ;
107 FUNCTOR-SYNTAX: INSTANCE:
110 \ add-mixin-instance suffix! ;
112 FUNCTOR-SYNTAX: GENERIC:
115 \ define-simple-generic* suffix! ;
117 FUNCTOR-SYNTAX: MACRO:
120 \ define-macro suffix! ;
122 FUNCTOR-SYNTAX: inline [ last-word make-inline ] append! ;
124 FUNCTOR-SYNTAX: call-next-method T{ fake-call-next-method } suffix! ;
126 : (INTERPOLATE) ( accum quot -- accum )
127 [ scan-token interpolate-locals-quot ] dip
128 '[ _ with-string-writer @ ] suffix! ;
132 SYNTAX: IS [ parse-word ] (INTERPOLATE) ;
134 SYNTAX: DEFERS [ current-vocab create-word ] (INTERPOLATE) ;
136 SYNTAX: DEFINES [ create-word-in ] (INTERPOLATE) ;
138 SYNTAX: DEFINES-PRIVATE [ begin-private create-word-in end-private ] (INTERPOLATE) ;
140 SYNTAX: DEFINES-CLASS [ create-class-in ] (INTERPOLATE) ;
142 DEFER: ;FUNCTOR> delimiter
146 : parse-binding ( end -- pair/f )
148 { [ 2dup = ] [ 2drop f ] }
149 [ nip scan-object 2array ]
152 : parse-bindings ( end -- words )
153 '[ _ parse-binding dup ]
154 [ first2 [ make-local ] dip 2array ]
157 : with-bindings ( ..a end quot: ( ..a words -- ..b ) -- ..b )
159 building get [ _ parse-bindings @ ] with-words
160 ] H{ } make drop ; inline
162 : parse-functor-body ( -- form )
165 [ swap <def> suffix ] { } assoc>map concat
166 \ ;FUNCTOR> parse-until [ ] append-as
168 ] with-lambda-scope ;
170 : (<FUNCTOR:) ( -- word def effect )
171 scan-new-word [ parse-functor-body ] parse-locals-definition ;
175 SYNTAX: <FUNCTOR: (<FUNCTOR:) define-declared ;