| author | bulwahn | 
| Tue, 09 Jun 2009 13:40:57 +0200 | |
| changeset 31515 | 62fc203eed88 | 
| parent 31156 | 90fed3d4430f | 
| child 31599 | 97b4d289c646 | 
| permissions | -rw-r--r-- | 
| 24219 | 1 | (* Title: Tools/code/code_target.ML | 
| 2 | Author: Florian Haftmann, TU Muenchen | |
| 3 | ||
| 28054 | 4 | Serializer from intermediate language ("Thin-gol") to target languages.
 | 
| 24219 | 5 | *) | 
| 6 | ||
| 7 | signature CODE_TARGET = | |
| 8 | sig | |
| 28054 | 9 | include CODE_PRINTER | 
| 10 | ||
| 11 | type serializer | |
| 28064 | 12 | val add_target: string * (serializer * literals) -> theory -> theory | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 13 | val extend_target: string * | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 14 | (string * (Code_Thingol.naming -> Code_Thingol.program -> Code_Thingol.program)) | 
| 28054 | 15 | -> theory -> theory | 
| 16 | val assert_target: theory -> string -> string | |
| 24219 | 17 | |
| 28054 | 18 | type destination | 
| 19 | type serialization | |
| 20 | val parse_args: (OuterLex.token list -> 'a * OuterLex.token list) | |
| 21 | -> OuterLex.token list -> 'a | |
| 22 | val stmt_names_of_destination: destination -> string list | |
| 23 | val code_of_pretty: Pretty.T -> string | |
| 24 | val code_writeln: Pretty.T -> unit | |
| 25 |   val mk_serialization: string -> ('a -> unit) option
 | |
| 26 | -> (Path.T option -> 'a -> unit) | |
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 27 |     -> ('a -> string * string option list)
 | 
| 28054 | 28 | -> 'a -> serialization | 
| 30513 | 29 | val serialize: theory -> string -> string option -> OuterLex.token list | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 30 | -> Code_Thingol.naming -> Code_Thingol.program -> string list -> serialization | 
| 28064 | 31 | val serialize_custom: theory -> string * (serializer * literals) | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 32 | -> Code_Thingol.naming -> Code_Thingol.program -> string list -> string * string option list | 
| 28090 
29af3c712d2b
distributed literal code generation out of central infrastructure
 haftmann parents: 
28064diff
changeset | 33 | val the_literals: theory -> string -> literals | 
| 28054 | 34 | val compile: serialization -> unit | 
| 35 | val export: serialization -> unit | |
| 36 | val file: Path.T -> serialization -> unit | |
| 37 | val string: string list -> serialization -> string | |
| 28690 | 38 | val code_of: theory -> string -> string | 
| 39 | -> string list -> (Code_Thingol.naming -> string list) -> string | |
| 30494 
c150e6fa4e0d
consider exit status of code generation direcitve
 haftmann parents: 
30242diff
changeset | 40 | val shell_command: string (*theory name*) -> string (*export_code expr*) -> unit | 
| 28054 | 41 | val code_width: int ref | 
| 42 | ||
| 43 | val allow_abort: string -> theory -> theory | |
| 28690 | 44 | val add_syntax_class: string -> class -> string option -> theory -> theory | 
| 28054 | 45 | val add_syntax_inst: string -> string * class -> bool -> theory -> theory | 
| 46 | val add_syntax_tyco: string -> string -> tyco_syntax option -> theory -> theory | |
| 31056 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 47 | val add_syntax_const: string -> string -> proto_const_syntax option -> theory -> theory | 
| 28054 | 48 | val add_reserved: string -> string -> theory -> theory | 
| 24219 | 49 | end; | 
| 50 | ||
| 28054 | 51 | structure Code_Target : CODE_TARGET = | 
| 24219 | 52 | struct | 
| 53 | ||
| 28054 | 54 | open Basic_Code_Thingol; | 
| 55 | open Code_Printer; | |
| 24219 | 56 | |
| 57 | (** basics **) | |
| 58 | ||
| 27304 | 59 | datatype destination = Compile | Export | File of Path.T | String of string list; | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 60 | type serialization = destination -> (string * string option list) option; | 
| 27014 
a5f53d9d2b60
yet another attempt to circumvent printmode problems
 haftmann parents: 
27001diff
changeset | 61 | |
| 27103 | 62 | val code_width = ref 80; (*FIXME after Pretty module no longer depends on print mode*) | 
| 63 | fun code_setmp f = PrintMode.setmp [] (Pretty.setmp_margin (!code_width) f); | |
| 64 | fun code_of_pretty p = code_setmp Pretty.string_of p ^ "\n"; | |
| 65 | fun code_writeln p = Pretty.setmp_margin (!code_width) Pretty.writeln p; | |
| 26998 | 66 | |
| 27103 | 67 | (*FIXME why another code_setmp?*) | 
| 68 | fun compile f = (code_setmp f Compile; ()); | |
| 27304 | 69 | fun export f = (code_setmp f Export; ()); | 
| 27103 | 70 | fun file p f = (code_setmp f (File p); ()); | 
| 30963 | 71 | fun string stmts f = fst (the (code_setmp f (String stmts))); | 
| 27304 | 72 | |
| 73 | fun stmt_names_of_destination (String stmts) = stmts | |
| 74 | | stmt_names_of_destination _ = []; | |
| 27014 
a5f53d9d2b60
yet another attempt to circumvent printmode problems
 haftmann parents: 
27001diff
changeset | 75 | |
| 28054 | 76 | fun mk_serialization target (SOME comp) _ _ code Compile = (comp code; NONE) | 
| 77 | | mk_serialization target NONE _ _ _ Compile = error (target ^ ": no internal compilation") | |
| 78 | | mk_serialization target _ output _ code Export = (output NONE code ; NONE) | |
| 79 | | mk_serialization target _ output _ code (File file) = (output (SOME file) code; NONE) | |
| 80 | | mk_serialization target _ _ string code (String _) = SOME (string code); | |
| 27550 | 81 | |
| 24219 | 82 | |
| 28054 | 83 | (** theory data **) | 
| 84 | ||
| 85 | datatype name_syntax_table = NameSyntaxTable of {
 | |
| 28690 | 86 | class: string Symtab.table, | 
| 30648 
17365ef082f3
clarified relationship of modules Code_Name and Code_Printer
 haftmann parents: 
30513diff
changeset | 87 | instance: unit Symreltab.table, | 
| 28054 | 88 | tyco: tyco_syntax Symtab.table, | 
| 31056 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 89 | const: proto_const_syntax Symtab.table | 
| 28054 | 90 | }; | 
| 27000 | 91 | |
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 92 | fun mk_name_syntax_table ((class, instance), (tyco, const)) = | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 93 |   NameSyntaxTable { class = class, instance = instance, tyco = tyco, const = const };
 | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 94 | fun map_name_syntax_table f (NameSyntaxTable { class, instance, tyco, const }) =
 | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 95 | mk_name_syntax_table (f ((class, instance), (tyco, const))); | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 96 | fun merge_name_syntax_table (NameSyntaxTable { class = class1, instance = instance1, tyco = tyco1, const = const1 },
 | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 97 |     NameSyntaxTable { class = class2, instance = instance2, tyco = tyco2, const = const2 }) =
 | 
| 28054 | 98 | mk_name_syntax_table ( | 
| 99 | (Symtab.join (K snd) (class1, class2), | |
| 30648 
17365ef082f3
clarified relationship of modules Code_Name and Code_Printer
 haftmann parents: 
30513diff
changeset | 100 | Symreltab.join (K snd) (instance1, instance2)), | 
| 28054 | 101 | (Symtab.join (K snd) (tyco1, tyco2), | 
| 102 | Symtab.join (K snd) (const1, const2)) | |
| 103 | ); | |
| 104 | ||
| 105 | type serializer = | |
| 106 | string option (*module name*) | |
| 30513 | 107 | -> OuterLex.token list (*arguments*) | 
| 28054 | 108 | -> (string -> string) (*labelled_name*) | 
| 109 | -> string list (*reserved symbols*) | |
| 110 | -> (string * Pretty.T) list (*includes*) | |
| 111 | -> (string -> string option) (*module aliasses*) | |
| 28690 | 112 | -> (string -> string option) (*class syntax*) | 
| 28054 | 113 | -> (string -> tyco_syntax option) | 
| 114 | -> (string -> const_syntax option) | |
| 115 | -> Code_Thingol.program | |
| 116 | -> string list (*selected statements*) | |
| 117 | -> serialization; | |
| 27000 | 118 | |
| 28064 | 119 | datatype serializer_entry = Serializer of serializer * literals | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 120 | | Extends of string * (Code_Thingol.naming -> Code_Thingol.program -> Code_Thingol.program); | 
| 28054 | 121 | |
| 122 | datatype target = Target of {
 | |
| 123 | serial: serial, | |
| 124 | serializer: serializer_entry, | |
| 125 | reserved: string list, | |
| 28926 | 126 | includes: (Pretty.T * string list) Symtab.table, | 
| 28054 | 127 | name_syntax_table: name_syntax_table, | 
| 128 | module_alias: string Symtab.table | |
| 129 | }; | |
| 27103 | 130 | |
| 28054 | 131 | fun mk_target ((serial, serializer), ((reserved, includes), (name_syntax_table, module_alias))) = | 
| 132 |   Target { serial = serial, serializer = serializer, reserved = reserved, 
 | |
| 133 | includes = includes, name_syntax_table = name_syntax_table, module_alias = module_alias }; | |
| 134 | fun map_target f ( Target { serial, serializer, reserved, includes, name_syntax_table, module_alias } ) =
 | |
| 135 | mk_target (f ((serial, serializer), ((reserved, includes), (name_syntax_table, module_alias)))); | |
| 136 | fun merge_target strict target (Target { serial = serial1, serializer = serializer,
 | |
| 137 | reserved = reserved1, includes = includes1, | |
| 138 | name_syntax_table = name_syntax_table1, module_alias = module_alias1 }, | |
| 139 |     Target { serial = serial2, serializer = _,
 | |
| 140 | reserved = reserved2, includes = includes2, | |
| 141 | name_syntax_table = name_syntax_table2, module_alias = module_alias2 }) = | |
| 142 | if serial1 = serial2 orelse not strict then | |
| 143 | mk_target ((serial1, serializer), | |
| 144 | ((merge (op =) (reserved1, reserved2), Symtab.merge (op =) (includes1, includes2)), | |
| 145 | (merge_name_syntax_table (name_syntax_table1, name_syntax_table2), | |
| 146 | Symtab.join (K snd) (module_alias1, module_alias2)) | |
| 147 | )) | |
| 148 | else | |
| 149 |     error ("Incompatible serializers: " ^ quote target);
 | |
| 27103 | 150 | |
| 28054 | 151 | structure CodeTargetData = TheoryDataFun | 
| 27436 | 152 | ( | 
| 28054 | 153 | type T = target Symtab.table * string list; | 
| 154 | val empty = (Symtab.empty, []); | |
| 155 | val copy = I; | |
| 156 | val extend = I; | |
| 157 | fun merge _ ((target1, exc1) : T, (target2, exc2)) = | |
| 158 | (Symtab.join (merge_target true) (target1, target2), Library.merge (op =) (exc1, exc2)); | |
| 27436 | 159 | ); | 
| 160 | ||
| 28054 | 161 | fun the_serializer (Target { serializer, ... }) = serializer;
 | 
| 162 | fun the_reserved (Target { reserved, ... }) = reserved;
 | |
| 163 | fun the_includes (Target { includes, ... }) = includes;
 | |
| 164 | fun the_name_syntax (Target { name_syntax_table = NameSyntaxTable x, ... }) = x;
 | |
| 165 | fun the_module_alias (Target { module_alias , ... }) = module_alias;
 | |
| 27437 | 166 | |
| 28054 | 167 | val abort_allowed = snd o CodeTargetData.get; | 
| 27436 | 168 | |
| 28054 | 169 | fun assert_target thy target = | 
| 170 | case Symtab.lookup (fst (CodeTargetData.get thy)) target | |
| 171 | of SOME data => target | |
| 172 |     | NONE => error ("Unknown code target language: " ^ quote target);
 | |
| 173 | ||
| 174 | fun put_target (target, seri) thy = | |
| 27304 | 175 | let | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 176 | val lookup_target = Symtab.lookup (fst (CodeTargetData.get thy)); | 
| 28054 | 177 | val _ = case seri | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 178 | of Extends (super, _) => if is_some (lookup_target super) then () | 
| 28054 | 179 |           else error ("Unknown code target language: " ^ quote super)
 | 
| 180 | | _ => (); | |
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 181 | val overwriting = case (Option.map the_serializer o lookup_target) target | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 182 | of NONE => false | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 183 | | SOME (Extends _) => true | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 184 | | SOME (Serializer _) => (case seri | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 185 |          of Extends _ => error ("Will not overwrite existing target " ^ quote target)
 | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 186 | | _ => true); | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 187 | val _ = if overwriting | 
| 28054 | 188 |       then warning ("Overwriting existing target " ^ quote target)
 | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 189 | else (); | 
| 28054 | 190 | in | 
| 191 | thy | |
| 192 | |> (CodeTargetData.map o apfst oo Symtab.map_default) | |
| 193 | (target, mk_target ((serial (), seri), (([], Symtab.empty), | |
| 30648 
17365ef082f3
clarified relationship of modules Code_Name and Code_Printer
 haftmann parents: 
30513diff
changeset | 194 | (mk_name_syntax_table ((Symtab.empty, Symreltab.empty), (Symtab.empty, Symtab.empty)), | 
| 28054 | 195 | Symtab.empty)))) | 
| 196 | ((map_target o apfst o apsnd o K) seri) | |
| 197 | end; | |
| 27436 | 198 | |
| 28054 | 199 | fun add_target (target, seri) = put_target (target, Serializer seri); | 
| 200 | fun extend_target (target, (super, modify)) = | |
| 201 | put_target (target, Extends (super, modify)); | |
| 27436 | 202 | |
| 28054 | 203 | fun map_target_data target f thy = | 
| 27436 | 204 | let | 
| 28054 | 205 | val _ = assert_target thy target; | 
| 206 | in | |
| 207 | thy | |
| 208 | |> (CodeTargetData.map o apfst o Symtab.map_entry target o map_target) f | |
| 209 | end; | |
| 27304 | 210 | |
| 28054 | 211 | fun map_reserved target = | 
| 212 | map_target_data target o apsnd o apfst o apfst; | |
| 213 | fun map_includes target = | |
| 214 | map_target_data target o apsnd o apfst o apsnd; | |
| 215 | fun map_name_syntax target = | |
| 216 | map_target_data target o apsnd o apsnd o apfst o map_name_syntax_table; | |
| 217 | fun map_module_alias target = | |
| 218 | map_target_data target o apsnd o apsnd o apsnd; | |
| 27000 | 219 | |
| 220 | ||
| 28054 | 221 | (** serializer configuration **) | 
| 27000 | 222 | |
| 223 | (* data access *) | |
| 24219 | 224 | |
| 225 | local | |
| 226 | ||
| 24992 | 227 | fun cert_class thy class = | 
| 228 | let | |
| 229 | val _ = AxClass.get_info thy class; | |
| 230 | in class end; | |
| 231 | ||
| 27103 | 232 | fun read_class thy = cert_class thy o Sign.intern_class thy; | 
| 24992 | 233 | |
| 234 | fun cert_tyco thy tyco = | |
| 235 | let | |
| 236 | val _ = if Sign.declared_tyname thy tyco then () | |
| 237 |       else error ("No such type constructor: " ^ quote tyco);
 | |
| 238 | in tyco end; | |
| 239 | ||
| 27103 | 240 | fun read_tyco thy = cert_tyco thy o Sign.intern_type thy; | 
| 24219 | 241 | |
| 242 | fun gen_add_syntax_class prep_class prep_const target raw_class raw_syn thy = | |
| 243 | let | |
| 24841 | 244 | val class = prep_class thy raw_class; | 
| 24219 | 245 | in case raw_syn | 
| 28690 | 246 | of SOME syntax => | 
| 24219 | 247 | thy | 
| 27024 | 248 | |> (map_name_syntax target o apfst o apfst) | 
| 28690 | 249 | (Symtab.update (class, syntax)) | 
| 24219 | 250 | | NONE => | 
| 251 | thy | |
| 27024 | 252 | |> (map_name_syntax target o apfst o apfst) | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 253 | (Symtab.delete_safe class) | 
| 24219 | 254 | end; | 
| 255 | ||
| 256 | fun gen_add_syntax_inst prep_class prep_tyco target (raw_tyco, raw_class) add_del thy = | |
| 257 | let | |
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 258 | val inst = (prep_class thy raw_class, prep_tyco thy raw_tyco); | 
| 24219 | 259 | in if add_del then | 
| 260 | thy | |
| 27024 | 261 | |> (map_name_syntax target o apfst o apsnd) | 
| 30648 
17365ef082f3
clarified relationship of modules Code_Name and Code_Printer
 haftmann parents: 
30513diff
changeset | 262 | (Symreltab.update (inst, ())) | 
| 24219 | 263 | else | 
| 264 | thy | |
| 27024 | 265 | |> (map_name_syntax target o apfst o apsnd) | 
| 30648 
17365ef082f3
clarified relationship of modules Code_Name and Code_Printer
 haftmann parents: 
30513diff
changeset | 266 | (Symreltab.delete_safe inst) | 
| 24219 | 267 | end; | 
| 268 | ||
| 269 | fun gen_add_syntax_tyco prep_tyco target raw_tyco raw_syn thy = | |
| 270 | let | |
| 271 | val tyco = prep_tyco thy raw_tyco; | |
| 272 | fun check_args (syntax as (n, _)) = if n <> Sign.arity_number thy tyco | |
| 273 |       then error ("Number of arguments mismatch in syntax for type constructor " ^ quote tyco)
 | |
| 274 | else syntax | |
| 275 | in case raw_syn | |
| 276 | of SOME syntax => | |
| 277 | thy | |
| 27024 | 278 | |> (map_name_syntax target o apsnd o apfst) | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 279 | (Symtab.update (tyco, check_args syntax)) | 
| 28690 | 280 | | NONE => | 
| 24219 | 281 | thy | 
| 27024 | 282 | |> (map_name_syntax target o apsnd o apfst) | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 283 | (Symtab.delete_safe tyco) | 
| 24219 | 284 | end; | 
| 285 | ||
| 286 | fun gen_add_syntax_const prep_const target raw_c raw_syn thy = | |
| 287 | let | |
| 288 | val c = prep_const thy raw_c; | |
| 31156 | 289 | fun check_args (syntax as (n, _)) = if n > Code.no_args thy c | 
| 24423 
ae9cd0e92423
overloaded definitions accompanied by explicit constants
 haftmann parents: 
24381diff
changeset | 290 |       then error ("Too many arguments in syntax for constant " ^ quote c)
 | 
| 24219 | 291 | else syntax; | 
| 292 | in case raw_syn | |
| 293 | of SOME syntax => | |
| 294 | thy | |
| 27024 | 295 | |> (map_name_syntax target o apsnd o apsnd) | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 296 | (Symtab.update (c, check_args syntax)) | 
| 28690 | 297 | | NONE => | 
| 24219 | 298 | thy | 
| 27024 | 299 | |> (map_name_syntax target o apsnd o apsnd) | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 300 | (Symtab.delete_safe c) | 
| 24219 | 301 | end; | 
| 302 | ||
| 303 | fun add_reserved target = | |
| 304 | let | |
| 305 | fun add sym syms = if member (op =) syms sym | |
| 306 |       then error ("Reserved symbol " ^ quote sym ^ " already declared")
 | |
| 307 | else insert (op =) sym syms | |
| 27103 | 308 | in map_reserved target o add end; | 
| 24992 | 309 | |
| 28926 | 310 | fun gen_add_include read_const target args thy = | 
| 24992 | 311 | let | 
| 28926 | 312 | fun add (name, SOME (content, raw_cs)) incls = | 
| 24992 | 313 | let | 
| 314 | val _ = if Symtab.defined incls name | |
| 315 |               then warning ("Overwriting existing include " ^ name)
 | |
| 316 | else (); | |
| 28926 | 317 | val cs = map (read_const thy) raw_cs; | 
| 318 | in Symtab.update (name, (str content, cs)) incls end | |
| 319 | | add (name, NONE) incls = Symtab.delete name incls; | |
| 320 | in map_includes target (add args) thy end; | |
| 321 | ||
| 31156 | 322 | val add_include = gen_add_include Code.check_const; | 
| 323 | val add_include_cmd = gen_add_include Code.read_const; | |
| 24219 | 324 | |
| 31013 | 325 | fun add_module_alias target (thyname, modlname) = | 
| 326 | let | |
| 327 | val xs = Long_Name.explode modlname; | |
| 31036 | 328 | val xs' = map (Name.desymbolize true) xs; | 
| 31013 | 329 | in if xs' = xs | 
| 330 | then map_module_alias target (Symtab.update (thyname, modlname)) | |
| 331 |     else error ("Invalid module name: " ^ quote modlname ^ "\n"
 | |
| 332 | ^ "perhaps try " ^ quote (Long_Name.implode xs')) | |
| 333 | end; | |
| 24219 | 334 | |
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 335 | fun gen_allow_abort prep_const raw_c thy = | 
| 24841 | 336 | let | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 337 | val c = prep_const thy raw_c; | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 338 | in thy |> (CodeTargetData.map o apsnd) (insert (op =) c) end; | 
| 24841 | 339 | |
| 24219 | 340 | fun zip_list (x::xs) f g = | 
| 341 | f | |
| 342 | #-> (fn y => | |
| 343 | fold_map (fn x => g |-- f >> pair x) xs | |
| 344 | #-> (fn xys => pair ((x, y) :: xys))); | |
| 345 | ||
| 27000 | 346 | |
| 27103 | 347 | (* concrete syntax *) | 
| 27000 | 348 | |
| 24219 | 349 | structure P = OuterParse | 
| 350 | and K = OuterKeyword | |
| 351 | ||
| 352 | fun parse_multi_syntax parse_thing parse_syntax = | |
| 353 | P.and_list1 parse_thing | |
| 354 |   #-> (fn things => Scan.repeat1 (P.$$$ "(" |-- P.name --
 | |
| 355 | (zip_list things parse_syntax (P.$$$ "and")) --| P.$$$ ")")); | |
| 356 | ||
| 357 | in | |
| 358 | ||
| 359 | val add_syntax_class = gen_add_syntax_class cert_class (K I); | |
| 360 | val add_syntax_inst = gen_add_syntax_inst cert_class cert_tyco; | |
| 361 | val add_syntax_tyco = gen_add_syntax_tyco cert_tyco; | |
| 362 | val add_syntax_const = gen_add_syntax_const (K I); | |
| 27103 | 363 | val allow_abort = gen_allow_abort (K I); | 
| 28054 | 364 | val add_reserved = add_reserved; | 
| 24219 | 365 | |
| 31156 | 366 | val add_syntax_class_cmd = gen_add_syntax_class read_class Code.read_const; | 
| 24219 | 367 | val add_syntax_inst_cmd = gen_add_syntax_inst read_class read_tyco; | 
| 368 | val add_syntax_tyco_cmd = gen_add_syntax_tyco read_tyco; | |
| 31156 | 369 | val add_syntax_const_cmd = gen_add_syntax_const Code.read_const; | 
| 370 | val allow_abort_cmd = gen_allow_abort Code.read_const; | |
| 24219 | 371 | |
| 28064 | 372 | fun the_literals thy = | 
| 373 | let | |
| 374 | val (targets, _) = CodeTargetData.get thy; | |
| 375 | fun literals target = case Symtab.lookup targets target | |
| 376 | of SOME data => (case the_serializer data | |
| 377 | of Serializer (_, literals) => literals | |
| 378 | | Extends (super, _) => literals super) | |
| 379 |       | NONE => error ("Unknown code target language: " ^ quote target);
 | |
| 380 | in literals end; | |
| 381 | ||
| 24867 | 382 | |
| 28054 | 383 | (** serializer usage **) | 
| 384 | ||
| 385 | (* montage *) | |
| 386 | ||
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 387 | local | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 388 | |
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 389 | fun labelled_name thy program name = case Graph.get_node program name | 
| 31156 | 390 | of Code_Thingol.Fun (c, _) => quote (Code.string_of_const thy c) | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 391 | | Code_Thingol.Datatype (tyco, _) => "type " ^ quote (Sign.extern_type thy tyco) | 
| 31156 | 392 | | Code_Thingol.Datatypecons (c, _) => quote (Code.string_of_const thy c) | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 393 | | Code_Thingol.Class (class, _) => "class " ^ quote (Sign.extern_class thy class) | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 394 | | Code_Thingol.Classrel (sub, super) => let | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 395 | val Code_Thingol.Class (sub, _) = Graph.get_node program sub | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 396 | val Code_Thingol.Class (super, _) = Graph.get_node program super | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 397 | in quote (Sign.extern_class thy sub ^ " < " ^ Sign.extern_class thy super) end | 
| 31156 | 398 | | Code_Thingol.Classparam (c, _) => quote (Code.string_of_const thy c) | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 399 | | Code_Thingol.Classinst ((class, (tyco, _)), _) => let | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 400 | val Code_Thingol.Class (class, _) = Graph.get_node program class | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 401 | val Code_Thingol.Datatype (tyco, _) = Graph.get_node program tyco | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 402 | in quote (Sign.extern_type thy tyco ^ " :: " ^ Sign.extern_class thy class) end | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 403 | |
| 31056 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 404 | fun activate_syntax lookup_name src_tab = Symtab.empty | 
| 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 405 | |> fold_map (fn thing_identifier => fn tab => case lookup_name thing_identifier | 
| 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 406 | of SOME name => (SOME name, | 
| 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 407 | Symtab.update_new (name, the (Symtab.lookup src_tab thing_identifier)) tab) | 
| 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 408 | | NONE => (NONE, tab)) (Symtab.keys src_tab) | 
| 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 409 | |>> map_filter I; | 
| 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 410 | |
| 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 411 | fun activate_const_syntax thy literals src_tab naming = (Symtab.empty, naming) | 
| 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 412 | |> fold_map (fn thing_identifier => fn (tab, naming) => | 
| 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 413 | case Code_Thingol.lookup_const naming thing_identifier | 
| 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 414 | of SOME name => let | 
| 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 415 | val (syn, naming') = Code_Printer.activate_const_syntax thy | 
| 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 416 | literals (the (Symtab.lookup src_tab thing_identifier)) naming | 
| 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 417 | in (SOME name, (Symtab.update_new (name, syn) tab, naming')) end | 
| 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 418 | | NONE => (NONE, (tab, naming))) (Symtab.keys src_tab) | 
| 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 419 | |>> map_filter I; | 
| 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 420 | |
| 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 421 | fun invoke_serializer thy abortable serializer literals reserved abs_includes | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 422 | module_alias class instance tyco const module args naming program2 names1 = | 
| 28054 | 423 | let | 
| 31056 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 424 | val (names_class, class') = | 
| 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 425 | activate_syntax (Code_Thingol.lookup_class naming) class; | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 426 | val names_inst = map_filter (Code_Thingol.lookup_instance naming) | 
| 30648 
17365ef082f3
clarified relationship of modules Code_Name and Code_Printer
 haftmann parents: 
30513diff
changeset | 427 | (Symreltab.keys instance); | 
| 31056 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 428 | val (names_tyco, tyco') = | 
| 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 429 | activate_syntax (Code_Thingol.lookup_tyco naming) tyco; | 
| 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 430 | val (names_const, (const', _)) = | 
| 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 431 | activate_const_syntax thy literals const naming; | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 432 | val names_hidden = names_class @ names_inst @ names_tyco @ names_const; | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 433 | val names2 = subtract (op =) names_hidden names1; | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 434 | val program3 = Graph.subgraph (not o member (op =) names_hidden) program2; | 
| 30767 
16c689643a7a
corrected projection of required statement names
 haftmann parents: 
30648diff
changeset | 435 | val names_all = Graph.all_succs program3 names2; | 
| 28926 | 436 | val includes = abs_includes names_all; | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 437 | val program4 = Graph.subgraph (member (op =) names_all) program3; | 
| 28054 | 438 | val empty_funs = filter_out (member (op =) abortable) | 
| 439 | (Code_Thingol.empty_funs program3); | |
| 30024 | 440 |     val _ = if null empty_funs then () else error ("No code equations for "
 | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 441 | ^ commas (map (Sign.extern_const thy) empty_funs)); | 
| 28054 | 442 | in | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 443 | serializer module args (labelled_name thy program2) reserved includes | 
| 28690 | 444 | (Symtab.lookup module_alias) (Symtab.lookup class') | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 445 | (Symtab.lookup tyco') (Symtab.lookup const') | 
| 31056 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 446 | program4 names2 | 
| 28054 | 447 | end; | 
| 448 | ||
| 28926 | 449 | fun mount_serializer thy alt_serializer target module args naming program names = | 
| 28054 | 450 | let | 
| 451 | val (targets, abortable) = CodeTargetData.get thy; | |
| 452 | fun collapse_hierarchy target = | |
| 453 | let | |
| 454 | val data = case Symtab.lookup targets target | |
| 455 | of SOME data => data | |
| 456 |           | NONE => error ("Unknown code target language: " ^ quote target);
 | |
| 457 | in case the_serializer data | |
| 458 | of Serializer _ => (I, data) | |
| 459 | | Extends (super, modify) => let | |
| 460 | val (modify', data') = collapse_hierarchy super | |
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 461 | in (modify' #> modify naming, merge_target false target (data', data)) end | 
| 28054 | 462 | end; | 
| 463 | val (modify, data) = collapse_hierarchy target; | |
| 28064 | 464 | val (serializer, _) = the_default (case the_serializer data | 
| 28054 | 465 | of Serializer seri => seri) alt_serializer; | 
| 466 | val reserved = the_reserved data; | |
| 28926 | 467 | fun select_include names_all (name, (content, cs)) = | 
| 468 | if null cs then SOME (name, content) | |
| 469 | else if exists (fn c => case Code_Thingol.lookup_const naming c | |
| 470 | of SOME name => member (op =) names_all name | |
| 471 | | NONE => false) cs | |
| 472 | then SOME (name, content) else NONE; | |
| 473 | fun includes names_all = map_filter (select_include names_all) | |
| 474 | ((Symtab.dest o the_includes) data); | |
| 28054 | 475 | val module_alias = the_module_alias data; | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 476 |     val { class, instance, tyco, const } = the_name_syntax data;
 | 
| 31056 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 477 | val literals = the_literals thy target; | 
| 28054 | 478 | in | 
| 31056 
01ac77eb660b
robustifed infrastructure for complex term syntax during code generation
 haftmann parents: 
31036diff
changeset | 479 | invoke_serializer thy abortable serializer literals reserved | 
| 28926 | 480 | includes module_alias class instance tyco const module args naming (modify program) names | 
| 28054 | 481 | end; | 
| 482 | ||
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 483 | in | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 484 | |
| 28054 | 485 | fun serialize thy = mount_serializer thy NONE; | 
| 486 | ||
| 28926 | 487 | fun serialize_custom thy (target_name, seri) naming program names = | 
| 488 | mount_serializer thy (SOME seri) target_name NONE [] naming program names (String []) | |
| 28054 | 489 | |> the; | 
| 490 | ||
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 491 | end; (* local *) | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 492 | |
| 28054 | 493 | fun parse_args f args = | 
| 494 | case Scan.read OuterLex.stopper f args | |
| 495 | of SOME x => x | |
| 496 | | NONE => error "Bad serializer arguments"; | |
| 497 | ||
| 498 | ||
| 499 | (* code presentation *) | |
| 500 | ||
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 501 | fun code_of thy target module_name cs names_stmt = | 
| 28054 | 502 | let | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 503 | val (names_cs, (naming, program)) = Code_Thingol.consts_program thy cs; | 
| 28054 | 504 | in | 
| 28690 | 505 | string (names_stmt naming) (serialize thy target (SOME module_name) [] | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 506 | naming program names_cs) | 
| 28054 | 507 | end; | 
| 508 | ||
| 509 | ||
| 510 | (* code generation *) | |
| 511 | ||
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 512 | fun transitivly_non_empty_funs thy naming program = | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 513 | let | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 514 | val cs = subtract (op =) (abort_allowed thy) (Code_Thingol.empty_funs program); | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 515 | val names = map_filter (Code_Thingol.lookup_const naming) cs; | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 516 | in subtract (op =) (Graph.all_preds program names) (Graph.keys program) end; | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 517 | |
| 28054 | 518 | fun read_const_exprs thy cs = | 
| 519 | let | |
| 31036 | 520 | val (cs1, cs2) = Code_Thingol.read_const_exprs thy cs; | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 521 | val (names3, (naming, program)) = Code_Thingol.consts_program thy cs2; | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 522 | val names4 = transitivly_non_empty_funs thy naming program; | 
| 28054 | 523 | val cs5 = map_filter | 
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 524 | (fn (c, name) => if member (op =) names4 name then SOME c else NONE) (cs2 ~~ names3); | 
| 28054 | 525 | in fold (insert (op =)) cs5 cs1 end; | 
| 526 | ||
| 527 | fun cached_program thy = | |
| 528 | let | |
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 529 | val (naming, program) = Code_Thingol.cached_program thy; | 
| 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 530 | in (transitivly_non_empty_funs thy naming program, (naming, program)) end | 
| 28054 | 531 | |
| 532 | fun export_code thy cs seris = | |
| 533 | let | |
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 534 | val (cs', (naming, program)) = if null cs then cached_program thy | 
| 28054 | 535 | else Code_Thingol.consts_program thy cs; | 
| 536 | fun mk_seri_dest dest = case dest | |
| 537 | of NONE => compile | |
| 538 | | SOME "-" => export | |
| 539 | | SOME f => file (Path.explode f) | |
| 540 | val _ = map (fn (((target, module), dest), args) => | |
| 28663 
bd8438543bf2
code identifier namings are no longer imperative
 haftmann parents: 
28090diff
changeset | 541 | (mk_seri_dest dest (serialize thy target module args naming program cs'))) seris; | 
| 28054 | 542 | in () end; | 
| 543 | ||
| 544 | fun export_code_cmd raw_cs seris thy = export_code thy (read_const_exprs thy raw_cs) seris; | |
| 545 | ||
| 27103 | 546 | |
| 27304 | 547 | (** Isar setup **) | 
| 27103 | 548 | |
| 549 | val (inK, module_nameK, fileK) = ("in", "module_name", "file");
 | |
| 550 | ||
| 30494 
c150e6fa4e0d
consider exit status of code generation direcitve
 haftmann parents: 
30242diff
changeset | 551 | val code_exprP = | 
| 27757 
650af1991b8b
fall back on P.term_group, to avoid problems with inner_syntax markup (due to CodeName.read_const_exprs);
 wenzelm parents: 
27710diff
changeset | 552 | (Scan.repeat P.term_group | 
| 27103 | 553 | -- Scan.repeat (P.$$$ inK |-- P.name | 
| 554 | -- Scan.option (P.$$$ module_nameK |-- P.name) | |
| 555 | -- Scan.option (P.$$$ fileK |-- P.name) | |
| 27809 
a1e409db516b
unified Args.T with OuterLex.token, renamed some operations;
 wenzelm parents: 
27757diff
changeset | 556 |      -- Scan.optional (P.$$$ "(" |-- Args.parse --| P.$$$ ")") []
 | 
| 30494 
c150e6fa4e0d
consider exit status of code generation direcitve
 haftmann parents: 
30242diff
changeset | 557 | ) >> (fn (raw_cs, seris) => export_code_cmd raw_cs seris)); | 
| 27103 | 558 | |
| 28054 | 559 | val _ = List.app OuterKeyword.keyword [inK, module_nameK, fileK]; | 
| 24867 | 560 | |
| 561 | val _ = | |
| 24992 | 562 | OuterSyntax.command "code_class" "define code syntax for class" K.thy_decl ( | 
| 28690 | 563 | parse_multi_syntax P.xname (Scan.option P.string) | 
| 24219 | 564 | >> (Toplevel.theory oo fold) (fn (target, syns) => | 
| 565 | fold (fn (raw_class, syn) => add_syntax_class_cmd target raw_class syn) syns) | |
| 566 | ); | |
| 567 | ||
| 24867 | 568 | val _ = | 
| 24992 | 569 | OuterSyntax.command "code_instance" "define code syntax for instance" K.thy_decl ( | 
| 24219 | 570 | parse_multi_syntax (P.xname --| P.$$$ "::" -- P.xname) | 
| 571 | ((P.minus >> K true) || Scan.succeed false) | |
| 572 | >> (Toplevel.theory oo fold) (fn (target, syns) => | |
| 573 | fold (fn (raw_inst, add_del) => add_syntax_inst_cmd target raw_inst add_del) syns) | |
| 574 | ); | |
| 575 | ||
| 24867 | 576 | val _ = | 
| 24992 | 577 | OuterSyntax.command "code_type" "define code syntax for type constructor" K.thy_decl ( | 
| 24219 | 578 | parse_multi_syntax P.xname (parse_syntax I) | 
| 579 | >> (Toplevel.theory oo fold) (fn (target, syns) => | |
| 580 | fold (fn (raw_tyco, syn) => add_syntax_tyco_cmd target raw_tyco syn) syns) | |
| 581 | ); | |
| 582 | ||
| 24867 | 583 | val _ = | 
| 24992 | 584 | OuterSyntax.command "code_const" "define code syntax for constant" K.thy_decl ( | 
| 27757 
650af1991b8b
fall back on P.term_group, to avoid problems with inner_syntax markup (due to CodeName.read_const_exprs);
 wenzelm parents: 
27710diff
changeset | 585 | parse_multi_syntax P.term_group (parse_syntax fst) | 
| 24219 | 586 | >> (Toplevel.theory oo fold) (fn (target, syns) => | 
| 28054 | 587 | fold (fn (raw_const, syn) => add_syntax_const_cmd target raw_const | 
| 588 | (Code_Printer.simple_const_syntax syn)) syns) | |
| 24219 | 589 | ); | 
| 590 | ||
| 24867 | 591 | val _ = | 
| 24992 | 592 | OuterSyntax.command "code_reserved" "declare words as reserved for target language" K.thy_decl ( | 
| 24219 | 593 | P.name -- Scan.repeat1 P.name | 
| 594 | >> (fn (target, reserveds) => (Toplevel.theory o fold (add_reserved target)) reserveds) | |
| 24841 | 595 | ); | 
| 24219 | 596 | |
| 24867 | 597 | val _ = | 
| 24992 | 598 | OuterSyntax.command "code_include" "declare piece of code to be included in generated code" K.thy_decl ( | 
| 28926 | 599 | P.name -- P.name -- (P.text :|-- (fn "-" => Scan.succeed NONE | 
| 600 | | s => Scan.optional (P.$$$ "attach" |-- Scan.repeat1 P.term) [] >> pair s >> SOME)) | |
| 601 | >> (fn ((target, name), content_consts) => | |
| 602 | (Toplevel.theory o add_include_cmd target) (name, content_consts)) | |
| 24992 | 603 | ); | 
| 604 | ||
| 605 | val _ = | |
| 606 | OuterSyntax.command "code_modulename" "alias module to other name" K.thy_decl ( | |
| 24219 | 607 | P.name -- Scan.repeat1 (P.name -- P.name) | 
| 27103 | 608 | >> (fn (target, modlnames) => (Toplevel.theory o fold (add_module_alias target)) modlnames) | 
| 609 | ); | |
| 610 | ||
| 611 | val _ = | |
| 612 | OuterSyntax.command "code_abort" "permit constant to be implemented as program abort" K.thy_decl ( | |
| 27757 
650af1991b8b
fall back on P.term_group, to avoid problems with inner_syntax markup (due to CodeName.read_const_exprs);
 wenzelm parents: 
27710diff
changeset | 613 | Scan.repeat1 P.term_group >> (Toplevel.theory o fold allow_abort_cmd) | 
| 24841 | 614 | ); | 
| 24219 | 615 | |
| 24867 | 616 | val _ = | 
| 27103 | 617 | OuterSyntax.command "export_code" "generate executable code for constants" | 
| 30494 
c150e6fa4e0d
consider exit status of code generation direcitve
 haftmann parents: 
30242diff
changeset | 618 | K.diag (P.!!! code_exprP >> (fn f => Toplevel.keep (f o Toplevel.theory_of))); | 
| 
c150e6fa4e0d
consider exit status of code generation direcitve
 haftmann parents: 
30242diff
changeset | 619 | |
| 
c150e6fa4e0d
consider exit status of code generation direcitve
 haftmann parents: 
30242diff
changeset | 620 | fun shell_command thyname cmd = Toplevel.program (fn _ => | 
| 
c150e6fa4e0d
consider exit status of code generation direcitve
 haftmann parents: 
30242diff
changeset | 621 | (use_thy thyname; case Scan.read OuterLex.stopper (P.!!! code_exprP) | 
| 
c150e6fa4e0d
consider exit status of code generation direcitve
 haftmann parents: 
30242diff
changeset | 622 | ((filter OuterLex.is_proper o OuterSyntax.scan Position.none) cmd) | 
| 
c150e6fa4e0d
consider exit status of code generation direcitve
 haftmann parents: 
30242diff
changeset | 623 | of SOME f => (writeln "Now generating code..."; f (theory thyname)) | 
| 
c150e6fa4e0d
consider exit status of code generation direcitve
 haftmann parents: 
30242diff
changeset | 624 |     | NONE => error ("Bad directive " ^ quote cmd)))
 | 
| 
c150e6fa4e0d
consider exit status of code generation direcitve
 haftmann parents: 
30242diff
changeset | 625 | handle TOPLEVEL_ERROR => OS.Process.exit OS.Process.failure; | 
| 27103 | 626 | |
| 24219 | 627 | end; (*local*) | 
| 628 | ||
| 629 | end; (*struct*) |