125 (** name spaces **) |
125 (** name spaces **) |
126 |
126 |
127 (* datatype T *) |
127 (* datatype T *) |
128 |
128 |
129 datatype T = |
129 datatype T = |
130 NameSpace of (string list * string list) Symtab.table; |
130 NameSpace of ((string list * string list) * stamp) Symtab.table; |
131 |
131 |
132 val empty = NameSpace Symtab.empty; |
132 val empty = NameSpace Symtab.empty; |
133 |
133 |
134 fun lookup (NameSpace tab) xname = |
134 fun lookup (NameSpace tab) xname = |
135 (case Symtab.lookup tab xname of |
135 (case Symtab.lookup tab xname of |
136 NONE => (xname, true) |
136 NONE => (xname, true) |
137 | SOME ([], []) => (xname, true) |
137 | SOME (([], []), _) => (xname, true) |
138 | SOME ([name], _) => (name, true) |
138 | SOME (([name], _), _) => (name, true) |
139 | SOME (name :: _, _) => (name, false) |
139 | SOME ((name :: _, _), _) => (name, false) |
140 | SOME ([], name' :: _) => (hidden name', true)); |
140 | SOME (([], name' :: _), _) => (hidden name', true)); |
141 |
141 |
142 fun valid_accesses (NameSpace tab) name = Symtab.fold (fn (xname, (names, _)) => |
142 fun valid_accesses (NameSpace tab) name = Symtab.fold (fn (xname, ((names, _), _)) => |
143 if not (null names) andalso hd names = name then cons xname else I) tab []; |
143 if not (null names) andalso hd names = name then cons xname else I) tab []; |
144 |
144 |
145 |
145 |
146 (* intern and extern *) |
146 (* intern and extern *) |
147 |
147 |
167 |
167 |
168 |
168 |
169 (* basic operations *) |
169 (* basic operations *) |
170 |
170 |
171 fun map_space f xname (NameSpace tab) = |
171 fun map_space f xname (NameSpace tab) = |
172 NameSpace (Symtab.update (xname, f (the_default ([], []) (Symtab.lookup tab xname))) tab); |
172 let val entry' = |
|
173 (case Symtab.lookup tab xname of |
|
174 NONE => f ([], []) |
|
175 | SOME (entry, _) => f entry) |
|
176 in NameSpace (Symtab.update (xname, (entry', stamp ())) tab) end; |
173 |
177 |
174 fun del (name: string) = remove (op =) name; |
178 fun del (name: string) = remove (op =) name; |
175 fun add name names = name :: del name names; |
179 fun add name names = name :: del name names; |
176 |
180 |
177 val del_name = map_space o apfst o del; |
181 val del_name = map_space o apfst o del; |
194 end; |
198 end; |
195 |
199 |
196 |
200 |
197 (* merge *) |
201 (* merge *) |
198 |
202 |
199 fun merge (NameSpace tab1, space2) = Symtab.fold (fn (xname, (names1, names1')) => |
203 fun merge (NameSpace tab1, NameSpace tab2) = |
200 xname |> map_space (fn (names2, names2') => |
204 NameSpace ((tab1, tab2) |> Symtab.join |
201 (Library.merge (op =) (names2, names1), Library.merge (op =) (names2', names1')))) tab1 space2; |
205 (K (fn (((names1, names1'), stamp1), ((names2, names2'), stamp2)) => |
|
206 if stamp1 = stamp2 then raise Symtab.SAME |
|
207 else |
|
208 ((Library.merge (op =) (names2, names1), |
|
209 Library.merge (op =) (names2', names1')), stamp ())))); |
202 |
210 |
203 |
211 |
204 |
212 |
205 (** naming contexts **) |
213 (** naming contexts **) |
206 |
214 |