29 val qualified_name: string -> binding |
29 val qualified_name: string -> binding |
30 val prefix_of: binding -> (string * bool) list |
30 val prefix_of: binding -> (string * bool) list |
31 val map_prefix: ((string * bool) list -> (string * bool) list) -> binding -> binding |
31 val map_prefix: ((string * bool) list -> (string * bool) list) -> binding -> binding |
32 val prefix: bool -> string -> binding -> binding |
32 val prefix: bool -> string -> binding -> binding |
33 val private: scope -> binding -> binding |
33 val private: scope -> binding -> binding |
34 val private_default: scope option -> binding -> binding |
34 val restricted: scope -> binding -> binding |
|
35 val limited_default: (bool * scope) option -> binding -> binding |
35 val concealed: binding -> binding |
36 val concealed: binding -> binding |
36 val pretty: binding -> Pretty.T |
37 val pretty: binding -> Pretty.T |
37 val print: binding -> string |
38 val print: binding -> string |
38 val pp: binding -> Pretty.T |
39 val pp: binding -> Pretty.T |
39 val bad: binding -> string |
40 val bad: binding -> string |
40 val check: binding -> unit |
41 val check: binding -> unit |
41 val name_spec: scope list -> (string * bool) list -> binding -> |
42 val name_spec: scope list -> (string * bool) list -> binding -> |
42 {accessible: bool, concealed: bool, spec: (string * bool) list} |
43 {limitation: bool option, concealed: bool, spec: (string * bool) list} |
43 end; |
44 end; |
44 |
45 |
45 structure Binding: BINDING = |
46 structure Binding: BINDING = |
46 struct |
47 struct |
47 |
48 |
48 (** representation **) |
49 (** representation **) |
49 |
50 |
50 (* scope of private entries *) |
51 (* scope of limited entries *) |
51 |
52 |
52 datatype scope = Scope of serial; |
53 datatype scope = Scope of serial; |
53 |
54 |
54 fun new_scope () = Scope (serial ()); |
55 fun new_scope () = Scope (serial ()); |
55 |
56 |
56 |
57 |
57 (* binding *) |
58 (* binding *) |
58 |
59 |
59 datatype binding = Binding of |
60 datatype binding = Binding of |
60 {private: scope option, (*entry is strictly private within its scope*) |
61 {limited: (bool * scope) option, (*entry is private (true) / restricted (false) to scope*) |
61 concealed: bool, (*entry is for foundational purposes -- please ignore*) |
62 concealed: bool, (*entry is for foundational purposes -- please ignore*) |
62 prefix: (string * bool) list, (*system prefix*) |
63 prefix: (string * bool) list, (*system prefix*) |
63 qualifier: (string * bool) list, (*user qualifier*) |
64 qualifier: (string * bool) list, (*user qualifier*) |
64 name: bstring, (*base name*) |
65 name: bstring, (*base name*) |
65 pos: Position.T}; (*source position*) |
66 pos: Position.T}; (*source position*) |
66 |
67 |
67 fun make_binding (private, concealed, prefix, qualifier, name, pos) = |
68 fun make_binding (limited, concealed, prefix, qualifier, name, pos) = |
68 Binding {private = private, concealed = concealed, prefix = prefix, |
69 Binding {limited = limited, concealed = concealed, prefix = prefix, |
69 qualifier = qualifier, name = name, pos = pos}; |
70 qualifier = qualifier, name = name, pos = pos}; |
70 |
71 |
71 fun map_binding f (Binding {private, concealed, prefix, qualifier, name, pos}) = |
72 fun map_binding f (Binding {limited, concealed, prefix, qualifier, name, pos}) = |
72 make_binding (f (private, concealed, prefix, qualifier, name, pos)); |
73 make_binding (f (limited, concealed, prefix, qualifier, name, pos)); |
73 |
74 |
74 fun path_of (Binding {prefix, qualifier, ...}) = prefix @ qualifier; |
75 fun path_of (Binding {prefix, qualifier, ...}) = prefix @ qualifier; |
75 |
76 |
76 |
77 |
77 |
78 |
81 |
82 |
82 fun make (name, pos) = make_binding (NONE, false, [], [], name, pos); |
83 fun make (name, pos) = make_binding (NONE, false, [], [], name, pos); |
83 |
84 |
84 fun pos_of (Binding {pos, ...}) = pos; |
85 fun pos_of (Binding {pos, ...}) = pos; |
85 fun set_pos pos = |
86 fun set_pos pos = |
86 map_binding (fn (private, concealed, prefix, qualifier, name, _) => |
87 map_binding (fn (limited, concealed, prefix, qualifier, name, _) => |
87 (private, concealed, prefix, qualifier, name, pos)); |
88 (limited, concealed, prefix, qualifier, name, pos)); |
88 |
89 |
89 fun name name = make (name, Position.none); |
90 fun name name = make (name, Position.none); |
90 fun name_of (Binding {name, ...}) = name; |
91 fun name_of (Binding {name, ...}) = name; |
91 |
92 |
92 fun eq_name (b, b') = name_of b = name_of b'; |
93 fun eq_name (b, b') = name_of b = name_of b'; |
93 |
94 |
94 fun map_name f = |
95 fun map_name f = |
95 map_binding (fn (private, concealed, prefix, qualifier, name, pos) => |
96 map_binding (fn (limited, concealed, prefix, qualifier, name, pos) => |
96 (private, concealed, prefix, qualifier, f name, pos)); |
97 (limited, concealed, prefix, qualifier, f name, pos)); |
97 |
98 |
98 val prefix_name = map_name o prefix; |
99 val prefix_name = map_name o prefix; |
99 val suffix_name = map_name o suffix; |
100 val suffix_name = map_name o suffix; |
100 |
101 |
101 val empty = name ""; |
102 val empty = name ""; |
104 |
105 |
105 (* user qualifier *) |
106 (* user qualifier *) |
106 |
107 |
107 fun qualify _ "" = I |
108 fun qualify _ "" = I |
108 | qualify mandatory qual = |
109 | qualify mandatory qual = |
109 map_binding (fn (private, concealed, prefix, qualifier, name, pos) => |
110 map_binding (fn (limited, concealed, prefix, qualifier, name, pos) => |
110 (private, concealed, prefix, (qual, mandatory) :: qualifier, name, pos)); |
111 (limited, concealed, prefix, (qual, mandatory) :: qualifier, name, pos)); |
111 |
112 |
112 fun qualified mandatory name' = |
113 fun qualified mandatory name' = |
113 map_binding (fn (private, concealed, prefix, qualifier, name, pos) => |
114 map_binding (fn (limited, concealed, prefix, qualifier, name, pos) => |
114 let val qualifier' = if name = "" then qualifier else qualifier @ [(name, mandatory)] |
115 let val qualifier' = if name = "" then qualifier else qualifier @ [(name, mandatory)] |
115 in (private, concealed, prefix, qualifier', name', pos) end); |
116 in (limited, concealed, prefix, qualifier', name', pos) end); |
116 |
117 |
117 fun qualified_name "" = empty |
118 fun qualified_name "" = empty |
118 | qualified_name s = |
119 | qualified_name s = |
119 let val (qualifier, name) = split_last (Long_Name.explode s) |
120 let val (qualifier, name) = split_last (Long_Name.explode s) |
120 in make_binding (NONE, false, [], map (rpair false) qualifier, name, Position.none) end; |
121 in make_binding (NONE, false, [], map (rpair false) qualifier, name, Position.none) end; |
123 (* system prefix *) |
124 (* system prefix *) |
124 |
125 |
125 fun prefix_of (Binding {prefix, ...}) = prefix; |
126 fun prefix_of (Binding {prefix, ...}) = prefix; |
126 |
127 |
127 fun map_prefix f = |
128 fun map_prefix f = |
128 map_binding (fn (private, concealed, prefix, qualifier, name, pos) => |
129 map_binding (fn (limited, concealed, prefix, qualifier, name, pos) => |
129 (private, concealed, f prefix, qualifier, name, pos)); |
130 (limited, concealed, f prefix, qualifier, name, pos)); |
130 |
131 |
131 fun prefix _ "" = I |
132 fun prefix _ "" = I |
132 | prefix mandatory prfx = map_prefix (cons (prfx, mandatory)); |
133 | prefix mandatory prfx = map_prefix (cons (prfx, mandatory)); |
133 |
134 |
134 |
135 |
135 (* visibility flags *) |
136 (* visibility flags *) |
136 |
137 |
137 fun private scope = |
138 fun limited strict scope = |
138 map_binding (fn (_, concealed, prefix, qualifier, name, pos) => |
139 map_binding (fn (_, concealed, prefix, qualifier, name, pos) => |
139 (SOME scope, concealed, prefix, qualifier, name, pos)); |
140 (SOME (strict, scope), concealed, prefix, qualifier, name, pos)); |
140 |
141 |
141 fun private_default private' = |
142 val private = limited true; |
142 map_binding (fn (private, concealed, prefix, qualifier, name, pos) => |
143 val restricted = limited false; |
143 (if is_some private then private else private', concealed, prefix, qualifier, name, pos)); |
144 |
|
145 fun limited_default limited' = |
|
146 map_binding (fn (limited, concealed, prefix, qualifier, name, pos) => |
|
147 (if is_some limited then limited else limited', concealed, prefix, qualifier, name, pos)); |
144 |
148 |
145 val concealed = |
149 val concealed = |
146 map_binding (fn (private, _, prefix, qualifier, name, pos) => |
150 map_binding (fn (limited, _, prefix, qualifier, name, pos) => |
147 (private, true, prefix, qualifier, name, pos)); |
151 (limited, true, prefix, qualifier, name, pos)); |
148 |
152 |
149 |
153 |
150 (* print *) |
154 (* print *) |
151 |
155 |
152 fun pretty (Binding {prefix, qualifier, name, pos, ...}) = |
156 fun pretty (Binding {prefix, qualifier, name, pos, ...}) = |
175 |
179 |
176 val bad_specs = ["", "??", "__"]; |
180 val bad_specs = ["", "??", "__"]; |
177 |
181 |
178 fun name_spec scopes path binding = |
182 fun name_spec scopes path binding = |
179 let |
183 let |
180 val Binding {private, concealed, prefix, qualifier, name, ...} = binding; |
184 val Binding {limited, concealed, prefix, qualifier, name, ...} = binding; |
181 val _ = Long_Name.is_qualified name andalso error (bad binding); |
185 val _ = Long_Name.is_qualified name andalso error (bad binding); |
182 |
186 |
183 val accessible = |
187 val limitation = |
184 (case private of |
188 (case limited of |
185 NONE => true |
189 NONE => NONE |
186 | SOME scope => member (op =) scopes scope); |
190 | SOME (strict, scope) => if member (op =) scopes scope then NONE else SOME strict); |
187 |
191 |
188 val spec1 = |
192 val spec1 = |
189 maps (fn (a, b) => map (rpair b) (Long_Name.explode a)) (path @ prefix @ qualifier); |
193 maps (fn (a, b) => map (rpair b) (Long_Name.explode a)) (path @ prefix @ qualifier); |
190 val spec2 = if name = "" then [] else [(name, true)]; |
194 val spec2 = if name = "" then [] else [(name, true)]; |
191 val spec = spec1 @ spec2; |
195 val spec = spec1 @ spec2; |
192 val _ = |
196 val _ = |
193 exists (fn (a, _) => member (op =) bad_specs a orelse exists_string (fn s => s = "\"") a) spec |
197 exists (fn (a, _) => member (op =) bad_specs a orelse exists_string (fn s => s = "\"") a) spec |
194 andalso error (bad binding); |
198 andalso error (bad binding); |
195 in {accessible = accessible, concealed = concealed, spec = if null spec2 then [] else spec} end; |
199 in {limitation = limitation, concealed = concealed, spec = if null spec2 then [] else spec} end; |
196 |
200 |
197 end; |
201 end; |
198 |
202 |
199 type binding = Binding.binding; |
203 type binding = Binding.binding; |