]> gitweb.factorcode.org Git - factor.git/blob - basis/functors/functors.factor
Merge branch 'master' of http://factorcode.org/git/factor
[factor.git] / basis / functors / functors.factor
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
5 combinators effects.parser fry functors.backend generic
6 generic.parser interpolate io.streams.string kernel lexer
7 locals.parser locals.types macros make namespaces parser
8 quotations sequences vocabs.parser words words.symbol ;
9 IN: functors
10
11 ! This is a hack
12
13 <PRIVATE
14
15 TUPLE: fake-call-next-method ;
16
17 TUPLE: fake-quotation seq ;
18
19 GENERIC: >fake-quotations ( quot -- fake )
20
21 M: callable >fake-quotations
22     >array >fake-quotations fake-quotation boa ;
23
24 M: array >fake-quotations [ >fake-quotations ] { } map-as ;
25
26 M: object >fake-quotations ;
27
28 GENERIC: (fake-quotations>) ( fake -- )
29
30 : fake-quotations> ( fake -- quot )
31     [ (fake-quotations>) ] [ ] make ;
32
33 M: fake-quotation (fake-quotations>)
34     [ seq>> [ (fake-quotations>) ] each ] [ ] make , ;
35
36 M: array (fake-quotations>)
37     [ [ (fake-quotations>) ] each ] { } make , ;
38
39 M: fake-call-next-method (fake-quotations>)
40     drop method-body get literalize , \ (call-next-method) , ;
41
42 M: object (fake-quotations>) , ;
43
44 : parse-definition* ( accum -- accum )
45     parse-definition >fake-quotations suffix!
46     [ fake-quotations> first ] append! ;
47
48 : parse-declared* ( accum -- accum )
49     complete-effect
50     [ parse-definition* ] dip
51     suffix! ;
52
53 FUNCTOR-SYNTAX: TUPLE:
54     scan-param suffix!
55     scan {
56         { ";" [ tuple suffix! f suffix! ] }
57         { "<" [ scan-param suffix! [ parse-tuple-slots ] { } make suffix! ] }
58         [
59             [ tuple suffix! ] dip
60             [ parse-slot-name [ parse-tuple-slots ] when ] { }
61             make suffix!
62         ]
63     } case
64     \ define-tuple-class suffix! ;
65
66 FUNCTOR-SYNTAX: SINGLETON:
67     scan-param suffix!
68     \ define-singleton-class suffix! ;
69
70 FUNCTOR-SYNTAX: MIXIN:
71     scan-param suffix!
72     \ define-mixin-class suffix! ;
73
74 FUNCTOR-SYNTAX: M:
75     scan-param suffix!
76     scan-param suffix!
77     [ create-method-in dup method-body set ] append! 
78     parse-definition*
79     \ define* suffix! ;
80
81 FUNCTOR-SYNTAX: C:
82     scan-param suffix!
83     scan-param suffix!
84     complete-effect
85     [ [ [ boa ] curry ] append! ] dip suffix!
86     \ define-declared* suffix! ;
87
88 FUNCTOR-SYNTAX: :
89     scan-param suffix!
90     parse-declared*
91     \ define-declared* suffix! ;
92
93 FUNCTOR-SYNTAX: SYMBOL:
94     scan-param suffix!
95     \ define-symbol suffix! ;
96
97 FUNCTOR-SYNTAX: SYNTAX:
98     scan-param suffix!
99     parse-definition*
100     \ define-syntax suffix! ;
101
102 FUNCTOR-SYNTAX: INSTANCE:
103     scan-param suffix!
104     scan-param suffix!
105     \ add-mixin-instance suffix! ;
106
107 FUNCTOR-SYNTAX: GENERIC:
108     scan-param suffix!
109     complete-effect suffix!
110     \ define-simple-generic* suffix! ;
111
112 FUNCTOR-SYNTAX: MACRO:
113     scan-param suffix!
114     parse-declared*
115     \ define-macro suffix! ;
116
117 FUNCTOR-SYNTAX: inline [ word make-inline ] append! ;
118
119 FUNCTOR-SYNTAX: call-next-method T{ fake-call-next-method } suffix! ;
120
121 : (INTERPOLATE) ( accum quot -- accum )
122     [ scan interpolate-locals ] dip
123     '[ _ with-string-writer @ ] suffix! ;
124
125 PRIVATE>
126
127 SYNTAX: IS [ dup search [ ] [ no-word ] ?if ] (INTERPOLATE) ;
128
129 SYNTAX: DEFERS [ current-vocab create ] (INTERPOLATE) ;
130
131 SYNTAX: DEFINES [ create-in ] (INTERPOLATE) ;
132
133 SYNTAX: DEFINES-PRIVATE [ begin-private create-in end-private ] (INTERPOLATE) ;
134
135 SYNTAX: DEFINES-CLASS [ create-class-in ] (INTERPOLATE) ;
136
137 DEFER: ;FUNCTOR delimiter
138
139 <PRIVATE
140
141 : push-functor-words ( -- )
142     functor-words use-words ;
143
144 : pop-functor-words ( -- )
145     functor-words unuse-words ;
146
147 : (parse-bindings) ( end -- )
148     dup parse-binding dup [
149         first2 [ make-local ] dip 2array ,
150         (parse-bindings)
151     ] [ 2drop ] if ;
152
153 : with-bindings ( quot -- words assoc )
154     '[
155         in-lambda? on
156         _ H{ } make-assoc
157     ] { } make swap ; inline
158
159 : parse-bindings ( end -- words assoc )
160     [
161         namespace use-words
162         (parse-bindings)
163         namespace unuse-words
164     ] with-bindings ;
165
166 : parse-functor-body ( -- form )
167     push-functor-words
168     "WHERE" parse-bindings
169     [ [ swap <def> suffix ] { } assoc>map concat ]
170     [ [ \ ;FUNCTOR parse-until >quotation ] ((parse-lambda)) ] bi*
171     [ ] append-as
172     pop-functor-words ;
173
174 : (FUNCTOR:) ( -- word def effect )
175     CREATE-WORD [ parse-functor-body ] parse-locals-definition ;
176
177 PRIVATE>
178
179 SYNTAX: FUNCTOR: (FUNCTOR:) define-declared ;