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 ;
9 ERROR: no-word-error name ;
13 { search-vocabs vector }
14 { qualified-vocabs vector }
15 { extra-words vector } ;
17 : <manifest> ( -- manifest )
19 V{ } clone >>search-vocabs
20 V{ } clone >>qualified-vocabs
21 V{ } clone >>extra-words ;
25 [ clone ] change-search-vocabs
26 [ clone ] change-qualified-vocabs
27 [ clone ] change-extra-words ;
31 : clear-manifest ( -- )
33 [ search-vocabs>> delete-all ]
34 [ qualified-vocabs>> delete-all ]
35 [ extra-words>> delete-all ]
38 : (use-vocab) ( vocab -- vocab seq )
39 load-vocab manifest get search-vocabs>> ;
41 : (add-qualified) ( qualified -- )
42 manifest get qualified-vocabs>> push ;
44 : (from) ( vocab words -- vocab words words' assoc )
45 2dup swap load-vocab words>> ;
47 : (use-words) ( assoc -- assoc seq )
48 manifest get extra-words>> ;
50 : extract-words ( seq assoc -- assoc' )
51 extract-keys dup [ [ drop ] [ no-word-error ] if ] assoc-each ;
53 : (lookup) ( name assoc -- word/f )
54 at dup forward-reference? [ drop f ] when ;
58 : set-current-vocab ( name -- )
59 create-vocab manifest get
61 [ [ words>> ] dip extra-words>> push ]
64 TUPLE: no-current-vocab ;
66 : no-current-vocab ( -- vocab )
67 \ no-current-vocab boa
68 { { "Define words in scratchpad vocabulary" "scratchpad" } }
69 throw-restarts dup set-current-vocab ;
71 : current-vocab ( -- vocab )
72 manifest get current-vocab>> [ no-current-vocab ] unless* ;
74 : begin-private ( -- )
75 manifest get current-vocab>> vocab-name ".private" ?tail
76 [ drop ] [ ".private" append set-current-vocab ] if ;
79 manifest get current-vocab>> vocab-name ".private" ?tail
80 [ set-current-vocab ] [ drop ] if ;
82 : use-vocab ( vocab -- ) (use-vocab) push ;
84 : unuse-vocab ( vocab -- ) (use-vocab) delq ;
86 : only-use-vocabs ( vocabs -- )
88 [ vocab ] V{ } map-as sift
89 manifest get search-vocabs>> push-all ;
91 TUPLE: qualified vocab prefix words ;
93 : <qualified> ( vocab prefix -- qualified )
95 [ load-vocab words>> ] [ CHAR: : suffix ] bi*
96 [ swap [ prepend ] dip ] curry assoc-map
99 : add-qualified ( vocab prefix -- )
100 <qualified> (add-qualified) ;
102 TUPLE: from vocab names words ;
104 : <from> ( vocab words -- from )
105 (from) extract-words from boa ;
107 : add-words-from ( vocab words -- )
108 <from> (add-qualified) ;
110 TUPLE: exclude vocab names words ;
112 : <exclude> ( vocab words -- from )
113 (from) [ nip ] [ extract-words ] 2bi assoc-diff exclude boa ;
115 : add-words-excluding ( vocab words -- )
116 <exclude> (add-qualified) ;
118 TUPLE: rename word vocab words ;
120 : <rename> ( word vocab new-name -- rename )
121 [ 2dup load-vocab words>> dupd at [ ] [ no-word-error ] ?if ] dip
122 associate rename boa ;
124 : add-renamed-word ( word vocab new-name -- )
125 <rename> (add-qualified) ;
127 : use-words ( words -- ) (use-words) push ;
129 : unuse-words ( words -- ) (use-words) delq ;
131 ERROR: ambiguous-use-error words ;
135 : (vocab-search) ( name assocs -- words n )
136 [ words>> (lookup) ] with map
139 : vocab-search ( name manifest -- word/f )
144 [ drop ambiguous-use-error ]
147 : qualified-search ( name manifest -- word/f )
149 (vocab-search) 0 = [ drop f ] [ peek ] if ;
151 : word-search ( name manifest -- word/f )
152 extra-words>> [ (lookup) ] with map-find-last drop ;
156 : search-manifest ( name manifest -- word/f )
157 2dup word-search dup [ 2nip ] [
158 drop 2dup qualified-search dup [ 2nip ] [
163 : search ( name -- word/f )
164 manifest get search-manifest ;
166 : word-restarts ( name possibilities -- restarts )
168 [ [ vocabulary>> "Use the " " vocabulary" surround ] keep ] { } map>assoc
169 swap "Defer word in current vocabulary" swap 2array
172 : <no-word-error> ( name possibilities -- error restarts )
173 [ drop \ no-word-error boa ] [ word-restarts ] 2bi ;