1 ! Copyright (C) 2007, 2009 Daniel Ehrenberg, Bruno Deferrari,
3 ! See http://factorcode.org/license.txt for BSD license.
4 USING: assocs hashtables kernel namespaces sequences
5 sets strings vocabs sorting accessors arrays compiler.units
6 combinators vectors splitting continuations math
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 hashtable }
27 { search-vocabs vector }
28 { qualified-vocabs vector }
29 { extra-words vector }
30 { auto-used vector } ;
32 : <manifest> ( -- manifest )
34 H{ } clone >>search-vocab-names
35 V{ } clone >>search-vocabs
36 V{ } clone >>qualified-vocabs
37 V{ } clone >>extra-words
38 V{ } clone >>auto-used ;
42 [ clone ] change-search-vocab-names
43 [ clone ] change-search-vocabs
44 [ clone ] change-qualified-vocabs
45 [ clone ] change-extra-words
46 [ clone ] change-auto-used ;
48 TUPLE: extra-words words ;
51 over extra-words? [ [ words>> ] bi@ eq? ] [ 2drop f ] if ;
53 C: <extra-words> extra-words
55 : clear-manifest ( -- )
57 [ search-vocab-names>> clear-assoc ]
58 [ search-vocabs>> delete-all ]
59 [ qualified-vocabs>> delete-all ]
62 ERROR: no-word-in-vocab word vocab ;
66 : (add-qualified) ( qualified -- )
67 manifest get qualified-vocabs>> push ;
69 : (from) ( vocab words -- vocab words words' vocab )
70 2dup swap load-vocab ;
72 : extract-words ( seq vocab -- assoc' )
73 [ words>> extract-keys dup ] [ name>> ] bi
74 [ swap [ 2drop ] [ no-word-in-vocab ] if ] curry assoc-each ;
76 : (lookup) ( name assoc -- word/f )
77 at dup forward-reference? [ drop f ] when ;
79 : (use-words) ( assoc -- extra-words seq )
80 <extra-words> manifest get qualified-vocabs>> ;
84 : set-current-vocab ( name -- )
86 [ manifest get (>>current-vocab) ]
87 [ words>> <extra-words> (add-qualified) ] bi ;
89 : with-current-vocab ( name quot -- )
90 manifest get clone manifest [
91 [ set-current-vocab ] dip call
92 ] with-variable ; inline
94 TUPLE: no-current-vocab ;
96 : no-current-vocab ( -- vocab )
97 \ no-current-vocab boa
98 { { "Define words in scratchpad vocabulary" "scratchpad" } }
99 throw-restarts dup set-current-vocab ;
101 : current-vocab ( -- vocab )
102 manifest get current-vocab>> [ no-current-vocab ] unless* ;
104 : begin-private ( -- )
105 manifest get current-vocab>> vocab-name ".private" ?tail
106 [ drop ] [ ".private" append set-current-vocab ] if ;
109 manifest get current-vocab>> vocab-name ".private" ?tail
110 [ set-current-vocab ] [ drop ] if ;
112 : using-vocab? ( vocab -- ? )
113 vocab-name manifest get search-vocab-names>> key? ;
115 : use-vocab ( vocab -- )
117 [ vocab-name "Already using ``" "'' vocabulary" surround note. ] [
119 [ [ load-vocab ] dip search-vocabs>> push ]
120 [ [ vocab-name ] dip search-vocab-names>> conjoin ]
124 : auto-use-vocab ( vocab -- )
125 [ use-vocab ] [ manifest get auto-used>> push ] bi ;
127 : auto-used? ( -- ? ) manifest get auto-used>> length 0 > ;
129 : unuse-vocab ( vocab -- )
132 [ [ load-vocab ] dip search-vocabs>> remove-eq! drop ]
133 [ [ vocab-name ] dip search-vocab-names>> delete-at ]
137 TUPLE: qualified vocab prefix words ;
139 : <qualified> ( vocab prefix -- qualified )
141 [ load-vocab words>> ] [ CHAR: : suffix ] bi*
142 [ swap [ prepend ] dip ] curry assoc-map
145 : add-qualified ( vocab prefix -- )
146 <qualified> (add-qualified) ;
148 TUPLE: from vocab names words ;
150 : <from> ( vocab words -- from )
151 (from) extract-words from boa ;
153 : add-words-from ( vocab words -- )
154 <from> (add-qualified) ;
156 TUPLE: exclude vocab names words ;
158 : <exclude> ( vocab words -- from )
159 (from) [ nip words>> ] [ extract-words ] 2bi assoc-diff exclude boa ;
161 : add-words-excluding ( vocab words -- )
162 <exclude> (add-qualified) ;
164 TUPLE: rename word vocab words ;
166 : <rename> ( word vocab new-name -- rename )
167 [ 2dup load-vocab words>> dupd at [ ] [ swap no-word-in-vocab ] ?if ] dip
168 associate rename boa ;
170 : add-renamed-word ( word vocab new-name -- )
171 <rename> (add-qualified) ;
173 : use-words ( assoc -- ) (use-words) push ;
175 : unuse-words ( assoc -- ) (use-words) remove! drop ;
177 TUPLE: ambiguous-use-error words ;
179 : <ambiguous-use-error> ( words -- error restarts )
180 [ \ ambiguous-use-error boa ] [ word-restarts ] bi ;
184 : (vocab-search) ( name assocs -- words n )
185 [ words>> (lookup) ] with map
188 : vocab-search ( name manifest -- word/f )
194 drop <ambiguous-use-error> throw-restarts
195 dup [ vocabulary>> ] [ name>> 1array ] bi add-words-from
199 : qualified-search ( name manifest -- word/f )
201 (vocab-search) 0 = [ drop f ] [ last ] if ;
205 : search-manifest ( name manifest -- word/f )
206 2dup qualified-search dup [ 2nip ] [ drop vocab-search ] if ;
208 : search ( name -- word/f )
209 manifest get search-manifest ;