author | wenzelm |
Sun, 26 Aug 2018 17:48:35 +0200 | |
changeset 68814 | 6a0b1357bded |
parent 68813 | 78edc4bc3bd3 |
child 68816 | 5a53724fe247 |
permissions | -rw-r--r-- |
31325 | 1 |
(* Title: Pure/ML/ml_env.ML |
2 |
Author: Makarius |
|
3 |
||
56275
600f432ab556
added command 'SML_file' for Standard ML without Isabelle/ML add-ons;
wenzelm
parents:
56203
diff
changeset
|
4 |
Toplevel environment for Standard ML and Isabelle/ML within the |
600f432ab556
added command 'SML_file' for Standard ML without Isabelle/ML add-ons;
wenzelm
parents:
56203
diff
changeset
|
5 |
implicit context. |
31325 | 6 |
*) |
7 |
||
8 |
signature ML_ENV = |
|
9 |
sig |
|
10 |
val inherit: Context.generic -> Context.generic -> Context.generic |
|
59127
723b11f8ffbf
more careful handling of auxiliary environment structure -- allow nested ML evaluation;
wenzelm
parents:
59058
diff
changeset
|
11 |
val forget_structure: string -> Context.generic -> Context.generic |
60746 | 12 |
val get_breakpoint: Context.generic -> serial -> (bool Unsynchronized.ref * Position.T) option |
62941 | 13 |
val add_breakpoints: (serial * (bool Unsynchronized.ref * Thread_Position.T)) list -> unit |
62873
2f9c8a18f832
support bootstrap from fresh SML environment, with syntax of Isabelle/ML or SML;
wenzelm
parents:
62839
diff
changeset
|
14 |
val init_bootstrap: Context.generic -> Context.generic |
62902
3c0f53eae166
more conventional theory syntax for ML bootstrap, with 'ML_file' instead of 'use';
wenzelm
parents:
62889
diff
changeset
|
15 |
val SML_environment: bool Config.T |
68813 | 16 |
val set_global: bool -> Context.generic -> Context.generic |
17 |
val restore_global: Context.generic -> Context.generic -> Context.generic |
|
60858 | 18 |
val add_name_space: {SML: bool} -> ML_Name_Space.T -> Context.generic -> Context.generic |
62495 | 19 |
val make_name_space: {SML: bool, exchange: bool} -> ML_Name_Space.T |
20 |
val context: ML_Compiler0.context |
|
21 |
val name_space: ML_Name_Space.T |
|
36163
823c9400eb62
proper checking of ML functors (in Poly/ML 5.2 or later);
wenzelm
parents:
33519
diff
changeset
|
22 |
val check_functor: string -> unit |
31325 | 23 |
end |
24 |
||
25 |
structure ML_Env: ML_ENV = |
|
26 |
struct |
|
27 |
||
68814 | 28 |
(* name space tables *) |
31328 | 29 |
|
56275
600f432ab556
added command 'SML_file' for Standard ML without Isabelle/ML add-ons;
wenzelm
parents:
56203
diff
changeset
|
30 |
type tables = |
62934 | 31 |
PolyML.NameSpace.Values.value Symtab.table * |
32 |
PolyML.NameSpace.TypeConstrs.typeConstr Symtab.table * |
|
33 |
PolyML.NameSpace.Infixes.fixity Symtab.table * |
|
34 |
PolyML.NameSpace.Structures.structureVal Symtab.table * |
|
35 |
PolyML.NameSpace.Signatures.signatureVal Symtab.table * |
|
36 |
PolyML.NameSpace.Functors.functorVal Symtab.table; |
|
56275
600f432ab556
added command 'SML_file' for Standard ML without Isabelle/ML add-ons;
wenzelm
parents:
56203
diff
changeset
|
37 |
|
68814 | 38 |
val empty_tables: tables = |
39 |
(Symtab.empty, Symtab.empty, Symtab.empty, Symtab.empty, Symtab.empty, Symtab.empty); |
|
40 |
||
56275
600f432ab556
added command 'SML_file' for Standard ML without Isabelle/ML add-ons;
wenzelm
parents:
56203
diff
changeset
|
41 |
fun merge_tables |
600f432ab556
added command 'SML_file' for Standard ML without Isabelle/ML add-ons;
wenzelm
parents:
56203
diff
changeset
|
42 |
((val1, type1, fixity1, structure1, signature1, functor1), |
600f432ab556
added command 'SML_file' for Standard ML without Isabelle/ML add-ons;
wenzelm
parents:
56203
diff
changeset
|
43 |
(val2, type2, fixity2, structure2, signature2, functor2)) : tables = |
600f432ab556
added command 'SML_file' for Standard ML without Isabelle/ML add-ons;
wenzelm
parents:
56203
diff
changeset
|
44 |
(Symtab.merge (K true) (val1, val2), |
600f432ab556
added command 'SML_file' for Standard ML without Isabelle/ML add-ons;
wenzelm
parents:
56203
diff
changeset
|
45 |
Symtab.merge (K true) (type1, type2), |
600f432ab556
added command 'SML_file' for Standard ML without Isabelle/ML add-ons;
wenzelm
parents:
56203
diff
changeset
|
46 |
Symtab.merge (K true) (fixity1, fixity2), |
600f432ab556
added command 'SML_file' for Standard ML without Isabelle/ML add-ons;
wenzelm
parents:
56203
diff
changeset
|
47 |
Symtab.merge (K true) (structure1, structure2), |
600f432ab556
added command 'SML_file' for Standard ML without Isabelle/ML add-ons;
wenzelm
parents:
56203
diff
changeset
|
48 |
Symtab.merge (K true) (signature1, signature2), |
600f432ab556
added command 'SML_file' for Standard ML without Isabelle/ML add-ons;
wenzelm
parents:
56203
diff
changeset
|
49 |
Symtab.merge (K true) (functor1, functor2)); |
600f432ab556
added command 'SML_file' for Standard ML without Isabelle/ML add-ons;
wenzelm
parents:
56203
diff
changeset
|
50 |
|
68814 | 51 |
val sml_tables: tables = |
52 |
(Symtab.make ML_Name_Space.sml_val, |
|
53 |
Symtab.make ML_Name_Space.sml_type, |
|
54 |
Symtab.make ML_Name_Space.sml_fixity, |
|
55 |
Symtab.make ML_Name_Space.sml_structure, |
|
56 |
Symtab.make ML_Name_Space.sml_signature, |
|
57 |
Symtab.make ML_Name_Space.sml_functor); |
|
58 |
||
59 |
fun bootstrap_tables ((val1, type1, fixity1, structure1, signature1, functor1): tables) : tables = |
|
60 |
let |
|
61 |
val val2 = |
|
62 |
fold (fn (x, y) => |
|
63 |
member (op =) ML_Name_Space.bootstrap_values x ? Symtab.update (x, y)) |
|
64 |
(#allVal ML_Name_Space.global ()) val1; |
|
65 |
val structure2 = |
|
66 |
fold (fn (x, y) => |
|
67 |
member (op =) ML_Name_Space.bootstrap_structures x ? Symtab.update (x, y)) |
|
68 |
(#allStruct ML_Name_Space.global ()) structure1; |
|
69 |
val signature2 = |
|
70 |
fold (fn (x, y) => |
|
71 |
member (op =) ML_Name_Space.bootstrap_signatures x ? Symtab.update (x, y)) |
|
72 |
(#allSig ML_Name_Space.global ()) signature1; |
|
73 |
in (val2, type1, fixity1, structure2, signature2, functor1) end; |
|
74 |
||
75 |
||
76 |
(* context data *) |
|
77 |
||
60746 | 78 |
type data = |
68813 | 79 |
{global: bool, |
60746 | 80 |
tables: tables, |
81 |
sml_tables: tables, |
|
82 |
breakpoints: (bool Unsynchronized.ref * Position.T) Inttab.table}; |
|
56275
600f432ab556
added command 'SML_file' for Standard ML without Isabelle/ML add-ons;
wenzelm
parents:
56203
diff
changeset
|
83 |
|
68813 | 84 |
fun make_data (global, tables, sml_tables, breakpoints) : data = |
85 |
{global = global, tables = tables, sml_tables = sml_tables, breakpoints = breakpoints}; |
|
56275
600f432ab556
added command 'SML_file' for Standard ML without Isabelle/ML add-ons;
wenzelm
parents:
56203
diff
changeset
|
86 |
|
33519 | 87 |
structure Env = Generic_Data |
31325 | 88 |
( |
56275
600f432ab556
added command 'SML_file' for Standard ML without Isabelle/ML add-ons;
wenzelm
parents:
56203
diff
changeset
|
89 |
type T = data |
68814 | 90 |
val empty = make_data (true, empty_tables, sml_tables, Inttab.empty); |
60746 | 91 |
fun extend (data : T) = make_data (false, #tables data, #sml_tables data, #breakpoints data); |
56275
600f432ab556
added command 'SML_file' for Standard ML without Isabelle/ML add-ons;
wenzelm
parents:
56203
diff
changeset
|
92 |
fun merge (data : T * T) = |
600f432ab556
added command 'SML_file' for Standard ML without Isabelle/ML add-ons;
wenzelm
parents:
56203
diff
changeset
|
93 |
make_data (false, |
59058
a78612c67ec0
renamed "pairself" to "apply2", in accordance to @{apply 2};
wenzelm
parents:
56618
diff
changeset
|
94 |
merge_tables (apply2 #tables data), |
60746 | 95 |
merge_tables (apply2 #sml_tables data), |
96 |
Inttab.merge (K true) (apply2 #breakpoints data)); |
|
31325 | 97 |
); |
98 |
||
99 |
val inherit = Env.put o Env.get; |
|
100 |
||
59127
723b11f8ffbf
more careful handling of auxiliary environment structure -- allow nested ML evaluation;
wenzelm
parents:
59058
diff
changeset
|
101 |
fun forget_structure name = |
68813 | 102 |
Env.map (fn {global, tables, sml_tables, breakpoints} => |
59127
723b11f8ffbf
more careful handling of auxiliary environment structure -- allow nested ML evaluation;
wenzelm
parents:
59058
diff
changeset
|
103 |
let |
68813 | 104 |
val _ = if global then ML_Name_Space.forget_structure name else (); |
59127
723b11f8ffbf
more careful handling of auxiliary environment structure -- allow nested ML evaluation;
wenzelm
parents:
59058
diff
changeset
|
105 |
val tables' = |
723b11f8ffbf
more careful handling of auxiliary environment structure -- allow nested ML evaluation;
wenzelm
parents:
59058
diff
changeset
|
106 |
(#1 tables, #2 tables, #3 tables, Symtab.delete_safe name (#4 tables), #5 tables, #6 tables); |
68813 | 107 |
in make_data (global, tables', sml_tables, breakpoints) end); |
60746 | 108 |
|
62941 | 109 |
val get_breakpoint = Inttab.lookup o #breakpoints o Env.get; |
60746 | 110 |
|
62941 | 111 |
fun add_breakpoints more_breakpoints = |
112 |
if is_some (Context.get_generic_context ()) then |
|
113 |
Context.>> |
|
68813 | 114 |
(Env.map (fn {global, tables, sml_tables, breakpoints} => |
62941 | 115 |
let val breakpoints' = |
116 |
fold (Inttab.update_new o (apsnd o apsnd) Position.make) more_breakpoints breakpoints; |
|
68813 | 117 |
in make_data (global, tables, sml_tables, breakpoints') end)) |
62941 | 118 |
else (); |
59127
723b11f8ffbf
more careful handling of auxiliary environment structure -- allow nested ML evaluation;
wenzelm
parents:
59058
diff
changeset
|
119 |
|
31328 | 120 |
|
62902
3c0f53eae166
more conventional theory syntax for ML bootstrap, with 'ML_file' instead of 'use';
wenzelm
parents:
62889
diff
changeset
|
121 |
(* SML environment for Isabelle/ML *) |
3c0f53eae166
more conventional theory syntax for ML bootstrap, with 'ML_file' instead of 'use';
wenzelm
parents:
62889
diff
changeset
|
122 |
|
3c0f53eae166
more conventional theory syntax for ML bootstrap, with 'ML_file' instead of 'use';
wenzelm
parents:
62889
diff
changeset
|
123 |
val SML_environment = |
64556 | 124 |
Config.bool (Config.declare ("SML_environment", \<^here>) (fn _ => Config.Bool false)); |
62902
3c0f53eae166
more conventional theory syntax for ML bootstrap, with 'ML_file' instead of 'use';
wenzelm
parents:
62889
diff
changeset
|
125 |
|
3c0f53eae166
more conventional theory syntax for ML bootstrap, with 'ML_file' instead of 'use';
wenzelm
parents:
62889
diff
changeset
|
126 |
fun sml_env SML = |
3c0f53eae166
more conventional theory syntax for ML bootstrap, with 'ML_file' instead of 'use';
wenzelm
parents:
62889
diff
changeset
|
127 |
SML orelse |
3c0f53eae166
more conventional theory syntax for ML bootstrap, with 'ML_file' instead of 'use';
wenzelm
parents:
62889
diff
changeset
|
128 |
(case Context.get_generic_context () of |
3c0f53eae166
more conventional theory syntax for ML bootstrap, with 'ML_file' instead of 'use';
wenzelm
parents:
62889
diff
changeset
|
129 |
NONE => false |
3c0f53eae166
more conventional theory syntax for ML bootstrap, with 'ML_file' instead of 'use';
wenzelm
parents:
62889
diff
changeset
|
130 |
| SOME context => Config.get_generic context SML_environment); |
3c0f53eae166
more conventional theory syntax for ML bootstrap, with 'ML_file' instead of 'use';
wenzelm
parents:
62889
diff
changeset
|
131 |
|
3c0f53eae166
more conventional theory syntax for ML bootstrap, with 'ML_file' instead of 'use';
wenzelm
parents:
62889
diff
changeset
|
132 |
|
56618
874bdedb2313
added command 'SML_export' and 'SML_import' for exchange of toplevel bindings;
wenzelm
parents:
56275
diff
changeset
|
133 |
(* name space *) |
56275
600f432ab556
added command 'SML_file' for Standard ML without Isabelle/ML add-ons;
wenzelm
parents:
56203
diff
changeset
|
134 |
|
62873
2f9c8a18f832
support bootstrap from fresh SML environment, with syntax of Isabelle/ML or SML;
wenzelm
parents:
62839
diff
changeset
|
135 |
val init_bootstrap = |
68813 | 136 |
Env.map (fn {global, tables, sml_tables, breakpoints} => |
68814 | 137 |
make_data (global, tables, bootstrap_tables sml_tables, breakpoints)); |
62873
2f9c8a18f832
support bootstrap from fresh SML environment, with syntax of Isabelle/ML or SML;
wenzelm
parents:
62839
diff
changeset
|
138 |
|
68813 | 139 |
fun set_global global = |
68276 | 140 |
Env.map (fn {tables, sml_tables, breakpoints, ...} => |
68813 | 141 |
make_data (global, tables, sml_tables, breakpoints)); |
68276 | 142 |
|
68813 | 143 |
val restore_global = set_global o #global o Env.get; |
68276 | 144 |
|
60858 | 145 |
fun add_name_space {SML} (space: ML_Name_Space.T) = |
68813 | 146 |
Env.map (fn {global, tables, sml_tables, breakpoints} => |
60858 | 147 |
let |
148 |
val (tables', sml_tables') = |
|
62902
3c0f53eae166
more conventional theory syntax for ML bootstrap, with 'ML_file' instead of 'use';
wenzelm
parents:
62889
diff
changeset
|
149 |
(tables, sml_tables) |> (if sml_env SML then apsnd else apfst) |
60858 | 150 |
(fn (val1, type1, fixity1, structure1, signature1, functor1) => |
151 |
let |
|
152 |
val val2 = fold Symtab.update (#allVal space ()) val1; |
|
153 |
val type2 = fold Symtab.update (#allType space ()) type1; |
|
154 |
val fixity2 = fold Symtab.update (#allFix space ()) fixity1; |
|
155 |
val structure2 = fold Symtab.update (#allStruct space ()) structure1; |
|
156 |
val signature2 = fold Symtab.update (#allSig space ()) signature1; |
|
157 |
val functor2 = fold Symtab.update (#allFunct space ()) functor1; |
|
158 |
in (val2, type2, fixity2, structure2, signature2, functor2) end); |
|
68813 | 159 |
in make_data (global, tables', sml_tables', breakpoints) end); |
60858 | 160 |
|
62495 | 161 |
fun make_name_space {SML, exchange} : ML_Name_Space.T = |
31325 | 162 |
let |
163 |
fun lookup sel1 sel2 name = |
|
62902
3c0f53eae166
more conventional theory syntax for ML bootstrap, with 'ML_file' instead of 'use';
wenzelm
parents:
62889
diff
changeset
|
164 |
if sml_env SML then |
62876 | 165 |
Context.the_generic_context () |
56618
874bdedb2313
added command 'SML_export' and 'SML_import' for exchange of toplevel bindings;
wenzelm
parents:
56275
diff
changeset
|
166 |
|> (fn context => Symtab.lookup (sel1 (#sml_tables (Env.get context))) name) |
874bdedb2313
added command 'SML_export' and 'SML_import' for exchange of toplevel bindings;
wenzelm
parents:
56275
diff
changeset
|
167 |
else |
62889 | 168 |
Context.get_generic_context () |
56618
874bdedb2313
added command 'SML_export' and 'SML_import' for exchange of toplevel bindings;
wenzelm
parents:
56275
diff
changeset
|
169 |
|> (fn NONE => NONE | SOME context => Symtab.lookup (sel1 (#tables (Env.get context))) name) |
874bdedb2313
added command 'SML_export' and 'SML_import' for exchange of toplevel bindings;
wenzelm
parents:
56275
diff
changeset
|
170 |
|> (fn NONE => sel2 ML_Name_Space.global name | some => some); |
31325 | 171 |
|
172 |
fun all sel1 sel2 () = |
|
62902
3c0f53eae166
more conventional theory syntax for ML bootstrap, with 'ML_file' instead of 'use';
wenzelm
parents:
62889
diff
changeset
|
173 |
(if sml_env SML then |
62876 | 174 |
Context.the_generic_context () |
56618
874bdedb2313
added command 'SML_export' and 'SML_import' for exchange of toplevel bindings;
wenzelm
parents:
56275
diff
changeset
|
175 |
|> (fn context => Symtab.dest (sel1 (#sml_tables (Env.get context)))) |
874bdedb2313
added command 'SML_export' and 'SML_import' for exchange of toplevel bindings;
wenzelm
parents:
56275
diff
changeset
|
176 |
else |
62889 | 177 |
Context.get_generic_context () |
56618
874bdedb2313
added command 'SML_export' and 'SML_import' for exchange of toplevel bindings;
wenzelm
parents:
56275
diff
changeset
|
178 |
|> (fn NONE => [] | SOME context => Symtab.dest (sel1 (#tables (Env.get context)))) |
874bdedb2313
added command 'SML_export' and 'SML_import' for exchange of toplevel bindings;
wenzelm
parents:
56275
diff
changeset
|
179 |
|> append (sel2 ML_Name_Space.global ())) |
59058
a78612c67ec0
renamed "pairself" to "apply2", in accordance to @{apply 2};
wenzelm
parents:
56618
diff
changeset
|
180 |
|> sort_distinct (string_ord o apply2 #1); |
31325 | 181 |
|
182 |
fun enter ap1 sel2 entry = |
|
62902
3c0f53eae166
more conventional theory syntax for ML bootstrap, with 'ML_file' instead of 'use';
wenzelm
parents:
62889
diff
changeset
|
183 |
if sml_env SML <> exchange then |
68813 | 184 |
Context.>> (Env.map (fn {global, tables, sml_tables, breakpoints} => |
56618
874bdedb2313
added command 'SML_export' and 'SML_import' for exchange of toplevel bindings;
wenzelm
parents:
56275
diff
changeset
|
185 |
let val sml_tables' = ap1 (Symtab.update entry) sml_tables |
68813 | 186 |
in make_data (global, tables, sml_tables', breakpoints) end)) |
62889 | 187 |
else if is_some (Context.get_generic_context ()) then |
68813 | 188 |
Context.>> (Env.map (fn {global, tables, sml_tables, breakpoints} => |
56203
76c72f4d0667
clarified bootstrap process: switch to ML with context and antiquotations earlier;
wenzelm
parents:
48992
diff
changeset
|
189 |
let |
68813 | 190 |
val _ = if global then sel2 ML_Name_Space.global entry else (); |
56275
600f432ab556
added command 'SML_file' for Standard ML without Isabelle/ML add-ons;
wenzelm
parents:
56203
diff
changeset
|
191 |
val tables' = ap1 (Symtab.update entry) tables; |
68813 | 192 |
in make_data (global, tables', sml_tables, breakpoints) end)) |
31325 | 193 |
else sel2 ML_Name_Space.global entry; |
194 |
in |
|
195 |
{lookupVal = lookup #1 #lookupVal, |
|
196 |
lookupType = lookup #2 #lookupType, |
|
197 |
lookupFix = lookup #3 #lookupFix, |
|
198 |
lookupStruct = lookup #4 #lookupStruct, |
|
199 |
lookupSig = lookup #5 #lookupSig, |
|
200 |
lookupFunct = lookup #6 #lookupFunct, |
|
201 |
enterVal = enter (fn h => fn (a, b, c, d, e, f) => (h a, b, c, d, e, f)) #enterVal, |
|
202 |
enterType = enter (fn h => fn (a, b, c, d, e, f) => (a, h b, c, d, e, f)) #enterType, |
|
203 |
enterFix = enter (fn h => fn (a, b, c, d, e, f) => (a, b, h c, d, e, f)) #enterFix, |
|
204 |
enterStruct = enter (fn h => fn (a, b, c, d, e, f) => (a, b, c, h d, e, f)) #enterStruct, |
|
205 |
enterSig = enter (fn h => fn (a, b, c, d, e, f) => (a, b, c, d, h e, f)) #enterSig, |
|
206 |
enterFunct = enter (fn h => fn (a, b, c, d, e, f) => (a, b, c, d, e, h f)) #enterFunct, |
|
207 |
allVal = all #1 #allVal, |
|
208 |
allType = all #2 #allType, |
|
209 |
allFix = all #3 #allFix, |
|
210 |
allStruct = all #4 #allStruct, |
|
211 |
allSig = all #5 #allSig, |
|
212 |
allFunct = all #6 #allFunct} |
|
213 |
end; |
|
214 |
||
62495 | 215 |
val context: ML_Compiler0.context = |
216 |
{name_space = make_name_space {SML = false, exchange = false}, |
|
62716
d80b9f4990e4
explicit print_depth for the sake of Spec_Check.determine_type;
wenzelm
parents:
62657
diff
changeset
|
217 |
print_depth = NONE, |
62493 | 218 |
here = Position.here oo Position.line_file, |
31325 | 219 |
print = writeln, |
220 |
error = error}; |
|
221 |
||
62495 | 222 |
val name_space = #name_space context; |
56618
874bdedb2313
added command 'SML_export' and 'SML_import' for exchange of toplevel bindings;
wenzelm
parents:
56275
diff
changeset
|
223 |
|
62495 | 224 |
val is_functor = is_some o #lookupFunct name_space; |
36163
823c9400eb62
proper checking of ML functors (in Poly/ML 5.2 or later);
wenzelm
parents:
33519
diff
changeset
|
225 |
|
823c9400eb62
proper checking of ML functors (in Poly/ML 5.2 or later);
wenzelm
parents:
33519
diff
changeset
|
226 |
fun check_functor name = |
36165 | 227 |
if not (is_functor "Table") (*mask dummy version of name_space*) orelse is_functor name then () |
36163
823c9400eb62
proper checking of ML functors (in Poly/ML 5.2 or later);
wenzelm
parents:
33519
diff
changeset
|
228 |
else error ("Unknown ML functor: " ^ quote name); |
823c9400eb62
proper checking of ML functors (in Poly/ML 5.2 or later);
wenzelm
parents:
33519
diff
changeset
|
229 |
|
31325 | 230 |
end; |