src/Pure/Tools/codegen_package.ML
changeset 19884 a7be206d8655
parent 19816 a8c8ed1c85e0
child 19953 2f54a51f1801
equal deleted inserted replaced
19883:d064712bdd1d 19884:a7be206d8655
     6 intermediate language ("Thin-gol").
     6 intermediate language ("Thin-gol").
     7 *)
     7 *)
     8 
     8 
     9 signature CODEGEN_PACKAGE =
     9 signature CODEGEN_PACKAGE =
    10 sig
    10 sig
    11   type auxtab;
    11   val codegen_term: term -> theory -> CodegenThingol.iexpr * theory;
    12   type appgen = theory -> auxtab
    12   val is_dtcon: string -> bool;
    13     -> (string * typ) * term list -> CodegenThingol.transact
    13   val consts_of_idfs: theory -> string list -> (string * typ) list;
    14     -> CodegenThingol.iexpr * CodegenThingol.transact;
    14   val idfs_of_consts: theory -> (string * typ) list -> string list;
    15 
    15   val get_root_module: theory -> CodegenThingol.module;
    16   val add_appconst: xstring * ((int * int) * appgen) -> theory -> theory;
    16   val get_ml_fun_datatype: theory -> (string -> string)
    17   val add_appconst_i: string * ((int * int) * appgen) -> theory -> theory;
    17     -> ((string * CodegenThingol.funn) list -> Pretty.T)
       
    18         * ((string * CodegenThingol.datatyp) list -> Pretty.T);
       
    19 
    18   val add_pretty_list: string -> string -> string * (int * string)
    20   val add_pretty_list: string -> string -> string * (int * string)
    19     -> theory -> theory;
    21     -> theory -> theory;
    20   val add_alias: string * string -> theory -> theory;
    22   val add_alias: string * string -> theory -> theory;
    21   val set_get_all_datatype_cons : (theory -> (string * string) list)
    23   val set_get_all_datatype_cons : (theory -> (string * string) list)
    22     -> theory -> theory;
    24     -> theory -> theory;
    23   val set_get_datatype: (theory -> string -> ((string * sort) list * (string * typ list) list) option)
    25   val set_get_datatype: (theory -> string -> ((string * sort) list * (string * typ list) list) option)
    24     -> theory -> theory;
    26     -> theory -> theory;
    25   val set_int_tyco: string -> theory -> theory;
    27   val set_int_tyco: string -> theory -> theory;
    26 
    28 
    27   val codegen_term: term -> theory -> CodegenThingol.iexpr * theory;
    29   type appgen;
    28   val is_dtcon: string -> bool;
    30   val add_appconst: xstring * ((int * int) * appgen) -> theory -> theory;
    29   val consts_of_idfs: theory -> string list -> (string * typ) list;
    31   val add_appconst_i: string * ((int * int) * appgen) -> theory -> theory;
    30   val idfs_of_consts: theory -> (string * typ) list -> string list;
       
    31   val get_root_module: theory -> CodegenThingol.module;
       
    32   val get_ml_fun_datatype: theory -> (string -> string)
       
    33     -> ((string * CodegenThingol.funn) list -> Pretty.T)
       
    34         * ((string * CodegenThingol.datatyp) list -> Pretty.T);
       
    35 
       
    36   val appgen_default: appgen;
    32   val appgen_default: appgen;
    37   val appgen_let: (int -> term -> term list * term)
    33   val appgen_let: (int -> term -> term list * term)
    38     -> appgen;
    34     -> appgen;
    39   val appgen_split: (int -> term -> term list * term)
    35   val appgen_split: (int -> term -> term list * term)
    40     -> appgen;
    36     -> appgen;
    49   (*debugging purpose only*)
    45   (*debugging purpose only*)
    50   structure InstNameMangler: NAME_MANGLER;
    46   structure InstNameMangler: NAME_MANGLER;
    51   structure ConstNameMangler: NAME_MANGLER;
    47   structure ConstNameMangler: NAME_MANGLER;
    52   structure DatatypeconsNameMangler: NAME_MANGLER;
    48   structure DatatypeconsNameMangler: NAME_MANGLER;
    53   structure CodegenData: THEORY_DATA;
    49   structure CodegenData: THEORY_DATA;
    54   val mk_tabs: theory -> string option -> auxtab;
    50   type auxtab;
       
    51   val mk_tabs: theory -> string list option -> auxtab;
    55   val alias_get: theory -> string -> string;
    52   val alias_get: theory -> string -> string;
    56   val idf_of_name: theory -> string -> string -> string;
    53   val idf_of_name: theory -> string -> string -> string;
    57   val idf_of_const: theory -> auxtab -> string * typ -> string;
    54   val idf_of_const: theory -> auxtab -> string * typ -> string;
    58   val idf_of_co: theory -> auxtab -> string * string -> string option;
    55   val idf_of_co: theory -> auxtab -> string * string -> string option;
    59 end;
    56 end;
   198   fun is_valid _ _ = true;
   195   fun is_valid _ _ = true;
   199   fun maybe_unique _ _ = NONE;
   196   fun maybe_unique _ _ = NONE;
   200   fun re_mangle _ dst = error ("no such datatype constructor: " ^ quote dst);
   197   fun re_mangle _ dst = error ("no such datatype constructor: " ^ quote dst);
   201 );
   198 );
   202 
   199 
   203 type auxtab = (string option * deftab)
   200 type auxtab = (bool * string list option * deftab)
   204   * (InstNameMangler.T * (typ list Symtab.table * ConstNameMangler.T)
   201   * (InstNameMangler.T * (typ list Symtab.table * ConstNameMangler.T)
   205   * DatatypeconsNameMangler.T);
   202   * DatatypeconsNameMangler.T);
   206 type eqextr = theory -> auxtab
   203 type eqextr = theory -> auxtab
   207   -> string * typ -> (thm list * typ) option;
   204   -> string * typ -> (thm list * typ) option;
   208 type eqextr_default = theory -> auxtab
   205 type eqextr_default = theory -> auxtab
   396                     of Type (dtco, _) => (idf', dtco)
   393                     of Type (dtco, _) => (idf', dtco)
   397                      | _ => (idf', "nat") (*a hack*)
   394                      | _ => (idf', "nat") (*a hack*)
   398       in SOME (c, dtco) end
   395       in SOME (c, dtco) end
   399     | NONE => NONE;
   396     | NONE => NONE;
   400 
   397 
   401 fun idf_of_const thy (tabs as (deftab, (_, (overltab1, overltab2), _)))
   398 fun idf_of_const thy (tabs as (_, (_, (overltab1, overltab2), _)))
   402       (c, ty) =
   399       (c, ty) =
   403   let
   400   let
   404     fun get_overloaded (c, ty) =
   401     fun get_overloaded (c, ty) =
   405       (case Symtab.lookup overltab1 c
   402       (case Symtab.lookup overltab1 c
   406        of SOME tys =>
   403        of SOME tys =>
   420     | NONE => case ClassPackage.lookup_const_class thy c
   417     | NONE => case ClassPackage.lookup_const_class thy c
   421    of SOME _ => idf_of_name thy nsp_mem c
   418    of SOME _ => idf_of_name thy nsp_mem c
   422     | NONE => idf_of_name thy nsp_const c
   419     | NONE => idf_of_name thy nsp_const c
   423   end;
   420   end;
   424 
   421 
       
   422 fun idf_of_const' thy (tabs as (_, (_, (overltab1, overltab2), _)))
       
   423       (c, ty) =
       
   424   let
       
   425     fun get_overloaded (c, ty) =
       
   426       (case Symtab.lookup overltab1 c
       
   427        of SOME tys =>
       
   428             (case find_first (curry (Sign.typ_instance thy) ty) tys
       
   429              of SOME ty' => ConstNameMangler.get thy overltab2
       
   430                   (c, ty') |> SOME
       
   431               | _ => NONE)
       
   432         | _ => NONE)
       
   433   in case get_overloaded (c, ty)
       
   434    of SOME idf => idf
       
   435     | NONE => case ClassPackage.lookup_const_class thy c
       
   436    of SOME _ => idf_of_name thy nsp_mem c
       
   437     | NONE => idf_of_name thy nsp_const c
       
   438   end;
       
   439 
   425 fun recconst_of_idf thy (_, (_, (_, overltab2), _)) idf =
   440 fun recconst_of_idf thy (_, (_, (_, overltab2), _)) idf =
   426   case name_of_idf thy nsp_const idf
   441   case name_of_idf thy nsp_const idf
   427    of SOME c => SOME (c, Sign.the_const_type thy c)
   442    of SOME c => SOME (c, Sign.the_const_type thy c)
   428     | NONE => (
   443     | NONE => (
   429         case dest_nsp nsp_overl idf
   444         case dest_nsp nsp_overl idf
   506     ); thy);
   521     ); thy);
   507 
   522 
   508 
   523 
   509 (* definition and expression generators *)
   524 (* definition and expression generators *)
   510 
   525 
   511 fun check_strict thy f x (tabs as ((SOME target, deftab), tabs')) =
   526 fun check_strict thy f x ((false, _, _), _) =
   512       thy
   527       false
   513       |> CodegenData.get
   528   | check_strict thy f x ((_, SOME targets, _), _) =
   514       |> #target_data
   529       exists (
   515       |> (fn data => (the oo Symtab.lookup) data target)
   530         is_none o (fn tab => Symtab.lookup tab x) o f o the o (Symtab.lookup ((#target_data o CodegenData.get) thy))
   516       |> f
   531       ) targets
   517       |> (fn tab => Symtab.lookup tab x)
   532   | check_strict thy f x ((true, _, _), _) =
   518       |> is_none
   533       true;
   519   | check_strict _ _ _ (tabs as ((NONE, _), _)) =
   534 
   520       false;
   535 fun no_strict ((_, targets, deftab), tabs') = ((false, targets, deftab), tabs');
   521 
   536 
   522 fun ensure_def_class thy tabs cls trns =
   537 fun ensure_def_class thy tabs cls trns =
   523   let
   538   let
   524     fun defgen_class thy (tabs as (_, (insttab, _, _))) cls trns =
   539     fun defgen_class thy (tabs as (_, (insttab, _, _))) cls trns =
   525       case name_of_idf thy nsp_class cls
   540       case name_of_idf thy nsp_class cls
   608       |-> (fn clss => pair (Lookup (clss, (v |> unprefix "'", if j = 1 then ~1 else i))))
   623       |-> (fn clss => pair (Lookup (clss, (v |> unprefix "'", if j = 1 then ~1 else i))))
   609 and mk_fun thy tabs (c, ty) trns =
   624 and mk_fun thy tabs (c, ty) trns =
   610   case CodegenTheorems.get_funs thy (c, Logic.legacy_varifyT ty)  (* FIXME *)
   625   case CodegenTheorems.get_funs thy (c, Logic.legacy_varifyT ty)  (* FIXME *)
   611    of SOME (ty, eq_thms) =>
   626    of SOME (ty, eq_thms) =>
   612         let
   627         let
       
   628           val msg = cat_lines ("generating code for theorems " :: map string_of_thm eq_thms);
   613           val sortctxt = ClassPackage.extract_sortctxt thy ty;
   629           val sortctxt = ClassPackage.extract_sortctxt thy ty;
   614           fun dest_eqthm eq_thm =
   630           fun dest_eqthm eq_thm =
   615             let
   631             let
   616               val ((t, args), rhs) =
   632               val ((t, args), rhs) =
   617                 (apfst strip_comb o Logic.dest_equals
   633                 (apfst strip_comb o Logic.dest_equals o prop_of) eq_thm;
   618                   o prop_of) eq_thm;
       
   619             in case t
   634             in case t
   620              of Const (c', _) => if c' = c then (args, rhs)
   635              of Const (c', _) => if c' = c then (args, rhs)
   621                  else error ("illegal function equation for " ^ quote c
   636                  else error ("illegal function equation for " ^ quote c
   622                    ^ ", actually defining " ^ quote c')
   637                    ^ ", actually defining " ^ quote c')
   623               | _ => error ("illegal function equation for " ^ quote c)
   638               | _ => error ("illegal function equation for " ^ quote c)
   624             end;
   639             end;
   625           fun exprgen_eq (args, rhs) trns =
   640           fun exprgen_eq (args, rhs) trns =
   626             trns
   641             trns
   627             |> fold_map (exprgen_term thy tabs) args
   642             |> fold_map (exprgen_term thy tabs) args
   628             ||>> exprgen_term thy tabs rhs
   643             ||>> exprgen_term thy tabs rhs;
   629         in
   644         in
   630           trns
   645           trns
       
   646           |> message msg (fn trns => trns
   631           |> fold_map (exprgen_eq o dest_eqthm) eq_thms
   647           |> fold_map (exprgen_eq o dest_eqthm) eq_thms
   632           ||>> exprgen_type thy tabs ty
   648           ||>> exprgen_type thy tabs ty
   633           ||>> fold_map (exprgen_tyvar_sort thy tabs) sortctxt
   649           ||>> fold_map (exprgen_tyvar_sort thy tabs) sortctxt
   634           |-> (fn ((eqs, ity), sortctxt) => (pair o SOME) ((eqs, (sortctxt, ity)), ty))
   650           |-> (fn ((eqs, ity), sortctxt) => (pair o SOME) ((eqs, (sortctxt, ity)), ty)))
   635         end
   651         end
   636     | NONE => (NONE, trns)
   652     | NONE => (NONE, trns)
   637 and ensure_def_inst thy (tabs as (_, (insttab, _, _))) (cls, tyco) trns =
   653 and ensure_def_inst thy (tabs as (_, (insttab, _, _))) (cls, tyco) trns =
   638   let
   654   let
   639     fun defgen_inst thy (tabs as (_, (insttab, _, _))) inst trns =
   655     fun defgen_inst thy (tabs as (_, (insttab, _, _))) inst trns =
   825         |-> (fn ((((de, dty), se), be), e0) => pair (ICase (((de, dty), [(se, be)]), e0)))
   841         |-> (fn ((((de, dty), se), be), e0) => pair (ICase (((de, dty), [(se, be)]), e0)))
   826     | _ =>
   842     | _ =>
   827         trns
   843         trns
   828         |> appgen_default thy tabs app;
   844         |> appgen_default thy tabs app;
   829 
   845 
   830 fun appgen_number_of bin_to_int thy tabs ((_, Type (_, [_, ty])), [bin]) trns =
   846 fun appgen_number_of int_of_bin thy tabs (app as (c as (_, ty), [bin])) trns =
   831   let
   847   case try (int_of_bin thy) bin
   832     val i = bin_to_int thy bin;
   848    of SOME i => if i < 0 then error ("negative numeral: " ^ IntInf.toString i)
   833       (*preprocessor eliminates nat and negative numerals*)
   849                 (*preprocessor eliminates nat and negative numerals*)
   834     val _ = if i < 0 then error ("negative numeral: " ^ IntInf.toString i) else ();
   850       else
   835   in
   851         trns
   836     trns
   852         |> pair (CodegenThingol.INum (i, IVar ""))
   837     |> exprgen_type thy tabs ty
   853         (*|> exprgen_term thy (no_strict tabs) (Const c)
   838     |-> (fn _ => pair (CodegenThingol.INum (i, ())))
   854         ||>> exprgen_term thy (no_strict tabs) bin
   839   end;
   855         |-> (fn (e1, e2) => pair (CodegenThingol.INum (i, e1 `$ e2)))*)
       
   856     | NONE =>
       
   857         trns
       
   858         |> appgen_default thy tabs app;
   840 
   859 
   841 fun appgen_char char_to_index thy tabs (app as ((_, ty), _)) trns =
   860 fun appgen_char char_to_index thy tabs (app as ((_, ty), _)) trns =
   842   case (char_to_index o list_comb o apfst Const) app
   861   case (char_to_index o list_comb o apfst Const) app
   843    of SOME i =>
   862    of SOME i =>
   844         trns
   863         trns
   854     val ty_def = (op ---> o apfst tl o strip_type o Logic.legacy_unvarifyT o Sign.the_const_type thy) c;
   873     val ty_def = (op ---> o apfst tl o strip_type o Logic.legacy_unvarifyT o Sign.the_const_type thy) c;
   855     val ty' = (op ---> o apfst tl o strip_type) ty;
   874     val ty' = (op ---> o apfst tl o strip_type) ty;
   856     val idf = idf_of_const thy tabs (c, ty);
   875     val idf = idf_of_const thy tabs (c, ty);
   857   in
   876   in
   858     trns
   877     trns
   859     |> ensure_def ((K o succeed) Bot) true ("generating wfrec") idf
   878     |> ensure_def ((K o fail) "no extraction of wfrec") false ("generating wfrec") idf
   860     |> exprgen_type thy tabs ty'
   879     |> exprgen_type thy tabs ty'
   861     ||>> (fold_map o fold_map) (exprgen_classlookup thy tabs)
   880     ||>> (fold_map o fold_map) (exprgen_classlookup thy tabs)
   862            (ClassPackage.extract_classlookup thy (c, ty))
   881            (ClassPackage.extract_classlookup thy (c, ty))
   863     ||>> exprgen_type thy tabs ty_def
   882     ||>> exprgen_type thy tabs ty_def
   864     ||>> exprgen_term thy tabs tf
   883     ||>> exprgen_term thy tabs tf
   904 
   923 
   905 
   924 
   906 
   925 
   907 (** theory interface **)
   926 (** theory interface **)
   908 
   927 
   909 fun mk_tabs thy target =
   928 fun mk_tabs thy targets =
   910   let
   929   let
   911     fun mk_insttab thy =
   930     fun mk_insttab thy =
   912       InstNameMangler.empty
   931       InstNameMangler.empty
   913       |> Symtab.fold_map
   932       |> Symtab.fold_map
   914           (fn (cls, clsinsts) => fold_map
   933           (fn (cls, clsinsts) => fold_map
   968             ) (get_all_datatype_cons thy) [])
   987             ) (get_all_datatype_cons thy) [])
   969       |-> (fn _ => I);
   988       |-> (fn _ => I);
   970     val insttab = mk_insttab thy;
   989     val insttab = mk_insttab thy;
   971     val overltabs = mk_overltabs thy;
   990     val overltabs = mk_overltabs thy;
   972     val dtcontab = mk_dtcontab thy;
   991     val dtcontab = mk_dtcontab thy;
   973   in ((target, Symtab.empty), (insttab, overltabs, dtcontab)) end;
   992   in ((true, targets, Symtab.empty), (insttab, overltabs, dtcontab)) end;
   974 
   993 
   975 fun get_serializer target =
   994 fun get_serializer target =
   976   case Symtab.lookup (!serializers) target
   995   case Symtab.lookup (!serializers) target
   977    of SOME seri => seri
   996    of SOME seri => seri
   978     | NONE => Scan.fail_with (fn _ => "unknown code target language: " ^ quote target) ();
   997     | NONE => Scan.fail_with (fn _ => "unknown code target language: " ^ quote target) ();
   979 
   998 
   980 fun map_module f =
   999 fun map_module f =
   981   map_codegen_data (fn (modl, gens, target_data, logic_data) =>
  1000   map_codegen_data (fn (modl, gens, target_data, logic_data) =>
   982     (f modl, gens, target_data, logic_data));
  1001     (f modl, gens, target_data, logic_data));
   983 
  1002 
   984 (*fun delete_defs NONE thy =
  1003 fun purge_defs NONE thy =
   985       map_module (K CodegenThingol.empty_module) thy
  1004       map_module (K CodegenThingol.empty_module) thy
   986   | delete_defs (SOME c) thy =
  1005   | purge_defs (SOME cs) thy =
   987       let
  1006       let
   988         val tabs = mk_tabs thy NONE;
  1007         val tabs = mk_tabs thy NONE;
       
  1008         val idfs = map (idf_of_const' thy tabs) cs;
       
  1009         val _ = writeln ("purging " ^ commas idfs);
       
  1010         fun purge idfs modl =
       
  1011           CodegenThingol.purge_module (filter (can (get_def modl)) idfs) modl
   989       in
  1012       in
   990         map_module (CodegenThingol.purge_module []) thy
  1013         map_module (purge idfs) thy
   991       end;
  1014       end;
   992 does not make sense:
  1015 
   993 * primitve definitions have to be kept
  1016 fun expand_module targets init gen arg thy =
   994 * *all* overloaded defintitions for a constant have to be purged
       
   995 * precondition: improved representation of definitions hidden by customary serializations
       
   996 *)
       
   997 
       
   998 fun expand_module target init gen arg thy =
       
   999   thy
  1017   thy
  1000   |> CodegenTheorems.notify_dirty
  1018   |> CodegenTheorems.notify_dirty
  1001   |> `(#modl o CodegenData.get)
  1019   |> `(#modl o CodegenData.get)
  1002   |> (fn (modl, thy) =>
  1020   |> (fn (modl, thy) =>
  1003         (start_transact init (gen thy (mk_tabs thy target) arg) modl, thy))
  1021         (start_transact init (gen thy (mk_tabs thy targets) arg) modl, thy))
  1004   |-> (fn (x, modl) => map_module (K modl) #> pair x);
  1022   |-> (fn (x, modl) => map_module (K modl) #> pair x);
  1005 
  1023 
  1006 fun rename_inconsistent thy =
  1024 fun rename_inconsistent thy =
  1007   let
  1025   let
  1008     fun get_inconsistent thyname =
  1026     fun get_inconsistent thyname =
  1009       let
  1027       let
  1010         val thy = theory thyname;
  1028         val thy = theory thyname;
  1011         fun own_tables get =
  1029         fun own_tables get =
  1012           (get thy)
  1030           get thy
  1013           |> fold (Symtab.fold (Symtab.remove (K true)) o get) (Theory.parents_of thy)
  1031           |> fold (Symtab.fold (Symtab.remove (K true)) o get) (Theory.parents_of thy)
  1014           |> Symtab.keys;
  1032           |> Symtab.keys;
  1015         val names = own_tables (#2 o #types o Type.rep_tsig o Sign.tsig_of)
  1033         val names = own_tables (#2 o #types o Type.rep_tsig o Sign.tsig_of)
  1016           @ own_tables (#2 o #constants o Consts.dest o #consts o Sign.rep_sg);
  1034           @ own_tables (#2 o #constants o Consts.dest o #consts o Sign.rep_sg);
  1017         fun diff names =
  1035         fun diff names =
  1051       resolv
  1069       resolv
  1052   end;
  1070   end;
  1053 
  1071 
  1054 
  1072 
  1055 (** target languages **)
  1073 (** target languages **)
  1056 
       
  1057 val ensure_bot = map_module o CodegenThingol.ensure_bot;
       
  1058 
  1074 
  1059 (* syntax *)
  1075 (* syntax *)
  1060 
  1076 
  1061 fun read_typ thy =
  1077 fun read_typ thy =
  1062   Sign.read_typ (thy, K NONE);
  1078   Sign.read_typ (thy, K NONE);
  1108       let
  1124       let
  1109         val _ = get_serializer target;
  1125         val _ = get_serializer target;
  1110         val tyco = prep_tyco thy raw_tyco;
  1126         val tyco = prep_tyco thy raw_tyco;
  1111       in
  1127       in
  1112         thy
  1128         thy
  1113         |> ensure_bot tyco
       
  1114         |> reader
  1129         |> reader
  1115         |-> (fn pretty => map_codegen_data
  1130         |-> (fn pretty => map_codegen_data
  1116           (fn (modl, gens, target_data, logic_data) =>
  1131           (fn (modl, gens, target_data, logic_data) =>
  1117              (modl, gens,
  1132              (modl, gens,
  1118               target_data |> Symtab.map_entry target
  1133               target_data |> Symtab.map_entry target
  1153       let
  1168       let
  1154         val _ = get_serializer target;
  1169         val _ = get_serializer target;
  1155         val c = prep_const thy raw_const;
  1170         val c = prep_const thy raw_const;
  1156       in
  1171       in
  1157         thy
  1172         thy
  1158         |> ensure_bot c
       
  1159         |> reader
  1173         |> reader
  1160         |-> (fn pretty => add_pretty_syntax_const c target pretty)
  1174         |-> (fn pretty => add_pretty_syntax_const c target pretty)
  1161       end;
  1175       end;
  1162   in
  1176   in
  1163     CodegenSerializer.parse_syntax (fn thy => no_args_const thy raw_const)
  1177     CodegenSerializer.parse_syntax (fn thy => no_args_const thy raw_const)
  1182     |> add_pretty_syntax_const cons' target pr'
  1196     |> add_pretty_syntax_const cons' target pr'
  1183   end;
  1197   end;
  1184 
  1198 
  1185 
  1199 
  1186 
  1200 
       
  1201 (** code basis change notifications **)
       
  1202 
       
  1203 val _ = Context.add_setup (CodegenTheorems.add_notify purge_defs);
       
  1204 
       
  1205 
       
  1206 
  1187 (** toplevel interface **)
  1207 (** toplevel interface **)
  1188 
  1208 
  1189 local
  1209 local
  1190 
  1210 
  1191 fun generate_code target (SOME raw_consts) thy =
  1211 fun generate_code targets (SOME raw_consts) thy =
  1192       let
  1212       let
  1193         val consts = map (read_const thy) raw_consts;
  1213         val consts = map (read_const thy) raw_consts;
  1194         val _ = case target of SOME target => (get_serializer target; ()) | _ => ();
  1214         val _ = case targets of SOME targets => (map get_serializer targets; ()) | _ => ();
  1195       in
  1215       in
  1196         thy
  1216         thy
  1197         |> expand_module target NONE (fold_map oo ensure_def_const) consts
  1217         |> expand_module targets NONE (fold_map oo ensure_def_const) consts
  1198         |-> (fn cs => pair (SOME cs))
  1218         |-> (fn cs => pair (SOME cs))
  1199       end
  1219       end
  1200   | generate_code _ NONE thy =
  1220   | generate_code _ NONE thy =
  1201       (NONE, thy);
  1221       (NONE, thy);
  1202 
  1222 
  1208         val target_data =
  1228         val target_data =
  1209           thy
  1229           thy
  1210           |> CodegenData.get
  1230           |> CodegenData.get
  1211           |> #target_data
  1231           |> #target_data
  1212           |> (fn data => (the oo Symtab.lookup) data target);
  1232           |> (fn data => (the oo Symtab.lookup) data target);
  1213         in (seri (
  1233         val s_class = #syntax_class target_data
  1214           (Symtab.lookup o #syntax_class) target_data,
  1234         val s_tyco = #syntax_tyco target_data
  1215           (Option.map fst oo Symtab.lookup o #syntax_tyco) target_data,
  1235         val s_const = #syntax_const target_data
  1216           (Option.map fst oo Symtab.lookup o #syntax_const) target_data
  1236       in
  1217         ) cs module : unit; thy) end;
  1237         (seri (
       
  1238           Symtab.lookup s_class,
       
  1239           (Option.map fst oo Symtab.lookup) s_tyco,
       
  1240           (Option.map fst oo Symtab.lookup) s_const
       
  1241         ) ([] (*TODO: add seri_defs here*), cs) module : unit; thy)
       
  1242       end;
  1218   in
  1243   in
  1219     thy
  1244     thy
  1220     |> generate_code (SOME target) raw_consts
  1245     |> generate_code (SOME [target]) raw_consts
  1221     |-> (fn cs => serialize cs)
  1246     |-> (fn cs => serialize cs)
  1222   end;
  1247   end;
  1223 
  1248 
  1224 fun purge_consts raw_ts thy =
  1249 fun purge_consts raw_ts thy =
  1225   let
  1250   let
  1230 and K = OuterKeyword
  1255 and K = OuterKeyword
  1231 
  1256 
  1232 in
  1257 in
  1233 
  1258 
  1234 val (generateK, serializeK,
  1259 val (generateK, serializeK,
  1235      primclassK, primtycoK, primconstK,
       
  1236      syntax_classK, syntax_tycoK, syntax_constK,
  1260      syntax_classK, syntax_tycoK, syntax_constK,
  1237      purgeK, aliasK) =
  1261      purgeK, aliasK) =
  1238   ("code_generate", "code_serialize",
  1262   ("code_generate", "code_serialize",
  1239    "code_primclass", "code_primtyco", "code_primconst",
  1263    "code_classapp", "code_typapp", "code_constapp",
  1240    "code_syntax_class", "code_syntax_tyco", "code_syntax_const",
       
  1241    "code_purge", "code_alias");
  1264    "code_purge", "code_alias");
  1242 
  1265 
  1243 val generateP =
  1266 val generateP =
  1244   OuterSyntax.command generateK "generate executable code for constants" K.thy_decl (
  1267   OuterSyntax.command generateK "generate executable code for constants" K.thy_decl (
  1245     Scan.option (P.$$$ "(" |-- P.name --| P.$$$ ")")
  1268     (Scan.option (P.$$$ "(" |-- P.list1 P.name --| P.$$$ ")")
       
  1269     >> (fn SOME ["-"] => SOME [] | ts => ts))
  1246     -- Scan.repeat1 P.term
  1270     -- Scan.repeat1 P.term
  1247     >> (fn (target, raw_consts) =>
  1271     >> (fn (targets, raw_consts) =>
  1248           Toplevel.theory (generate_code target (SOME raw_consts) #> snd))
  1272           Toplevel.theory (generate_code targets (SOME raw_consts) #> snd))
  1249   );
  1273   );
  1250 
  1274 
  1251 val serializeP =
  1275 val serializeP =
  1252   OuterSyntax.command serializeK "serialize executable code for constants" K.thy_decl (
  1276   OuterSyntax.command serializeK "serialize executable code for constants" K.thy_decl (
  1253     P.name
  1277     P.name
  1260             Toplevel.theory (serialize_code target seri raw_consts)
  1284             Toplevel.theory (serialize_code target seri raw_consts)
  1261           ))
  1285           ))
  1262   );
  1286   );
  1263 
  1287 
  1264 val syntax_classP =
  1288 val syntax_classP =
  1265   OuterSyntax.command syntax_tycoK "define code syntax for class" K.thy_decl (
  1289   OuterSyntax.command syntax_classK "define code syntax for class" K.thy_decl (
  1266     Scan.repeat1 (
  1290     Scan.repeat1 (
  1267       P.xname
  1291       P.xname
  1268       -- Scan.repeat1 (
  1292       -- Scan.repeat1 (
  1269            P.name -- P.string
  1293            P.name -- P.string
  1270          )
  1294          )
  1307   OuterSyntax.command aliasK "declare an alias for a theory identifier" K.thy_decl (
  1331   OuterSyntax.command aliasK "declare an alias for a theory identifier" K.thy_decl (
  1308     Scan.repeat1 (P.name -- P.name)
  1332     Scan.repeat1 (P.name -- P.name)
  1309       >> (Toplevel.theory oo fold) add_alias
  1333       >> (Toplevel.theory oo fold) add_alias
  1310   );
  1334   );
  1311 
  1335 
  1312 val _ = OuterSyntax.add_parsers [generateP, serializeP, syntax_tycoP, syntax_constP,
  1336 val _ = OuterSyntax.add_parsers [generateP, serializeP,
       
  1337   syntax_classP, syntax_tycoP, syntax_constP,
  1313   purgeP, aliasP];
  1338   purgeP, aliasP];
  1314 
  1339 
  1315 end; (* local *)
  1340 end; (* local *)
  1316 
  1341 
  1317 end; (* struct *)
  1342 end; (* struct *)