1 ! Copyright (C) 2007, 2008 Daniel Ehrenberg
2 ! Portions copyright (C) 2009, 2010 Slava Pestov, Joe Groff
3 ! See http://factorcode.org/license.txt for BSD license.
4 USING: accessors arrays assocs classes.tuple definitions effects generic
5 generic.standard hashtables kernel lexer math parser
6 generic.parser sequences sets slots words words.symbol fry
10 ERROR: broadcast-words-must-have-no-outputs group ;
14 : protocol-words ( protocol -- words )
15 \ protocol-words word-prop ;
17 : protocol-consult ( protocol -- consulters )
18 \ protocol-consult word-prop ;
20 GENERIC: group-words ( group -- words )
22 M: standard-generic group-words
23 dup "combination" word-prop #>> 2array 1array ;
25 : slot-group-words ( slots -- words )
28 [ reader-word 0 2array ]
29 [ writer-word 0 2array ] bi
33 M: tuple-class group-words
34 all-slots slot-group-words ;
36 : check-broadcast-group ( group -- group )
37 dup group-words [ first stack-effect out>> empty? ] all?
38 [ broadcast-words-must-have-no-outputs ] unless ;
42 TUPLE: consultation group class quot loc ;
43 TUPLE: broadcast < consultation ;
45 : <consultation> ( group class quot -- consultation )
47 : <broadcast> ( group class quot -- consultation )
48 [ check-broadcast-group ] 2dip f broadcast boa ;
50 : create-consult-method ( word consultation -- method )
51 [ class>> swap first create-method dup fake-definition ] keep
52 [ drop ] [ "consultation" set-word-prop ] 2bi ;
54 PREDICATE: consult-method < method "consultation" word-prop ;
56 M: consult-method reset-word
57 [ call-next-method ] [ f "consultation" set-word-prop ] bi ;
59 GENERIC# (consult-method-quot) 2 ( consultation quot word -- object )
61 M: consultation (consult-method-quot)
62 '[ _ call _ execute ] nip ;
63 M: broadcast (consult-method-quot)
64 '[ _ call [ _ execute ] each ] nip ;
66 : consult-method-quot ( consultation word -- object )
68 [ second [ [ dip ] curry ] times ] [ first ] bi
69 (consult-method-quot) ;
71 : consult-method ( word consultation -- )
72 [ create-consult-method ]
73 [ swap consult-method-quot ] 2bi
76 : change-word-prop ( word prop quot -- )
77 [ swap props>> ] dip change-at ; inline
79 : each-generic ( consultation quot -- )
80 [ [ group>> group-words ] keep ] dip curry each ; inline
82 : register-consult ( consultation -- )
83 [ group>> \ protocol-consult ] [ ] [ class>> ] tri
84 '[ [ _ _ ] dip ?set-at ] change-word-prop ;
86 : consult-methods ( consultation -- )
87 [ consult-method ] each-generic ;
89 : unregister-consult ( consultation -- )
90 [ class>> ] [ group>> ] bi
91 \ protocol-consult word-prop delete-at ;
93 : unconsult-method ( word consultation -- )
94 [ class>> swap first method ] keep
96 over "consultation" word-prop eq?
97 [ forget ] [ drop ] if
100 : unconsult-methods ( consultation -- )
101 [ unconsult-method ] each-generic ;
105 : define-consult ( consultation -- )
106 [ register-consult ] [ consult-methods ] bi ;
109 scan-word scan-word parse-definition <consultation>
110 [ save-location ] [ define-consult ] bi ;
113 scan-word scan-word parse-definition <broadcast>
114 [ save-location ] [ define-consult ] bi ;
116 M: consultation where loc>> ;
118 M: consultation set-where loc<< ;
120 M: consultation forget*
121 [ unconsult-methods ] [ unregister-consult ] bi ;
126 : forget-all-methods ( classes words -- )
127 [ first method forget ] cartesian-each ;
129 : protocol-users ( protocol -- users )
130 protocol-consult keys ;
132 : lost-words ( protocol wordlist -- lost-words )
133 [ protocol-words ] dip diff ;
135 : forget-old-definitions ( protocol new-wordlist -- )
136 [ drop protocol-users ] [ lost-words ] 2bi
139 : added-words ( protocol wordlist -- added-words )
140 swap protocol-words diff ;
142 : add-new-definitions ( protocol wordlist -- )
143 [ drop protocol-consult values ] [ added-words ] 2bi
144 [ swap consult-method ] cartesian-each ;
146 : initialize-protocol-props ( protocol wordlist -- )
148 drop \ protocol-consult
149 [ H{ } assoc-like ] change-word-prop
150 ] [ { } like \ protocol-words set-word-prop ] 2bi ;
152 : fill-in-depth ( wordlist -- wordlist' )
153 [ dup word? [ 0 2array ] when ] map ;
155 : show-words ( wordlist' -- wordlist )
156 [ dup second zero? [ first ] when ] map ;
160 : define-protocol ( protocol wordlist -- )
161 [ drop define-symbol ] [
163 [ forget-old-definitions ]
164 [ add-new-definitions ]
165 [ initialize-protocol-props ] 2tri
169 CREATE-WORD parse-definition define-protocol ;
171 PREDICATE: protocol < word protocol-words ; ! Subclass of symbol?
174 [ f forget-old-definitions ] [ call-next-method ] bi ;
177 M: protocol definition protocol-words show-words ;
179 M: protocol definer drop \ PROTOCOL: \ ; ;
181 M: protocol group-words protocol-words ;
183 SYNTAX: SLOT-PROTOCOL:
185 [ [ reader-word ] [ writer-word ] bi 2array ]
186 map-tokens concat define-protocol ;