]> gitweb.factorcode.org Git - factor.git/blob - core/vocabs/vocabs.factor
f86dcda135540db2a72f91d4839a73760c6c40f0
[factor.git] / core / vocabs / vocabs.factor
1 ! Copyright (C) 2007, 2009 Eduardo Cavazos, Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors assocs definitions kernel namespaces sequences
4 sets sorting splitting strings ;
5 IN: vocabs
6
7 SYMBOL: dictionary
8
9 TUPLE: vocab < identity-tuple
10 name words
11 main help
12 source-loaded? docs-loaded? ;
13
14 ! sources-loaded? slot is one of these three
15 SYMBOL: +parsing+
16 SYMBOL: +running+
17 SYMBOL: +done+
18
19 : <vocab> ( name -- vocab )
20     \ vocab new
21         swap >>name
22         H{ } clone >>words ;
23
24 ERROR: bad-vocab-name name ;
25
26 : check-vocab-name ( name -- name )
27     dup string? [ bad-vocab-name ] unless
28     dup [ ":/\\ " member? ] any? [ bad-vocab-name ] when ;
29
30 TUPLE: vocab-link name ;
31
32 C: <vocab-link> vocab-link
33
34 UNION: vocab-spec vocab vocab-link ;
35
36 GENERIC: vocab-name ( vocab-spec -- name )
37
38 M: vocab vocab-name name>> ;
39
40 M: vocab-link vocab-name name>> ;
41
42 M: object vocab-name check-vocab-name ;
43
44 : vocab-name* ( vocab-spec -- name )
45     vocab-name ".private" ?tail drop ;
46
47 : private-vocab? ( vocab -- ? )
48     vocab-name ".private" tail? ;
49
50 GENERIC: lookup-vocab ( vocab-spec -- vocab )
51
52 M: vocab lookup-vocab ;
53
54 M: object lookup-vocab ( name -- vocab ) vocab-name dictionary get at ;
55
56 GENERIC: vocab-words ( vocab-spec -- words )
57
58 M: vocab vocab-words words>> ;
59
60 M: object vocab-words lookup-vocab vocab-words ;
61
62 M: f vocab-words ;
63
64 GENERIC: vocab-help ( vocab-spec -- help )
65
66 M: vocab vocab-help help>> ;
67
68 M: object vocab-help lookup-vocab vocab-help ;
69
70 M: f vocab-help ;
71
72 GENERIC: vocab-main ( vocab-spec -- main )
73
74 M: vocab vocab-main main>> ;
75
76 M: object vocab-main lookup-vocab vocab-main ;
77
78 M: f vocab-main ;
79
80 SYMBOL: vocab-observers
81
82 GENERIC: vocab-changed ( vocab obj -- )
83
84 : add-vocab-observer ( obj -- )
85     vocab-observers get push ;
86
87 : remove-vocab-observer ( obj -- )
88     vocab-observers get remove-eq! drop ;
89
90 : notify-vocab-observers ( vocab -- )
91     vocab-observers get [ vocab-changed ] with each ;
92
93 : create-vocab ( name -- vocab )
94     check-vocab-name
95     dictionary get [ <vocab> ] cache
96     dup notify-vocab-observers ;
97
98 ERROR: no-vocab name ;
99
100 : vocabs ( -- seq )
101     dictionary get keys natural-sort ;
102
103 : words ( vocab -- seq )
104     vocab-words values ;
105
106 : all-words ( -- seq )
107     dictionary get values [ words ] map concat ;
108
109 : words-named ( str -- seq )
110     dictionary get values
111     [ vocab-words at ] with map
112     sift ;
113
114 : child-vocab? ( prefix name -- ? )
115     2dup = pick empty? or
116     [ 2drop t ] [ swap CHAR: . suffix head? ] if ;
117
118 : child-vocabs ( vocab -- seq )
119     vocab-name vocabs [ child-vocab? ] with filter ;
120
121 GENERIC: >vocab-link ( name -- vocab )
122
123 M: vocab-spec >vocab-link ;
124
125 M: object >vocab-link dup lookup-vocab [ ] [ <vocab-link> ] ?if ;
126
127 : forget-vocab ( vocab -- )
128     [ words forget-all ]
129     [ vocab-name dictionary get delete-at ]
130     [ notify-vocab-observers ] tri ;
131
132 M: vocab-spec forget* forget-vocab ;
133
134 SYMBOL: require-hook
135
136 PREDICATE: runnable-vocab < vocab
137     vocab-main >boolean ;
138
139 INSTANCE: vocab-spec definition
140
141 : call-require-hook ( name -- )
142     require-hook get call( name -- ) ;
143
144 GENERIC: require ( object -- )
145
146 M: vocab require name>> require ;
147 M: vocab-link require name>> require ;
148
149 ! When calling "foo.private" require, load "foo" instead, but only when
150 ! "foo.private" does not exist. The reason for this is that stage1 bootstrap
151 ! starts out with some .private vocabs that contain primitives, and
152 ! loading the public vocabs would cause circularity issues.
153 M: string require ( vocab -- )
154     dup ".private" ?tail [
155         over lookup-vocab
156         [ 2drop ]
157         [ nip call-require-hook ]
158         if
159     ] [
160         nip call-require-hook
161     ] if ;
162
163 : load-vocab ( name -- vocab )
164     [ require ] [ lookup-vocab ] bi ;