author | wenzelm |
Fri, 01 Apr 2016 16:31:54 +0200 | |
changeset 62791 | 64ebecf8646c |
parent 62712 | 22a17cec2efe |
child 62875 | 5a0c06491974 |
permissions | -rw-r--r-- |
48456
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
1 |
(* Title: Pure/System/options.ML |
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
2 |
Author: Makarius |
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
3 |
|
51945 | 4 |
System options with external string representation. |
48456
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
5 |
*) |
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
6 |
|
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
7 |
signature OPTIONS = |
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
8 |
sig |
51943 | 9 |
val boolT: string |
10 |
val intT: string |
|
11 |
val realT: string |
|
12 |
val stringT: string |
|
13 |
val unknownT: string |
|
48456
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
14 |
type T |
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
15 |
val empty: T |
59812 | 16 |
val names: T -> string list |
56467 | 17 |
val markup: T -> string * Position.T -> Markup.T |
51942 | 18 |
val typ: T -> string -> string |
48456
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
19 |
val bool: T -> string -> bool |
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
20 |
val int: T -> string -> int |
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
21 |
val real: T -> string -> real |
62791 | 22 |
val seconds: T -> string -> Time.time |
48456
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
23 |
val string: T -> string -> string |
51943 | 24 |
val put_bool: string -> bool -> T -> T |
25 |
val put_int: string -> int -> T -> T |
|
26 |
val put_real: string -> real -> T -> T |
|
27 |
val put_string: string -> string -> T -> T |
|
56465 | 28 |
val declare: {pos: Position.T, name: string, typ: string, value: string} -> T -> T |
51943 | 29 |
val update: string -> string -> T -> T |
48456
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
30 |
val decode: XML.body -> T |
48698
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
31 |
val default: unit -> T |
56467 | 32 |
val default_markup: string * Position.T -> Markup.T |
51946 | 33 |
val default_typ: string -> string |
51942 | 34 |
val default_bool: string -> bool |
35 |
val default_int: string -> int |
|
36 |
val default_real: string -> real |
|
62791 | 37 |
val default_seconds: string -> Time.time |
51942 | 38 |
val default_string: string -> string |
51943 | 39 |
val default_put_bool: string -> bool -> unit |
40 |
val default_put_int: string -> int -> unit |
|
41 |
val default_put_real: string -> real -> unit |
|
42 |
val default_put_string: string -> string -> unit |
|
43 |
val get_default: string -> string |
|
44 |
val put_default: string -> string -> unit |
|
48698
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
45 |
val set_default: T -> unit |
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
46 |
val reset_default: unit -> unit |
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
47 |
val load_default: unit -> unit |
48456
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
48 |
end; |
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
49 |
|
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
50 |
structure Options: OPTIONS = |
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
51 |
struct |
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
52 |
|
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
53 |
(* representation *) |
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
54 |
|
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
55 |
val boolT = "bool"; |
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
56 |
val intT = "int"; |
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
57 |
val realT = "real"; |
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
58 |
val stringT = "string"; |
51943 | 59 |
val unknownT = "unknown"; |
48456
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
60 |
|
56465 | 61 |
datatype T = Options of {pos: Position.T, typ: string, value: string} Symtab.table; |
48456
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
62 |
|
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
63 |
val empty = Options Symtab.empty; |
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
64 |
|
59812 | 65 |
fun names (Options tab) = sort_strings (Symtab.keys tab); |
66 |
||
48456
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
67 |
|
51943 | 68 |
(* check *) |
51942 | 69 |
|
51943 | 70 |
fun check_name (Options tab) name = |
71 |
let val opt = Symtab.lookup tab name in |
|
72 |
if is_some opt andalso #typ (the opt) <> unknownT then the opt |
|
51978 | 73 |
else error ("Unknown system option " ^ quote name) |
51943 | 74 |
end; |
75 |
||
76 |
fun check_type options name typ = |
|
77 |
let val opt = check_name options name in |
|
78 |
if #typ opt = typ then opt |
|
51978 | 79 |
else error ("Ill-typed system option " ^ quote name ^ " : " ^ #typ opt ^ " vs. " ^ typ) |
51943 | 80 |
end; |
51942 | 81 |
|
82 |
||
56467 | 83 |
(* markup *) |
51943 | 84 |
|
56467 | 85 |
fun markup options (name, pos) = |
86 |
let |
|
87 |
val opt = |
|
88 |
check_name options name |
|
89 |
handle ERROR msg => error (msg ^ Position.here pos); |
|
90 |
val props = Position.def_properties_of (#pos opt); |
|
91 |
in Markup.properties props (Markup.entity Markup.system_optionN name) end; |
|
92 |
||
93 |
||
94 |
(* typ *) |
|
95 |
||
51943 | 96 |
fun typ options name = #typ (check_name options name); |
97 |
||
98 |
||
99 |
(* basic operations *) |
|
100 |
||
101 |
fun put T print name x (options as Options tab) = |
|
102 |
let val opt = check_type options name T |
|
56465 | 103 |
in Options (Symtab.update (name, {pos = #pos opt, typ = #typ opt, value = print x}) tab) end; |
48456
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
104 |
|
51943 | 105 |
fun get T parse options name = |
106 |
let val opt = check_type options name T in |
|
107 |
(case parse (#value opt) of |
|
108 |
SOME x => x |
|
109 |
| NONE => |
|
51978 | 110 |
error ("Malformed value for system option " ^ quote name ^ |
51943 | 111 |
" : " ^ T ^ " =\n" ^ quote (#value opt))) |
112 |
end; |
|
113 |
||
114 |
||
115 |
(* internal lookup and update *) |
|
48456
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
116 |
|
51951
fab4ab92e812
more standard Isabelle/ML operations -- avoid inaccurate Bool.fromString;
wenzelm
parents:
51946
diff
changeset
|
117 |
val bool = get boolT (try Markup.parse_bool); |
fab4ab92e812
more standard Isabelle/ML operations -- avoid inaccurate Bool.fromString;
wenzelm
parents:
51946
diff
changeset
|
118 |
val int = get intT (try Markup.parse_int); |
51988 | 119 |
val real = get realT (try Markup.parse_real); |
62791 | 120 |
val seconds = Time.fromReal oo real; |
48456
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
121 |
val string = get stringT SOME; |
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
122 |
|
51951
fab4ab92e812
more standard Isabelle/ML operations -- avoid inaccurate Bool.fromString;
wenzelm
parents:
51946
diff
changeset
|
123 |
val put_bool = put boolT Markup.print_bool; |
fab4ab92e812
more standard Isabelle/ML operations -- avoid inaccurate Bool.fromString;
wenzelm
parents:
51946
diff
changeset
|
124 |
val put_int = put intT Markup.print_int; |
51990 | 125 |
val put_real = put realT Markup.print_real; |
51943 | 126 |
val put_string = put stringT I; |
48456
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
127 |
|
51943 | 128 |
|
129 |
(* external updates *) |
|
130 |
||
131 |
fun check_value options name = |
|
132 |
let val opt = check_name options name in |
|
133 |
if #typ opt = boolT then ignore (bool options name) |
|
134 |
else if #typ opt = intT then ignore (int options name) |
|
135 |
else if #typ opt = realT then ignore (real options name) |
|
136 |
else if #typ opt = stringT then ignore (string options name) |
|
137 |
else () |
|
138 |
end; |
|
48456
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
139 |
|
56465 | 140 |
fun declare {pos, name, typ, value} (Options tab) = |
48456
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
141 |
let |
56465 | 142 |
val options' = |
143 |
(case Symtab.lookup tab name of |
|
144 |
SOME other => |
|
145 |
error ("Duplicate declaration of system option " ^ quote name ^ Position.here pos ^ |
|
146 |
Position.here (#pos other)) |
|
147 |
| NONE => Options (Symtab.update (name, {pos = pos, typ = typ, value = value}) tab)); |
|
51943 | 148 |
val _ = |
149 |
typ = boolT orelse typ = intT orelse typ = realT orelse typ = stringT orelse |
|
56465 | 150 |
error ("Unknown type for system option " ^ quote name ^ " : " ^ quote typ ^ |
151 |
Position.here pos); |
|
51943 | 152 |
val _ = check_value options' name; |
153 |
in options' end; |
|
154 |
||
155 |
fun update name value (options as Options tab) = |
|
156 |
let |
|
157 |
val opt = check_name options name; |
|
56465 | 158 |
val options' = |
159 |
Options (Symtab.update (name, {pos = #pos opt, typ = #typ opt, value = value}) tab); |
|
48456
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
160 |
val _ = check_value options' name; |
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
161 |
in options' end; |
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
162 |
|
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
163 |
|
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
164 |
(* decode *) |
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
165 |
|
56465 | 166 |
fun decode_opt body = |
167 |
let open XML.Decode |
|
168 |
in list (pair properties (pair string (pair string string))) end body |
|
169 |
|> map (fn (props, (name, (typ, value))) => |
|
170 |
{pos = Position.of_properties props, name = name, typ = typ, value = value}); |
|
171 |
||
172 |
fun decode body = fold declare (decode_opt body) empty; |
|
48456
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
173 |
|
48698
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
174 |
|
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
175 |
|
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
176 |
(** global default **) |
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
177 |
|
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
178 |
val global_default = Synchronized.var "Options.default" (NONE: T option); |
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
179 |
|
51978 | 180 |
fun err_no_default () = error "Missing default for system options within Isabelle process"; |
51943 | 181 |
|
182 |
fun change_default f x y = |
|
183 |
Synchronized.change global_default |
|
184 |
(fn SOME options => SOME (f x y options) |
|
185 |
| NONE => err_no_default ()); |
|
186 |
||
48698
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
187 |
fun default () = |
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
188 |
(case Synchronized.value global_default of |
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
189 |
SOME options => options |
51943 | 190 |
| NONE => err_no_default ()); |
48698
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
191 |
|
56467 | 192 |
fun default_markup arg = markup (default ()) arg; |
51946 | 193 |
fun default_typ name = typ (default ()) name; |
51942 | 194 |
fun default_bool name = bool (default ()) name; |
195 |
fun default_int name = int (default ()) name; |
|
196 |
fun default_real name = real (default ()) name; |
|
62791 | 197 |
fun default_seconds name = seconds (default ()) name; |
51942 | 198 |
fun default_string name = string (default ()) name; |
199 |
||
51943 | 200 |
val default_put_bool = change_default put_bool; |
201 |
val default_put_int = change_default put_int; |
|
202 |
val default_put_real = change_default put_real; |
|
203 |
val default_put_string = change_default put_string; |
|
204 |
||
205 |
fun get_default name = |
|
206 |
let val options = default () in get (typ options name) SOME options name end; |
|
207 |
val put_default = change_default update; |
|
208 |
||
48698
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
209 |
fun set_default options = Synchronized.change global_default (K (SOME options)); |
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
210 |
fun reset_default () = Synchronized.change global_default (K NONE); |
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
211 |
|
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
212 |
fun load_default () = |
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
213 |
(case getenv "ISABELLE_PROCESS_OPTIONS" of |
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
214 |
"" => () |
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
215 |
| name => |
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
216 |
let val path = Path.explode name in |
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
217 |
(case try File.read path of |
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
218 |
SOME s => (set_default (decode (YXML.parse_body s)); ignore (try File.rm path)) |
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
219 |
| NONE => ()) |
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
220 |
end); |
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
221 |
|
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
222 |
val _ = load_default (); |
62712 | 223 |
val _ = ML_Pretty.print_depth (default_int "ML_print_depth"); |
48698
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
wenzelm
parents:
48456
diff
changeset
|
224 |
|
48456
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
wenzelm
parents:
diff
changeset
|
225 |
end; |