| author | nipkow | 
| Mon, 17 Oct 2016 17:33:07 +0200 | |
| changeset 64272 | f76b6dda2e56 | 
| parent 63806 | c54a53ef1873 | 
| child 67208 | 16519cd83ed4 | 
| 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: 
48456diff
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: 
48456diff
changeset | 45 | val set_default: T -> unit | 
| 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
changeset | 46 | val reset_default: unit -> unit | 
| 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
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 | |
| 63806 | 117 | val bool = get boolT (try Value.parse_bool); | 
| 118 | val int = get intT (try Value.parse_int); | |
| 119 | val real = get realT (try Value.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 | |
| 63806 | 123 | val put_bool = put boolT Value.print_bool; | 
| 124 | val put_int = put intT Value.print_int; | |
| 125 | val put_real = put realT Value.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: 
48456diff
changeset | 174 | |
| 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
changeset | 175 | |
| 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
changeset | 176 | (** global default **) | 
| 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
changeset | 177 | |
| 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
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: 
48456diff
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: 
48456diff
changeset | 187 | fun default () = | 
| 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
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: 
48456diff
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: 
48456diff
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: 
48456diff
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: 
48456diff
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: 
48456diff
changeset | 211 | |
| 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
changeset | 212 | fun load_default () = | 
| 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
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: 
48456diff
changeset | 214 | "" => () | 
| 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
changeset | 215 | | name => | 
| 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
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: 
48456diff
changeset | 217 | (case try File.read path of | 
| 62885 | 218 | SOME s => set_default (decode (YXML.parse_body s)) | 
| 48698 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
changeset | 219 | | NONE => ()) | 
| 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
changeset | 220 | end); | 
| 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
changeset | 221 | |
| 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
changeset | 222 | val _ = load_default (); | 
| 62878 | 223 | val _ = ML_Print_Depth.set_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: 
48456diff
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; |