| author | wenzelm | 
| Sat, 05 Jun 2021 20:20:25 +0200 | |
| changeset 73814 | c8b4a4f69068 | 
| parent 71911 | d25093536482 | 
| child 74161 | 3f371ba2b4fc | 
| 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 | 
| 71911 | 16 | val dest: T -> (string * Position.T) list | 
| 51942 | 17 | 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 | 18 | 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 | 19 | 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 | 20 | val real: T -> string -> real | 
| 62791 | 21 | 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 | 22 | val string: T -> string -> string | 
| 51943 | 23 | val put_bool: string -> bool -> T -> T | 
| 24 | val put_int: string -> int -> T -> T | |
| 25 | val put_real: string -> real -> T -> T | |
| 26 | val put_string: string -> string -> T -> T | |
| 56465 | 27 |   val declare: {pos: Position.T, name: string, typ: string, value: string} -> T -> T
 | 
| 51943 | 28 | 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 | 29 | 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 | 30 | val default: unit -> T | 
| 51946 | 31 | val default_typ: string -> string | 
| 51942 | 32 | val default_bool: string -> bool | 
| 33 | val default_int: string -> int | |
| 34 | val default_real: string -> real | |
| 62791 | 35 | val default_seconds: string -> Time.time | 
| 51942 | 36 | val default_string: string -> string | 
| 51943 | 37 | val default_put_bool: string -> bool -> unit | 
| 38 | val default_put_int: string -> int -> unit | |
| 39 | val default_put_real: string -> real -> unit | |
| 40 | val default_put_string: string -> string -> unit | |
| 41 | val get_default: string -> string | |
| 42 | 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 | 43 | val set_default: T -> unit | 
| 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
changeset | 44 | val reset_default: unit -> unit | 
| 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
changeset | 45 | 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 | 46 | end; | 
| 
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
 wenzelm parents: diff
changeset | 47 | |
| 
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
 wenzelm parents: diff
changeset | 48 | 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 | 49 | struct | 
| 
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
 wenzelm parents: diff
changeset | 50 | |
| 
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
 wenzelm parents: diff
changeset | 51 | (* representation *) | 
| 
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 | 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 | 54 | 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 | 55 | 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 | 56 | val stringT = "string"; | 
| 51943 | 57 | 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 | 58 | |
| 56465 | 59 | 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 | 60 | |
| 
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
 wenzelm parents: diff
changeset | 61 | 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 | 62 | |
| 71911 | 63 | fun dest (Options tab) = | 
| 64 |   Symtab.fold (fn (name, {pos, ...}) => cons (name, pos)) tab []
 | |
| 65 | |> sort_by #1; | |
| 59812 | 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 | (* typ *) | 
| 84 | ||
| 51943 | 85 | fun typ options name = #typ (check_name options name); | 
| 86 | ||
| 87 | ||
| 88 | (* basic operations *) | |
| 89 | ||
| 90 | fun put T print name x (options as Options tab) = | |
| 91 | let val opt = check_type options name T | |
| 56465 | 92 |   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 | 93 | |
| 51943 | 94 | fun get T parse options name = | 
| 95 | let val opt = check_type options name T in | |
| 96 | (case parse (#value opt) of | |
| 97 | SOME x => x | |
| 98 | | NONE => | |
| 51978 | 99 |         error ("Malformed value for system option " ^ quote name ^
 | 
| 51943 | 100 | " : " ^ T ^ " =\n" ^ quote (#value opt))) | 
| 101 | end; | |
| 102 | ||
| 103 | ||
| 104 | (* 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 | 105 | |
| 63806 | 106 | val bool = get boolT (try Value.parse_bool); | 
| 107 | val int = get intT (try Value.parse_int); | |
| 108 | val real = get realT (try Value.parse_real); | |
| 62791 | 109 | 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 | 110 | 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 | 111 | |
| 63806 | 112 | val put_bool = put boolT Value.print_bool; | 
| 113 | val put_int = put intT Value.print_int; | |
| 114 | val put_real = put realT Value.print_real; | |
| 51943 | 115 | 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 | 116 | |
| 51943 | 117 | |
| 118 | (* external updates *) | |
| 119 | ||
| 120 | fun check_value options name = | |
| 121 | let val opt = check_name options name in | |
| 122 | if #typ opt = boolT then ignore (bool options name) | |
| 123 | else if #typ opt = intT then ignore (int options name) | |
| 124 | else if #typ opt = realT then ignore (real options name) | |
| 125 | else if #typ opt = stringT then ignore (string options name) | |
| 126 | else () | |
| 127 | end; | |
| 48456 
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
 wenzelm parents: diff
changeset | 128 | |
| 56465 | 129 | 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 | 130 | let | 
| 56465 | 131 | val options' = | 
| 132 | (case Symtab.lookup tab name of | |
| 133 | SOME other => | |
| 134 |           error ("Duplicate declaration of system option " ^ quote name ^ Position.here pos ^
 | |
| 135 | Position.here (#pos other)) | |
| 136 |       | NONE => Options (Symtab.update (name, {pos = pos, typ = typ, value = value}) tab));
 | |
| 51943 | 137 | val _ = | 
| 138 | typ = boolT orelse typ = intT orelse typ = realT orelse typ = stringT orelse | |
| 56465 | 139 |         error ("Unknown type for system option " ^ quote name ^ " : " ^ quote typ ^
 | 
| 140 | Position.here pos); | |
| 51943 | 141 | val _ = check_value options' name; | 
| 142 | in options' end; | |
| 143 | ||
| 144 | fun update name value (options as Options tab) = | |
| 145 | let | |
| 146 | val opt = check_name options name; | |
| 56465 | 147 | val options' = | 
| 148 |       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 | 149 | 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 | 150 | 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 | 151 | |
| 
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
 wenzelm parents: diff
changeset | 152 | |
| 
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
 wenzelm parents: diff
changeset | 153 | (* decode *) | 
| 
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
 wenzelm parents: diff
changeset | 154 | |
| 56465 | 155 | fun decode_opt body = | 
| 156 | let open XML.Decode | |
| 157 | in list (pair properties (pair string (pair string string))) end body | |
| 158 | |> map (fn (props, (name, (typ, value))) => | |
| 159 |       {pos = Position.of_properties props, name = name, typ = typ, value = value});
 | |
| 160 | ||
| 161 | 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 | 162 | |
| 48698 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
changeset | 163 | |
| 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
changeset | 164 | |
| 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
changeset | 165 | (** global default **) | 
| 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
changeset | 166 | |
| 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
changeset | 167 | 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 | 168 | |
| 51978 | 169 | fun err_no_default () = error "Missing default for system options within Isabelle process"; | 
| 51943 | 170 | |
| 171 | fun change_default f x y = | |
| 172 | Synchronized.change global_default | |
| 173 | (fn SOME options => SOME (f x y options) | |
| 174 | | NONE => err_no_default ()); | |
| 175 | ||
| 48698 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
changeset | 176 | fun default () = | 
| 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
changeset | 177 | (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 | 178 | SOME options => options | 
| 51943 | 179 | | NONE => err_no_default ()); | 
| 48698 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
changeset | 180 | |
| 51946 | 181 | fun default_typ name = typ (default ()) name; | 
| 51942 | 182 | fun default_bool name = bool (default ()) name; | 
| 183 | fun default_int name = int (default ()) name; | |
| 184 | fun default_real name = real (default ()) name; | |
| 62791 | 185 | fun default_seconds name = seconds (default ()) name; | 
| 51942 | 186 | fun default_string name = string (default ()) name; | 
| 187 | ||
| 51943 | 188 | val default_put_bool = change_default put_bool; | 
| 189 | val default_put_int = change_default put_int; | |
| 190 | val default_put_real = change_default put_real; | |
| 191 | val default_put_string = change_default put_string; | |
| 192 | ||
| 193 | fun get_default name = | |
| 194 | let val options = default () in get (typ options name) SOME options name end; | |
| 195 | val put_default = change_default update; | |
| 196 | ||
| 48698 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
changeset | 197 | 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 | 198 | 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 | 199 | |
| 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
changeset | 200 | fun load_default () = | 
| 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
changeset | 201 | (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 | 202 | "" => () | 
| 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
changeset | 203 | | name => | 
| 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
changeset | 204 | 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 | 205 | (case try File.read path of | 
| 62885 | 206 | 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 | 207 | | NONE => ()) | 
| 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
changeset | 208 | end); | 
| 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
changeset | 209 | |
| 
2585042b1a30
pass Isabelle/Scala system options into ML process of Isar tty or build jobs;
 wenzelm parents: 
48456diff
changeset | 210 | val _ = load_default (); | 
| 62878 | 211 | 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 | 212 | |
| 48456 
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
 wenzelm parents: diff
changeset | 213 | end; |