1 ! Copyright (C) 2007, 2010 Daniel Ehrenberg, Bruno Deferrari,
3 ! See http://factorcode.org/license.txt for BSD license.
4 USING: accessors arrays assocs combinators compiler.units
5 continuations hash-sets hashtables kernel math namespaces
6 parser.notes sequences sets sorting splitting vectors vocabs
10 ERROR: no-word-error name ;
12 : word-restarts ( possibilities -- restarts )
14 [ [ vocabulary>> "Use the " " vocabulary" surround ] keep ] { } map>assoc ;
16 : word-restarts-with-defer ( name possibilities -- restarts )
18 swap "Defer word in current vocabulary" swap 2array
21 : <no-word-error> ( name possibilities -- error restarts )
22 [ drop \ no-word-error boa ] [ word-restarts-with-defer ] 2bi ;
26 { search-vocab-names hash-set }
27 { search-vocabs vector }
28 { qualified-vocabs vector }
29 { auto-used vector } ;
31 : <manifest> ( -- manifest )
33 HS{ } clone >>search-vocab-names
34 V{ } clone >>search-vocabs
35 V{ } clone >>qualified-vocabs
36 V{ } clone >>auto-used ;
40 [ clone ] change-search-vocab-names
41 [ clone ] change-search-vocabs
42 [ clone ] change-qualified-vocabs
43 [ clone ] change-auto-used ;
45 TUPLE: extra-words words ;
48 over extra-words? [ [ words>> ] bi@ eq? ] [ 2drop f ] if ;
50 C: <extra-words> extra-words
52 ERROR: no-word-in-vocab word vocab ;
56 : (from) ( vocab words -- vocab words words' vocab )
57 2dup swap load-vocab ;
59 : extract-words ( seq vocab -- assoc )
60 [ words>> extract-keys dup ] [ name>> ] bi
61 [ swap [ 2drop ] [ no-word-in-vocab ] if ] curry assoc-each ;
63 : excluding-words ( seq vocab -- assoc )
64 [ nip words>> ] [ extract-words ] 2bi assoc-diff ;
66 : qualified-words ( prefix vocab -- assoc )
67 words>> swap [ swap [ swap ":" glue ] dip ] curry assoc-map ;
69 : (lookup) ( name assoc -- word/f )
70 at* [ dup forward-reference? [ drop f ] when ] when ;
74 : qualified-vocabs ( -- qualified-vocabs )
75 manifest get qualified-vocabs>> ;
77 : set-current-vocab ( name -- )
79 [ manifest get current-vocab<< ]
80 [ qualified-vocabs push ] bi ;
82 : with-current-vocab ( name quot -- )
83 manifest get clone manifest [
84 [ set-current-vocab ] dip call
85 ] with-variable ; inline
87 TUPLE: no-current-vocab-error ;
89 : no-current-vocab ( -- vocab )
90 no-current-vocab-error boa
91 { { "Define words in scratchpad vocabulary" "scratchpad" } }
92 throw-restarts dup set-current-vocab ;
94 : current-vocab ( -- vocab )
95 manifest get current-vocab>> [ no-current-vocab ] unless* ;
97 : begin-private ( -- )
98 current-vocab name>> ".private" ?tail
99 [ drop ] [ ".private" append set-current-vocab ] if ;
102 current-vocab name>> ".private" ?tail
103 [ set-current-vocab ] [ drop ] if ;
105 : using-vocab? ( vocab -- ? )
106 vocab-name manifest get search-vocab-names>> in? ;
108 : use-vocab ( vocab -- )
110 [ vocab-name "Already using ``" "'' vocabulary" surround note. ] [
112 [ [ load-vocab ] dip search-vocabs>> push ]
113 [ [ vocab-name ] dip search-vocab-names>> adjoin ]
117 : auto-use-vocab ( vocab -- )
118 [ use-vocab ] [ manifest get auto-used>> push ] bi ;
120 : auto-used? ( -- ? )
121 manifest get auto-used>> length 0 > ;
123 : unuse-vocab ( vocab -- )
126 [ [ load-vocab ] dip search-vocabs>> remove-eq! drop ]
127 [ [ vocab-name ] dip search-vocab-names>> delete ]
131 TUPLE: qualified vocab prefix words ;
133 : <qualified> ( vocab prefix -- qualified )
134 (from) qualified-words qualified boa ;
136 : add-qualified ( vocab prefix -- )
137 <qualified> qualified-vocabs push ;
139 TUPLE: from vocab names words ;
141 : <from> ( vocab words -- from )
142 (from) extract-words from boa ;
144 : add-words-from ( vocab words -- )
145 <from> qualified-vocabs push ;
147 TUPLE: exclude vocab names words ;
149 : <exclude> ( vocab words -- from )
150 (from) excluding-words exclude boa ;
152 : add-words-excluding ( vocab words -- )
153 <exclude> qualified-vocabs push ;
155 TUPLE: rename word vocab words ;
157 : <rename> ( word vocab new-name -- rename )
159 2dup load-vocab words>> dupd at
160 [ ] [ swap no-word-in-vocab ] ?if
161 ] dip associate rename boa ;
163 : add-renamed-word ( word vocab new-name -- )
164 <rename> qualified-vocabs push ;
166 : use-words ( assoc -- )
167 <extra-words> qualified-vocabs push ;
169 : unuse-words ( assoc -- )
170 <extra-words> qualified-vocabs remove! drop ;
172 TUPLE: ambiguous-use-error words ;
174 : <ambiguous-use-error> ( words -- error restarts )
175 [ ambiguous-use-error boa ] [ word-restarts ] bi ;
179 : (vocab-search) ( name assocs -- words n )
180 [ words>> (lookup) ] with map sift dup length ;
182 : vocab-search ( name manifest -- word/f )
188 drop <ambiguous-use-error> throw-restarts
189 dup [ vocabulary>> ] [ name>> 1array ] bi add-words-from
193 : qualified-search ( name manifest -- word/f )
195 (vocab-search) 0 = [ drop f ] [ last ] if ;
199 : search-manifest ( name manifest -- word/f )
200 2dup qualified-search dup [ 2nip ] [ drop vocab-search ] if ;
202 : search ( name -- word/f )
203 manifest get search-manifest ;
207 GENERIC: update ( search-path-elt -- valid? )
209 : trim-forgotten ( qualified-vocab -- valid? )
210 [ [ nip "forgotten" word-prop ] assoc-reject ] change-words
211 words>> assoc-empty? not ;
213 M: from update trim-forgotten ;
214 M: rename update trim-forgotten ;
215 M: extra-words update trim-forgotten ;
216 M: exclude update trim-forgotten ;
219 dup vocab>> lookup-vocab [
220 dup [ prefix>> ] [ vocab>> load-vocab ] bi qualified-words
224 M: vocab update dup name>> lookup-vocab eq? ;
226 : update-current-vocab ( manifest -- manifest )
227 [ dup [ name>> lookup-vocab ] when ] change-current-vocab ; inline
229 : compute-search-vocabs ( manifest -- search-vocab-names search-vocabs )
230 search-vocab-names>> members dup length <vector> [
231 [ push ] curry [ when* ] curry
232 [ lookup-vocab dup ] prepose filter fast-set
235 : update-search-vocabs ( manifest -- manifest )
236 dup compute-search-vocabs
237 [ >>search-vocab-names ] [ >>search-vocabs ] bi* ; inline
239 : update-qualified-vocabs ( manifest -- manifest )
240 dup qualified-vocabs>> [ update ] filter! drop ; inline
242 : update-manifest ( manifest -- manifest )
245 update-qualified-vocabs ; inline
247 M: manifest definitions-changed
248 nip update-manifest drop ;
252 : with-manifest ( quot -- )
253 <manifest> manifest [
255 [ manifest get add-definition-observer call ]
256 [ manifest get remove-definition-observer ]
260 ] with-variable ; inline