src/Pure/Tools/codegen_package.ML
changeset 18282 98431741bda3
parent 18247 b17724cae935
child 18304 684832c9fa62
equal deleted inserted replaced
18281:591e8cdea6f7 18282:98431741bda3
     4 
     4 
     5 Code generator from Isabelle theories to
     5 Code generator from Isabelle theories to
     6 intermediate language ("Thin-gol").
     6 intermediate language ("Thin-gol").
     7 *)
     7 *)
     8 
     8 
     9 (*NOTE: for simplifying development, this package contains
     9 (*NOTE: for simplifying developement, this package contains
    10 some stuff which will finally be moved upwards to HOL*)
    10 some stuff which will finally be moved upwards to HOL*)
    11 
    11 
    12 signature CODEGEN_PACKAGE =
    12 signature CODEGEN_PACKAGE =
    13 sig
    13 sig
    14   type deftab;
    14   type deftab;
   118 (* serializer *)
   118 (* serializer *)
   119 
   119 
   120 val serializer_ml =
   120 val serializer_ml =
   121   let
   121   let
   122     val name_root = "Generated";
   122     val name_root = "Generated";
   123     val nsp_conn_ml = [
   123     val nsp_conn = [
   124       [nsp_class, nsp_type, nsp_eq_class], [nsp_const, nsp_inst, nsp_mem, nsp_eq]
   124       [nsp_class, nsp_type, nsp_eq_class], [nsp_const, nsp_inst, nsp_mem, nsp_eq]
   125     ];
   125     ];
   126   in CodegenSerializer.ml_from_thingol nsp_conn_ml name_root end;
   126   in CodegenSerializer.ml_from_thingol nsp_conn name_root end;
   127 
   127 
   128 fun serializer_hs _ _ _ _ =
   128 val serializer_hs =
   129   error ("haskell serialization not implemented yet");
   129   let
       
   130     val name_root = "Generated";
       
   131     val nsp_conn = [
       
   132       [nsp_class, nsp_eq_class], [nsp_type], [nsp_const], [nsp_inst], [nsp_mem], [nsp_eq]
       
   133     ];
       
   134   in CodegenSerializer.haskell_from_thingol nsp_conn name_root end;
   130 
   135 
   131 
   136 
   132 (* theory data for codegen *)
   137 (* theory data for codegen *)
   133 
   138 
   134 type gens = {
   139 type gens = {
   221        syntax_tyco = syntax_tyco, syntax_const = syntax_const } end;
   226        syntax_tyco = syntax_tyco, syntax_const = syntax_const } end;
   222 
   227 
   223 fun merge_serialize_data
   228 fun merge_serialize_data
   224   ({ serializer = serializer, primitives = primitives1,
   229   ({ serializer = serializer, primitives = primitives1,
   225      syntax_tyco = syntax_tyco1, syntax_const = syntax_const1 },
   230      syntax_tyco = syntax_tyco1, syntax_const = syntax_const1 },
   226    { serializer = _, primitives = primitives2,
   231    {serializer = _, primitives = primitives2,
   227      syntax_tyco = syntax_tyco2, syntax_const = syntax_const2 }) =
   232      syntax_tyco = syntax_tyco2, syntax_const = syntax_const2 }) =
   228   { serializer = serializer,
   233   { serializer = serializer,
   229     primitives = CodegenSerializer.merge_prims (primitives1, primitives2) : CodegenSerializer.primitives,
   234     primitives = CodegenSerializer.merge_prims (primitives1, primitives2) : CodegenSerializer.primitives,
   230     syntax_tyco = Symtab.merge (op =) (syntax_tyco1, syntax_tyco2),
   235     syntax_tyco = Symtab.merge (op =) (syntax_tyco1, syntax_tyco2),
   231     syntax_const = Symtab.merge (op =) (syntax_const1, syntax_const2) };
   236     syntax_const = Symtab.merge (op =) (syntax_const1, syntax_const2) };
   313     (fn (modl, gens, lookups, serialize_data, logic_data) =>
   318     (fn (modl, gens, lookups, serialize_data, logic_data) =>
   314        (modl,
   319        (modl,
   315         gens |> map_gens
   320         gens |> map_gens
   316           (fn (codegens_sort, codegens_type, codegens_expr, defgens) =>
   321           (fn (codegens_sort, codegens_type, codegens_expr, defgens) =>
   317             (codegens_sort, codegens_type,
   322             (codegens_sort, codegens_type,
   318              codegens_expr
   323         codegens_expr
   319              |> Output.update_warn (op =) ("overwriting existing expression code generator " ^ name) (name, (cg, stamp ())),
   324              |> Output.update_warn (op =) ("overwriting existing expression code generator " ^ name) (name, (cg, stamp ())),
   320              defgens)),
   325              defgens)),
   321              lookups, serialize_data, logic_data));
   326              lookups, serialize_data, logic_data));
   322 
   327 
   323 fun add_defgen (name, dg) =
   328 fun add_defgen (name, dg) =
   338     (fn (modl, gens, lookups, serialize_data, logic_data) =>
   343     (fn (modl, gens, lookups, serialize_data, logic_data) =>
   339        (modl, gens,
   344        (modl, gens,
   340         lookups |> map_lookups
   345         lookups |> map_lookups
   341           (fn (lookups_tyco, lookups_const) =>
   346           (fn (lookups_tyco, lookups_const) =>
   342             (lookups_tyco |> Symtab.update_new (src, dst),
   347             (lookups_tyco |> Symtab.update_new (src, dst),
   343              lookups_const)), 
   348              lookups_const)),
   344         serialize_data, logic_data));
   349         serialize_data, logic_data));
   345 
   350 
   346 fun add_lookup_const ((src, ty), dst) =
   351 fun add_lookup_const ((src, ty), dst) =
   347   map_codegen_data
   352   map_codegen_data
   348     (fn (modl, gens, lookups, serialize_data, logic_data) =>
   353     (fn (modl, gens, lookups, serialize_data, logic_data) =>
   349        (modl, gens,
   354        (modl, gens,
   350         lookups |> map_lookups
   355         lookups |> map_lookups
   351           (fn (lookups_tyco, lookups_const) =>
   356           (fn (lookups_tyco, lookups_const) =>
   352             (lookups_tyco,
   357             (lookups_tyco,
   353              lookups_const |> Symtab.update_multi (src, (ty, dst)))), 
   358              lookups_const |> Symtab.update_multi (src, (ty, dst)))),
   354         serialize_data, logic_data));
   359         serialize_data, logic_data));
   355 
   360 
   356 fun set_is_datatype f =
   361 fun set_is_datatype f =
   357   map_codegen_data
   362   map_codegen_data
   358     (fn (modl, gens, lookups, serialize_data, logic_data) =>
   363     (fn (modl, gens, lookups, serialize_data, logic_data) =>
   434    of NONE => idf_of_name thy nsp_const name
   439    of NONE => idf_of_name thy nsp_const name
   435     | SOME tab => (the o AList.lookup (Sign.typ_instance thy) tab) ty
   440     | SOME tab => (the o AList.lookup (Sign.typ_instance thy) tab) ty
   436 
   441 
   437 fun cname_of_idf thy ((_, overl_rev), _, _) idf =
   442 fun cname_of_idf thy ((_, overl_rev), _, _) idf =
   438   case Symtab.lookup overl_rev idf
   443   case Symtab.lookup overl_rev idf
   439    of NONE => 
   444    of NONE =>
   440         (case name_of_idf thy nsp_const idf
   445         (case name_of_idf thy nsp_const idf
   441          of NONE => (case name_of_idf thy nsp_mem idf
   446     of NONE => (case name_of_idf thy nsp_mem idf
   442          of NONE => NONE
   447          of NONE => NONE
   443           | SOME n => SOME (n, Sign.the_const_constraint thy n))
   448           | SOME n => SOME (n, Sign.the_const_constraint thy n))
   444           | SOME n => SOME (n, Sign.the_const_constraint thy n))
   449           | SOME n => SOME (n, Sign.the_const_constraint thy n))
   445     | s => s;
   450     | s => s;
   446 
   451 
   507     | SOME (IConst (f, ty)) =>
   512     | SOME (IConst (f, ty)) =>
   508         trns
   513         trns
   509         |> pair f
   514         |> pair f
   510   else (f, trns);
   515   else (f, trns);
   511 
   516 
   512 fun mk_fun thy defs eqs ty trns = 
   517 fun mk_fun thy defs eqs ty trns =
   513   let
   518   let
   514     val sortctxt = ClassPackage.extract_sortctxt thy ty;
   519     val sortctxt = ClassPackage.extract_sortctxt thy ty;
   515     fun mk_sortvar (v, sort) trns =
   520     fun mk_sortvar (v, sort) trns =
   516       trns
   521       trns
   517       |> invoke_cg_sort thy defs sort
   522       |> invoke_cg_sort thy defs sort
   559   trns
   564   trns
   560   |> fold_map (ensure_def_class thy defs)
   565   |> fold_map (ensure_def_class thy defs)
   561        (sort |> filter (ClassPackage.is_class thy) |> map (idf_of_name thy nsp_class))
   566        (sort |> filter (ClassPackage.is_class thy) |> map (idf_of_name thy nsp_class))
   562   |-> (fn sort => succeed sort)
   567   |-> (fn sort => succeed sort)
   563 
   568 
   564 fun codegen_type_default thy defs (v as TVar (_, sort)) trns =
   569 fun codegen_type_default thy defs(v as TVar (_, sort)) trns =
   565       trns
   570       trns
   566       |> invoke_cg_sort thy defs sort
   571       |> invoke_cg_sort thy defs sort
   567       |-> (fn sort => succeed (IVarT (name_of_tvar v, sort)))
   572       |-> (fn sort => succeed (IVarT (name_of_tvar v, sort)))
   568   | codegen_type_default thy defs (v as TFree (_, sort)) trns =
   573   | codegen_type_default thy defs (v as TFree (_, sort)) trns =
   569       trns
   574       trns
   596               |> fold_map (ensure_def_class thy defs) (map (idf_of_name thy nsp_class) clss)
   601               |> fold_map (ensure_def_class thy defs) (map (idf_of_name thy nsp_class) clss)
   597               |-> (fn clss => pair (ClassPackage.Lookup (clss, (name_of_tvar (TFree (v, [])), i))));
   602               |-> (fn clss => pair (ClassPackage.Lookup (clss, (name_of_tvar (TFree (v, [])), i))));
   598         val _ = debug 10 (fn _ => "making application (3)") ();
   603         val _ = debug 10 (fn _ => "making application (3)") ();
   599         fun mk_itapp e [] = e
   604         fun mk_itapp e [] = e
   600           | mk_itapp e lookup = IInst (e, lookup);
   605           | mk_itapp e lookup = IInst (e, lookup);
   601       in 
   606       in
   602         trns
   607         trns
   603         |> debug 10 (fn _ => "making application (4): " ^ f ^ "::" ^ Sign.string_of_typ thy ty ^ " <~> " ^ Sign.string_of_typ thy ty_def)
   608         |> debug 10 (fn _ => "making application (4): " ^ f ^ "::" ^ Sign.string_of_typ thy ty ^ " <~> " ^ Sign.string_of_typ thy ty_def)
   604         |> ensure_def_const thy defs (idf_of_cname thy defs (f, ty))
   609         |> ensure_def_const thy defs (idf_of_cname thy defs (f, ty))
   605         |> debug 10 (fn _ => "making application (5)")
   610         |> debug 10 (fn _ => "making application (5)")
   606         ||>> (fold_map o fold_map) mk_lookup (ClassPackage.extract_sortlookup thy (ty_def, ty))
   611         ||>> (fold_map o fold_map) mk_lookup (ClassPackage.extract_sortlookup thy (ty_def, ty))
   660 
   665 
   661 (* definition generators *)
   666 (* definition generators *)
   662 
   667 
   663 fun defgen_tyco_fallback thy defs tyco trns =
   668 fun defgen_tyco_fallback thy defs tyco trns =
   664   if Symtab.fold (fn (_, { syntax_tyco, ... }) => fn b => b orelse Symtab.defined syntax_tyco tyco)
   669   if Symtab.fold (fn (_, { syntax_tyco, ... }) => fn b => b orelse Symtab.defined syntax_tyco tyco)
   665     ((#serialize_data o CodegenData.get) thy) false 
   670     ((#serialize_data o CodegenData.get) thy) false
   666   then
   671   then
   667     trns
   672     trns
   668     |> debug 5 (fn _ => "trying defgen tyco fallback for " ^ quote tyco)
   673     |> debug 5 (fn _ => "trying defgen tyco fallback for " ^ quote tyco)
   669     |> succeed (Nop, [])
   674     |> succeed (Nop, [])
   670   else
   675   else
   671     trns
   676     trns
   672     |> fail ("no code generation fallback for " ^ quote tyco)
   677     |> fail ("no code generation fallback for " ^ quote tyco)
   673 
   678 
   674 fun defgen_const_fallback thy defs f trns =
   679 fun defgen_const_fallback thy defs f trns =
   675   if Symtab.fold (fn (_, { syntax_const, ... }) => fn b => b orelse Symtab.defined syntax_const f)
   680   if Symtab.fold (fn (_, { syntax_const, ... }) => fn b => b orelse Symtab.defined syntax_const f)
   676     ((#serialize_data o CodegenData.get) thy) false 
   681     ((#serialize_data o CodegenData.get) thy) false
   677   then
   682   then
   678     trns
   683     trns
   679     |> debug 5 (fn _ => "trying defgen const fallback for " ^ quote f)
   684     |> debug 5 (fn _ => "trying defgen const fallback for " ^ quote f)
   680     |> succeed (Nop, [])
   685     |> succeed (Nop, [])
   681   else
   686   else
   707 
   712 
   708 fun defgen_clsmem thy (defs as (_, _, _)) f trns =
   713 fun defgen_clsmem thy (defs as (_, _, _)) f trns =
   709   case name_of_idf thy nsp_mem f
   714   case name_of_idf thy nsp_mem f
   710    of SOME clsmem =>
   715    of SOME clsmem =>
   711         let
   716         let
       
   717           val _ = debug 10 (fn _ => "CLSMEM " ^ quote clsmem) ();
       
   718           val _ = debug 10 (fn _ => (the o ClassPackage.lookup_const_class thy) clsmem) ();
   712           val cls = idf_of_name thy nsp_class ((the o ClassPackage.lookup_const_class thy) clsmem);
   719           val cls = idf_of_name thy nsp_class ((the o ClassPackage.lookup_const_class thy) clsmem);
   713           val (tvar, ty) = ClassPackage.get_const_sign thy clsmem;
   720           val (tvar, ty) = ClassPackage.get_const_sign thy clsmem;
   714         in
   721         in
   715           trns
   722           trns
   716           |> debug 5 (fn _ => "trying defgen class member for " ^ quote f)
   723           |> debug 5 (fn _ => "trying defgen class member for " ^ quote f)
   723 fun defgen_clsinst thy defs clsinst trns =
   730 fun defgen_clsinst thy defs clsinst trns =
   724   case inst_of_idf thy defs clsinst
   731   case inst_of_idf thy defs clsinst
   725    of SOME (cls, tyco) =>
   732    of SOME (cls, tyco) =>
   726         let
   733         let
   727           val arity = (map o map) (idf_of_name thy nsp_class)
   734           val arity = (map o map) (idf_of_name thy nsp_class)
   728             (ClassPackage.get_arities thy [cls] tyco)
   735             (ClassPackage.get_arities thy [cls] tyco);
   729           val clsmems = map (idf_of_name thy nsp_mem)
   736           val clsmems = map (idf_of_name thy nsp_mem)
   730             (ClassPackage.the_consts thy cls);
   737             (ClassPackage.the_consts thy cls);
   731           val instmem_idfs = map (idf_of_cname thy defs)
   738           val instmem_idfs = map (idf_of_cname thy defs)
   732             (ClassPackage.get_inst_consts_sign thy (tyco, cls));
   739             (ClassPackage.get_inst_consts_sign thy (tyco, cls));
       
   740           fun add_vars arity clsmems (trns as (_, univ)) =
       
   741             ((invent_var_t_names
       
   742               (map ((fn Classmember (_, _, ty) => ty) o get_def univ)
       
   743               clsmems) (length arity) [] "a" ~~ arity, clsmems), trns)
   733         in
   744         in
   734           trns
   745           trns
   735           |> debug 5 (fn _ => "trying defgen class instance for (" ^ quote cls ^ ", " ^ quote tyco ^ ")")
   746           |> debug 5 (fn _ => "trying defgen class instance for (" ^ quote cls ^ ", " ^ quote tyco ^ ")")
   736           |> ensure_def_class thy defs (idf_of_name thy nsp_class cls)
   747           |> (fold_map o fold_map) (ensure_def_class thy defs) arity
       
   748           ||>> fold_map (ensure_def_const thy defs) clsmems
       
   749           |-> (fn (arity, clsmems) => add_vars arity clsmems)
       
   750           ||>> ensure_def_class thy defs (idf_of_name thy nsp_class cls)
   737           ||>> ensure_def_tyco thy defs (idf_of_tname thy tyco)
   751           ||>> ensure_def_tyco thy defs (idf_of_tname thy tyco)
   738           ||>> (fold_map o fold_map) (ensure_def_class thy defs) arity
       
   739           ||>> fold_map (ensure_def_const thy defs) clsmems
       
   740           ||>> fold_map (ensure_def_const thy defs) instmem_idfs
   752           ||>> fold_map (ensure_def_const thy defs) instmem_idfs
   741           |-> (fn ((((cls, tyco), arity), clsmems), instmem_idfs) =>
   753           |-> (fn ((((arity, clsmems), cls), tyco), instmem_idfs) =>
   742                  succeed (Classinst (cls, (tyco, arity), clsmems ~~ instmem_idfs), []))
   754                  succeed (Classinst (cls, (tyco, arity), clsmems ~~ instmem_idfs), []))
   743         end
   755         end
   744     | _ =>
   756     | _ =>
   745         trns |> fail ("no class instance found for " ^ quote clsinst);
   757         trns |> fail ("no class instance found for " ^ quote clsinst);
   746 
   758 
   857                 |-> succeed
   869                 |-> succeed
   858               end
   870               end
   859         )
   871         )
   860     | _ =>
   872     | _ =>
   861         trns
   873         trns
   862         |> fail ("not a case constant expression: " ^ Sign.string_of_term thy t)
   874         |> fail ("not a caseconstant expression: " ^ Sign.string_of_term thy t)
   863   end;
   875   end;
   864 
   876 
   865 fun defgen_datatype get_datatype thy defs tyco trns =
   877 fun defgen_datatype get_datatype thy defs tyco trns =
   866   case tname_of_idf thy tyco
   878   case tname_of_idf thy tyco
   867    of SOME dtname =>
   879    of SOME dtname =>
   950         |> List.mapPartial mangle
   962         |> List.mapPartial mangle
   951         |> Library.flat
   963         |> Library.flat
   952         |> null ? K ["x"]
   964         |> null ? K ["x"]
   953         |> space_implode "_"
   965         |> space_implode "_"
   954       end;
   966       end;
   955     fun add_def (name, [(ty, (_, (args, rhs)))]) (overl, defs, clstab) =
   967     fun mangle_instname thyname (cls, tyco) =
   956           (overl,
       
   957            defs |> Symtab.update_new (idf_of_name thy nsp_const name, (args, rhs, ty)),
       
   958            clstab)
       
   959       | add_def (name, ds) ((overl, overl_rev), defs, clstab) =
       
   960           let
       
   961             val ty_decl = Sign.the_const_constraint thy name;
       
   962             fun mk_idf ("0", Type ("nat", [])) = "const.Zero"
       
   963               | mk_idf ("1", Type ("nat", [])) = "."
       
   964               | mk_idf (nm, ty) =
       
   965                   if is_number nm
       
   966                   then nm
       
   967                   else idf_of_name thy nsp_const nm
       
   968                      ^ "_" ^ mangle_tyname (ty_decl, ty)
       
   969             val overl_lookups = map
       
   970               (fn (ty, (_, (args, rhs))) => (ty, mk_idf (name, ty), args, rhs)) ds;
       
   971           in
       
   972             ((overl |> Symtab.update_new (name, map (fn (ty, idf, _, _) => (ty, idf)) overl_lookups),
       
   973               overl_rev |> fold Symtab.update_new (map (fn (ty, idf, _, _) => (idf, (name, ty))) overl_lookups)),
       
   974              defs |> fold Symtab.update_new (map (fn (ty, idf, args, rhs) => (idf, (args, rhs, ty))) overl_lookups),
       
   975              clstab)
       
   976           end;
       
   977     fun mk_instname thyname (cls, tyco) =
       
   978       idf_of_name thy nsp_inst
   968       idf_of_name thy nsp_inst
   979         (NameSpace.append thyname (NameSpace.base cls ^ "_" ^ NameSpace.base tyco))
   969         (NameSpace.append thyname (NameSpace.base cls ^ "_" ^ NameSpace.base tyco))
   980     fun add_clsmems classtab ((overl, overl_rev), defs, (clstab, clstab_rev, clsmems)) =
   970     fun add_clsmems classtab ((overl, overl_rev), defs, (clstab, clstab_rev, clsmems)) =
   981       ((overl
   971       ((overl
   982         |> Symtab.fold
   972         |> Symtab.fold
   999              ) classtab),
   989              ) classtab),
  1000        defs,
   990        defs,
  1001        (clstab
   991        (clstab
  1002         |> Symtab.fold
   992         |> Symtab.fold
  1003              (fn (cls, (_, clsinsts)) => fold
   993              (fn (cls, (_, clsinsts)) => fold
  1004                 (fn (tyco, thyname) => Insttab.update ((cls, tyco), mk_instname thyname (cls, tyco))) clsinsts)
   994                 (fn (tyco, thyname) => Insttab.update ((cls, tyco), mangle_instname thyname (cls, tyco))) clsinsts)
  1005              classtab,
   995              classtab,
  1006         clstab_rev
   996         clstab_rev
  1007         |> Symtab.fold
   997         |> Symtab.fold
  1008              (fn (cls, (_, clsinsts)) => fold
   998              (fn (cls, (_, clsinsts)) => fold
  1009                 (fn (tyco, thyname) => Symtab.update (mk_instname thyname (cls, tyco), (cls, tyco))) clsinsts)
   999                 (fn (tyco, thyname) => Symtab.update (mangle_instname thyname (cls, tyco), (cls, tyco))) clsinsts)
  1010              classtab,
  1000              classtab,
  1011         clsmems
  1001         clsmems
  1012         |> Symtab.fold
  1002         |> Symtab.fold
  1013              (fn (class, (clsmems, _)) => fold
  1003              (fn (class, (clsmems, _)) => fold
  1014                 (fn clsmem => Symtab.update (clsmem, class)) clsmems)
  1004                 (fn clsmem => Symtab.update (clsmem, class)) clsmems)
  1015              classtab))
  1005              classtab))
  1016   in 
  1006     fun add_def (name, [(ty, (_, (args, rhs)))]) (overl, defs, clstab) =
       
  1007           (overl,
       
  1008            defs |> Symtab.update_new (idf_of_name thy nsp_const name, (args, rhs, ty)),
       
  1009            clstab)
       
  1010       | add_def (name, ds) ((overl, overl_rev), defs, clstab) =
       
  1011           let
       
  1012             val ty_decl = Sign.the_const_constraint thy name;
       
  1013             fun mk_idf ("0", Type ("nat", [])) = "const.Zero"
       
  1014               | mk_idf ("1", Type ("nat", [])) = "."
       
  1015               | mk_idf (nm, ty) =
       
  1016                   if is_number nm
       
  1017                   then nm
       
  1018                   else idf_of_name thy nsp_const nm
       
  1019                      ^ "_" ^ mangle_tyname (ty_decl, ty)
       
  1020             val overl_lookups = map
       
  1021               (fn (ty, (_, (args, rhs))) => (ty, mk_idf (name, ty), args, rhs)) ds;
       
  1022           in
       
  1023             ((overl
       
  1024               |> Symtab.default (name, [])
       
  1025               |> Symtab.map_entry name (append (map (fn (ty, idf, _, _) => (ty, idf)) overl_lookups)),
       
  1026               overl_rev
       
  1027               |> fold Symtab.update_new (map (fn (ty, idf, _, _) => (idf, (name, ty))) overl_lookups)),
       
  1028              defs
       
  1029              |> fold Symtab.update_new (map (fn (ty, idf, args, rhs) => (idf, (args, rhs, ty))) overl_lookups), clstab)
       
  1030           end;  in
  1017     ((Symtab.empty, Symtab.empty), Symtab.empty, (Insttab.empty, Symtab.empty, Symtab.empty))
  1031     ((Symtab.empty, Symtab.empty), Symtab.empty, (Insttab.empty, Symtab.empty, Symtab.empty))
  1018     |> add_clsmems (ClassPackage.get_classtab thy)
  1032     |> add_clsmems (ClassPackage.get_classtab thy)
  1019     |> fold add_def (Codegen.mk_deftab thy |> Symtab.dest)
  1033     |> fold add_def (Codegen.mk_deftab thy |> Symtab.dest)
  1020   end;
  1034   end;
  1021 
  1035 
  1172     |-> (fn _ => pair consts')
  1186     |-> (fn _ => pair consts')
  1173   end;
  1187   end;
  1174 
  1188 
  1175 fun serialize_code serial_name filename consts thy =
  1189 fun serialize_code serial_name filename consts thy =
  1176   let
  1190   let
  1177     fun mk_sfun tab name args f =
  1191     fun mk_sfun tab =
  1178       Symtab.lookup tab name
  1192       let
  1179       |> Option.map (fn ms => Codegen.fillin_mixfix ms args (f : 'a -> Pretty.T))
  1193         fun na name =
       
  1194           Option.map Codegen.num_args_of (Symtab.lookup tab name)
       
  1195         fun stx name =
       
  1196           Codegen.fillin_mixfix ((the o Symtab.lookup tab) name)
       
  1197       in (na, stx) end;
  1180     val serialize_data =
  1198     val serialize_data =
  1181       thy
  1199       thy
  1182       |> CodegenData.get
  1200       |> CodegenData.get
  1183       |> #serialize_data
  1201       |> #serialize_data
  1184       |> (fn data => (the oo Symtab.lookup) data serial_name)
  1202       |> (fn data => (the oo Symtab.lookup) data serial_name)
  1186       ((mk_sfun o #syntax_tyco) serialize_data)
  1204       ((mk_sfun o #syntax_tyco) serialize_data)
  1187       ((mk_sfun o #syntax_const) serialize_data)
  1205       ((mk_sfun o #syntax_const) serialize_data)
  1188       (#primitives serialize_data);
  1206       (#primitives serialize_data);
  1189     val _ = serializer' : string list option -> module -> Pretty.T;
  1207     val _ = serializer' : string list option -> module -> Pretty.T;
  1190     val compile_it = serial_name = "ml" andalso filename = "-";
  1208     val compile_it = serial_name = "ml" andalso filename = "-";
  1191     fun use_code code = 
  1209     fun use_code code =
  1192       if compile_it
  1210       if compile_it
  1193       then use_text Context.ml_output false code
  1211       then use_text Context.ml_output false code
  1194       else File.write (Path.unpack filename) (code ^ "\n");
  1212       else File.write (Path.unpack filename) (code ^ "\n");
  1195   in
  1213   in
  1196     thy
  1214     thy
  1197     |> (if is_some consts then generate_code (the consts) else pair [])
  1215     |> (if is_some consts then generate_code (the consts) else pair [])
  1198     |-> (fn [] => `(serializer' NONE o #modl o CodegenData.get)
  1216     |-> (fn [] => `(serializer' NONE o #modl o CodegenData.get)
  1199           | consts => `(serializer' (SOME consts) o #modl o CodegenData.get))
  1217           | consts => `(serializer' (SOME consts) o #modl o CodegenData.get))
  1200     |-> (fn code => ((use_code o Pretty.output) code; I))
  1218     |-> (fn code => (setmp print_mode [] (use_code o Pretty.output) code; I))
  1201   end;
  1219   end;
  1202 
  1220 
  1203 
  1221 
  1204 (* toplevel interface *)
  1222 (* toplevel interface *)
  1205 
  1223 
  1212 
  1230 
  1213 val (generateK, serializeK, extractingK, aliasK, definedK, dependingK, syntax_tycoK, syntax_constK) =
  1231 val (generateK, serializeK, extractingK, aliasK, definedK, dependingK, syntax_tycoK, syntax_constK) =
  1214   ("code_generate", "code_serialize", "extracting", "defined_by", "depending_on", "code_alias", "code_syntax_tyco", "code_syntax_const");
  1232   ("code_generate", "code_serialize", "extracting", "defined_by", "depending_on", "code_alias", "code_syntax_tyco", "code_syntax_const");
  1215 
  1233 
  1216 val generateP =
  1234 val generateP =
  1217   OuterSyntax.command generateK "generate executable code for constants" K.thy_decl ( 
  1235   OuterSyntax.command generateK "generate executable code for constants" K.thy_decl (
  1218     Scan.repeat1 (P.name -- Scan.option (P.$$$ "::" |-- P.typ))
  1236     Scan.repeat1 (P.name -- Scan.option (P.$$$ "::" |-- P.typ))
  1219     >> (fn consts =>
  1237     >> (fn consts =>
  1220           Toplevel.theory (generate_code consts #> snd))
  1238           Toplevel.theory (generate_code consts #> snd))
  1221   );
  1239   );
  1222 
  1240 
  1223 val serializeP =
  1241 val serializeP =
  1224   OuterSyntax.command serializeK "serialize executable code for constants" K.thy_decl ( 
  1242   OuterSyntax.command serializeK "serialize executable code for constants" K.thy_decl (
  1225     P.name
  1243     P.name
  1226     -- P.name
  1244     -- P.name
  1227     -- Scan.option (
  1245     -- Scan.option (
  1228          P.$$$ extractingK
  1246          P.$$$ extractingK
  1229          |-- Scan.repeat1 (P.name -- Scan.option (P.$$$ "::" |-- P.typ))
  1247          |-- Scan.repeat1 (P.name -- Scan.option (P.$$$ "::" |-- P.typ))
  1231     >> (fn ((serial_name, filename), consts) =>
  1249     >> (fn ((serial_name, filename), consts) =>
  1232           Toplevel.theory (serialize_code serial_name filename consts))
  1250           Toplevel.theory (serialize_code serial_name filename consts))
  1233   );
  1251   );
  1234 
  1252 
  1235 val aliasP =
  1253 val aliasP =
  1236   OuterSyntax.command aliasK "declare an alias for a theory identifier" K.thy_decl ( 
  1254   OuterSyntax.command aliasK "declare an alias for a theory identifier" K.thy_decl (
  1237     P.name
  1255     P.name
  1238     -- P.name
  1256     -- P.name
  1239       >> (fn (src, dst) => Toplevel.theory (add_alias (src, dst)))
  1257       >> (fn (src, dst) => Toplevel.theory (add_alias (src, dst)))
  1240   );
  1258   );
  1241 
  1259 
  1298     add_defgen ("tyco_fallback", defgen_tyco_fallback),
  1316     add_defgen ("tyco_fallback", defgen_tyco_fallback),
  1299     add_defgen ("const_fallback", defgen_const_fallback),
  1317     add_defgen ("const_fallback", defgen_const_fallback),
  1300     add_defgen ("defs", defgen_defs),
  1318     add_defgen ("defs", defgen_defs),
  1301     add_defgen ("clsmem", defgen_clsmem),
  1319     add_defgen ("clsmem", defgen_clsmem),
  1302     add_defgen ("clsinst", defgen_clsinst),
  1320     add_defgen ("clsinst", defgen_clsinst),
  1303     add_alias ("op <>", "neq"),
  1321     add_alias ("op <>", "op_neq"),
  1304     add_alias ("op >=", "ge"),
  1322     add_alias ("op >=", "op_ge"),
  1305     add_alias ("op >", "gt"),
  1323     add_alias ("op >", "op_gt"),
  1306     add_alias ("op <=", "le"),
  1324     add_alias ("op <=", "op_le"),
  1307     add_alias ("op <", "lt"),
  1325     add_alias ("op <", "op_lt"),
  1308     add_alias ("op +", "add"),
  1326     add_alias ("op +", "op_add"),
  1309     add_alias ("op -", "minus"),
  1327     add_alias ("op -", "op_minus"),
  1310     add_alias ("op *", "times"),
  1328     add_alias ("op *", "op_times"),
  1311     add_alias ("op @", "append"),
  1329     add_alias ("op @", "op_append"),
  1312     add_lookup_tyco ("bool", type_bool),
  1330     add_lookup_tyco ("bool", type_bool),
  1313     add_lookup_tyco ("IntDef.int", type_integer),
  1331     add_lookup_tyco ("IntDef.int", type_integer),
  1314     add_lookup_tyco ("List.list", type_list),
  1332     add_lookup_tyco ("List.list", type_list),
  1315     add_lookup_tyco ("*", type_pair),
  1333     add_lookup_tyco ("*", type_pair),
  1316     add_lookup_const (("True", bool), Cons_true),
  1334     add_lookup_const (("True", bool), Cons_true),