src/Pure/Tools/codegen_package.ML
changeset 18231 2eea98bbf650
parent 18217 e0b08c9534ff
child 18247 b17724cae935
equal deleted inserted replaced
18230:4dc1f30af6a1 18231:2eea98bbf650
    35   val add_alias: string * string -> theory -> theory;
    35   val add_alias: string * string -> theory -> theory;
    36   val set_is_datatype: (theory -> string -> bool) -> theory -> theory;
    36   val set_is_datatype: (theory -> string -> bool) -> theory -> theory;
    37 
    37 
    38   val idf_of_name: theory -> string -> string -> string;
    38   val idf_of_name: theory -> string -> string -> string;
    39   val name_of_idf: theory -> string -> string -> string option;
    39   val name_of_idf: theory -> string -> string -> string option;
       
    40   val idf_of_inst: theory -> deftab -> class * string -> string;
       
    41   val inst_of_idf: theory -> deftab -> string -> (class * string) option;
    40   val idf_of_tname: theory -> string -> string;
    42   val idf_of_tname: theory -> string -> string;
    41   val tname_of_idf: theory -> string -> string option;
    43   val tname_of_idf: theory -> string -> string option;
    42   val idf_of_cname: theory -> deftab -> string * typ -> string;
    44   val idf_of_cname: theory -> deftab -> string * typ -> string;
    43   val cname_of_idf: theory -> deftab -> string -> (string * typ) option;
    45   val cname_of_idf: theory -> deftab -> string -> (string * typ) option;
    44 
    46 
    64   val defgen_recfun: (theory -> string * typ -> (term list * term) list * typ)
    66   val defgen_recfun: (theory -> string * typ -> (term list * term) list * typ)
    65     -> defgen;
    67     -> defgen;
    66 
    68 
    67   val print_codegen_modl: theory -> unit;
    69   val print_codegen_modl: theory -> unit;
    68   val mk_deftab: theory -> deftab;
    70   val mk_deftab: theory -> deftab;
    69   structure CodegenData : THEORY_DATA;
    71   structure CodegenData: THEORY_DATA;
       
    72   structure Insttab: TABLE;
    70 end;
    73 end;
    71 
    74 
    72 structure CodegenPackage : CODEGEN_PACKAGE =
    75 structure CodegenPackage : CODEGEN_PACKAGE =
    73 struct
    76 struct
    74 
    77 
    89 type deftab = ((typ * string) list Symtab.table
    92 type deftab = ((typ * string) list Symtab.table
    90     * (string * typ) Symtab.table)
    93     * (string * typ) Symtab.table)
    91   * (term list * term * typ) Symtab.table
    94   * (term list * term * typ) Symtab.table
    92     * (string Insttab.table
    95     * (string Insttab.table
    93       * (string * string) Symtab.table
    96       * (string * string) Symtab.table
    94       * (class * (string * typ))  Symtab.table);
    97       * class Symtab.table);
    95 
    98 
    96 type codegen_class = theory -> deftab -> (class, class) gen_codegen;
    99 type codegen_sort = theory -> deftab -> (sort, sort) gen_codegen;
    97 type codegen_type = theory -> deftab -> (typ, itype) gen_codegen;
   100 type codegen_type = theory -> deftab -> (typ, itype) gen_codegen;
    98 type codegen_expr = theory -> deftab -> (term, iexpr) gen_codegen;
   101 type codegen_expr = theory -> deftab -> (term, iexpr) gen_codegen;
    99 type defgen = theory -> deftab -> gen_defgen;
   102 type defgen = theory -> deftab -> gen_defgen;
   100 
   103 
   101 
   104 
   125 
   128 
   126 
   129 
   127 (* theory data for codegen *)
   130 (* theory data for codegen *)
   128 
   131 
   129 type gens = {
   132 type gens = {
   130   codegens_class: (string * (codegen_class * stamp)) list,
   133   codegens_sort: (string * (codegen_sort * stamp)) list,
   131   codegens_type: (string * (codegen_type * stamp)) list,
   134   codegens_type: (string * (codegen_type * stamp)) list,
   132   codegens_expr: (string * (codegen_expr * stamp)) list,
   135   codegens_expr: (string * (codegen_expr * stamp)) list,
   133   defgens: (string * (defgen * stamp)) list
   136   defgens: (string * (defgen * stamp)) list
   134 };
   137 };
   135 
   138 
   136 val empty_gens = {
   139 val empty_gens = {
   137   codegens_class = Symtab.empty, codegens_type = Symtab.empty,
   140   codegens_sort = Symtab.empty, codegens_type = Symtab.empty,
   138   codegens_expr = Symtab.empty, defgens = Symtab.empty
   141   codegens_expr = Symtab.empty, defgens = Symtab.empty
   139 };
   142 };
   140 
   143 
   141 fun map_gens f { codegens_class, codegens_type, codegens_expr, defgens } =
   144 fun map_gens f { codegens_sort, codegens_type, codegens_expr, defgens } =
   142   let
   145   let
   143     val (codegens_class, codegens_type, codegens_expr, defgens) =
   146     val (codegens_sort, codegens_type, codegens_expr, defgens) =
   144       f (codegens_class, codegens_type, codegens_expr, defgens)
   147       f (codegens_sort, codegens_type, codegens_expr, defgens)
   145   in { codegens_class = codegens_class, codegens_type = codegens_type,
   148   in { codegens_sort = codegens_sort, codegens_type = codegens_type,
   146        codegens_expr = codegens_expr, defgens = defgens } end;
   149        codegens_expr = codegens_expr, defgens = defgens } end;
   147 
   150 
   148 fun merge_gens
   151 fun merge_gens
   149   ({ codegens_class = codegens_class1, codegens_type = codegens_type1,
   152   ({ codegens_sort = codegens_sort1, codegens_type = codegens_type1,
   150      codegens_expr = codegens_expr1, defgens = defgens1 },
   153      codegens_expr = codegens_expr1, defgens = defgens1 },
   151    { codegens_class = codegens_class2, codegens_type = codegens_type2,
   154    { codegens_sort = codegens_sort2, codegens_type = codegens_type2,
   152      codegens_expr = codegens_expr2, defgens = defgens2 }) =
   155      codegens_expr = codegens_expr2, defgens = defgens2 }) =
   153   { codegens_class = AList.merge (op =) (eq_snd (op =)) (codegens_class1, codegens_class2),
   156   { codegens_sort = AList.merge (op =) (eq_snd (op =)) (codegens_sort1, codegens_sort2),
   154     codegens_type = AList.merge (op =) (eq_snd (op =)) (codegens_type1, codegens_type2),
   157     codegens_type = AList.merge (op =) (eq_snd (op =)) (codegens_type1, codegens_type2),
   155     codegens_expr = AList.merge (op =) (eq_snd (op =)) (codegens_expr1, codegens_expr2),
   158     codegens_expr = AList.merge (op =) (eq_snd (op =)) (codegens_expr1, codegens_expr2),
   156     defgens = AList.merge (op =) (eq_snd (op =)) (defgens1, defgens2) };
   159     defgens = AList.merge (op =) (eq_snd (op =)) (defgens1, defgens2) };
   157 
   160 
   158 type lookups = {
   161 type lookups = {
   235     logic_data: logic_data,
   238     logic_data: logic_data,
   236     serialize_data: serialize_data Symtab.table
   239     serialize_data: serialize_data Symtab.table
   237   };
   240   };
   238   val empty = {
   241   val empty = {
   239     modl = empty_module,
   242     modl = empty_module,
   240     gens = { codegens_class = [], codegens_type = [], codegens_expr = [], defgens = [] } : gens,
   243     gens = { codegens_sort = [], codegens_type = [], codegens_expr = [], defgens = [] } : gens,
   241     lookups = { lookups_tyco = Symtab.empty, lookups_const = Symtab.empty } : lookups,
   244     lookups = { lookups_tyco = Symtab.empty, lookups_const = Symtab.empty } : lookups,
   242     logic_data = { is_datatype = NONE, alias = (Symtab.empty, Symtab.empty) } : logic_data,
   245     logic_data = { is_datatype = NONE, alias = (Symtab.empty, Symtab.empty) } : logic_data,
   243     serialize_data =
   246     serialize_data =
   244       Symtab.empty
   247       Symtab.empty
   245       |> Symtab.update ("ml",
   248       |> Symtab.update ("ml",
   246           { serializer = serializer_ml,
   249           { serializer = serializer_ml : CodegenSerializer.serializer,
   247             primitives =
   250             primitives =
   248               CodegenSerializer.empty_prims
   251               CodegenSerializer.empty_prims
   249               |> CodegenSerializer.add_prim ("fst", ("fun fst (x, _) = x;", []))
   252               |> CodegenSerializer.add_prim ("fst", ("fun fst (x, _) = x;", []))
   250               |> CodegenSerializer.add_prim ("snd", ("fun snd (_, y) = y;", []))
   253               |> CodegenSerializer.add_prim ("snd", ("fun snd (_, y) = y;", []))
   251               |> CodegenSerializer.add_prim ("wfrec", ("fun wfrec f x = f (wfrec f) x;", [])),
   254               |> CodegenSerializer.add_prim ("wfrec", ("fun wfrec f x = f (wfrec f) x;", [])),
   252             syntax_tyco = Symtab.empty, syntax_const = Symtab.empty })
   255             syntax_tyco = Symtab.empty, syntax_const = Symtab.empty })
   253       |> Symtab.update ("haskell",
   256       |> Symtab.update ("haskell",
   254           { serializer = serializer_hs, primitives = CodegenSerializer.empty_prims,
   257           { serializer = serializer_hs : CodegenSerializer.serializer, primitives = CodegenSerializer.empty_prims,
   255             syntax_tyco = Symtab.empty, syntax_const = Symtab.empty })
   258             syntax_tyco = Symtab.empty, syntax_const = Symtab.empty })
   256   } : T;
   259   } : T;
   257   val copy = I;
   260   val copy = I;
   258   val extend = I;
   261   val extend = I;
   259   fun merge _ (
   262   fun merge _ (
   280       in CodegenData.put { modl = modl, gens = gens, lookups = lookups,
   283       in CodegenData.put { modl = modl, gens = gens, lookups = lookups,
   281            serialize_data = serialize_data, logic_data = logic_data } thy end;
   284            serialize_data = serialize_data, logic_data = logic_data } thy end;
   282 
   285 
   283 val print_codegen_modl = writeln o Pretty.output o pretty_module o #modl o CodegenData.get;
   286 val print_codegen_modl = writeln o Pretty.output o pretty_module o #modl o CodegenData.get;
   284 
   287 
   285 fun add_codegen_class (name, cg) =
   288 fun add_codegen_sort (name, cg) =
   286   map_codegen_data
   289   map_codegen_data
   287     (fn (modl, gens, lookups, serialize_data, logic_data) =>
   290     (fn (modl, gens, lookups, serialize_data, logic_data) =>
   288        (modl,
   291        (modl,
   289         gens |> map_gens
   292         gens |> map_gens
   290           (fn (codegens_class, codegens_type, codegens_expr, defgens) =>
   293           (fn (codegens_sort, codegens_type, codegens_expr, defgens) =>
   291             (codegens_class
   294             (codegens_sort
   292              |> Output.update_warn (op =) ("overwriting existing class code generator " ^ name) (name, (cg, stamp ())),
   295              |> Output.update_warn (op =) ("overwriting existing class code generator " ^ name) (name, (cg, stamp ())),
   293              codegens_type, codegens_expr, defgens)), lookups, serialize_data, logic_data));
   296              codegens_type, codegens_expr, defgens)), lookups, serialize_data, logic_data));
   294 
   297 
   295 fun add_codegen_type (name, cg) =
   298 fun add_codegen_type (name, cg) =
   296   map_codegen_data
   299   map_codegen_data
   297     (fn (modl, gens, lookups, serialize_data, logic_data) =>
   300     (fn (modl, gens, lookups, serialize_data, logic_data) =>
   298        (modl,
   301        (modl,
   299         gens |> map_gens
   302         gens |> map_gens
   300           (fn (codegens_class, codegens_type, codegens_expr, defgens) =>
   303           (fn (codegens_sort, codegens_type, codegens_expr, defgens) =>
   301             (codegens_class,
   304             (codegens_sort,
   302              codegens_type
   305              codegens_type
   303              |> Output.update_warn (op =) ("overwriting existing type code generator " ^ name) (name, (cg, stamp ())),
   306              |> Output.update_warn (op =) ("overwriting existing type code generator " ^ name) (name, (cg, stamp ())),
   304              codegens_expr, defgens)), lookups, serialize_data, logic_data));
   307              codegens_expr, defgens)), lookups, serialize_data, logic_data));
   305 
   308 
   306 fun add_codegen_expr (name, cg) =
   309 fun add_codegen_expr (name, cg) =
   307   map_codegen_data
   310   map_codegen_data
   308     (fn (modl, gens, lookups, serialize_data, logic_data) =>
   311     (fn (modl, gens, lookups, serialize_data, logic_data) =>
   309        (modl,
   312        (modl,
   310         gens |> map_gens
   313         gens |> map_gens
   311           (fn (codegens_class, codegens_type, codegens_expr, defgens) =>
   314           (fn (codegens_sort, codegens_type, codegens_expr, defgens) =>
   312             (codegens_class, codegens_type,
   315             (codegens_sort, codegens_type,
   313              codegens_expr
   316              codegens_expr
   314              |> Output.update_warn (op =) ("overwriting existing expression code generator " ^ name) (name, (cg, stamp ())),
   317              |> Output.update_warn (op =) ("overwriting existing expression code generator " ^ name) (name, (cg, stamp ())),
   315              defgens)),
   318              defgens)),
   316              lookups, serialize_data, logic_data));
   319              lookups, serialize_data, logic_data));
   317 
   320 
   318 fun add_defgen (name, dg) =
   321 fun add_defgen (name, dg) =
   319   map_codegen_data
   322   map_codegen_data
   320     (fn (modl, gens, lookups, serialize_data, logic_data) =>
   323     (fn (modl, gens, lookups, serialize_data, logic_data) =>
   321        (modl,
   324        (modl,
   322         gens |> map_gens
   325         gens |> map_gens
   323           (fn (codegens_class, codegens_type, codegens_expr, defgens) =>
   326           (fn (codegens_sort, codegens_type, codegens_expr, defgens) =>
   324             (codegens_class, codegens_type, codegens_expr,
   327             (codegens_sort, codegens_type, codegens_expr,
   325              defgens
   328              defgens
   326              |> Output.update_warn (op =) ("overwriting existing definition code generator " ^ name) (name, (dg, stamp ())))),
   329              |> Output.update_warn (op =) ("overwriting existing definition code generator " ^ name) (name, (dg, stamp ())))),
   327              lookups, serialize_data, logic_data));
   330              lookups, serialize_data, logic_data));
   328 
   331 
   329 val get_lookups_tyco = #lookups_tyco o #lookups o CodegenData.get;
   332 val get_lookups_tyco = #lookups_tyco o #lookups o CodegenData.get;
   422     if is_datatype thy ((NameSpace.drop_base o NameSpace.drop_base) idf)
   425     if is_datatype thy ((NameSpace.drop_base o NameSpace.drop_base) idf)
   423     then (NameSpace.drop_base o NameSpace.drop_base) idf |> SOME
   426     then (NameSpace.drop_base o NameSpace.drop_base) idf |> SOME
   424     else name_of_idf thy nsp_type idf
   427     else name_of_idf thy nsp_type idf
   425   else name_of_idf thy nsp_type idf;
   428   else name_of_idf thy nsp_type idf;
   426 
   429 
   427 fun idf_of_cname thy ((overl, _), _, (_, _, clsmems)) (name, ty) =
   430 fun idf_of_cname thy ((overl, _), _, _) (name, ty) =
   428   case Symtab.lookup overl name
   431   case Symtab.lookup overl name
   429    of NONE =>
   432    of NONE => idf_of_name thy nsp_const name
   430         (case Symtab.lookup clsmems name
   433     | SOME tab => (the o AList.lookup (Sign.typ_instance thy) tab) ty
   431          of NONE => idf_of_name thy nsp_const name
       
   432           | SOME (_, (idf, ty')) =>
       
   433               if Type.raw_instance (ty', ty)
       
   434               then idf
       
   435               else idf_of_name thy nsp_const name)
       
   436     | SOME tab => (the o AList.lookup (Sign.typ_instance thy) tab) ty;
       
   437 
   434 
   438 fun cname_of_idf thy ((_, overl_rev), _, _) idf =
   435 fun cname_of_idf thy ((_, overl_rev), _, _) idf =
   439   case Symtab.lookup overl_rev idf
   436   case Symtab.lookup overl_rev idf
   440    of NONE => 
   437    of NONE => 
   441         (case name_of_idf thy nsp_const idf
   438         (case name_of_idf thy nsp_const idf
       
   439          of NONE => (case name_of_idf thy nsp_mem idf
   442          of NONE => NONE
   440          of NONE => NONE
       
   441           | SOME n => SOME (n, Sign.the_const_constraint thy n))
   443           | SOME n => SOME (n, Sign.the_const_constraint thy n))
   442           | SOME n => SOME (n, Sign.the_const_constraint thy n))
   444     | s => s;
   443     | s => s;
   445 
   444 
   446 
   445 
   447 (* auxiliary *)
   446 (* auxiliary *)
   455       (if i=0 then v else v ^ string_of_int i) |> unprefix "'"
   454       (if i=0 then v else v ^ string_of_int i) |> unprefix "'"
   456 
   455 
   457 
   456 
   458 (* code generator instantiation, part 2 *)
   457 (* code generator instantiation, part 2 *)
   459 
   458 
   460 fun invoke_cg_class thy defs class trns =
   459 fun invoke_cg_sort thy defs sort trns =
   461   gen_invoke
   460   gen_invoke
   462     ((map (apsnd (fn (cg, _) => cg thy defs)) o #codegens_class o #gens o CodegenData.get) thy)
   461     ((map (apsnd (fn (cg, _) => cg thy defs)) o #codegens_sort o #gens o CodegenData.get) thy)
   463     class class trns;
   462     ("generating sort " ^ (quote o Sign.string_of_sort thy) sort) sort trns;
   464 
   463 
   465 fun invoke_cg_type thy defs ty trns =
   464 fun invoke_cg_type thy defs ty trns =
   466   gen_invoke
   465   gen_invoke
   467     ((map (apsnd (fn (cg, _) => cg thy defs)) o #codegens_type o #gens o CodegenData.get) thy)
   466     ((map (apsnd (fn (cg, _) => cg thy defs)) o #codegens_type o #gens o CodegenData.get) thy)
   468     (Sign.string_of_typ thy ty) ty trns;
   467     ("generating type " ^ (quote o Sign.string_of_typ thy) ty) ty trns;
   469 
   468 
   470 fun invoke_cg_expr thy defs t trns =
   469 fun invoke_cg_expr thy defs t trns =
   471   gen_invoke
   470   gen_invoke
   472     ((map (apsnd (fn (cg, _) => cg thy defs)) o #codegens_expr o #gens o CodegenData.get) thy)
   471     ((map (apsnd (fn (cg, _) => cg thy defs)) o #codegens_expr o #gens o CodegenData.get) thy)
   473     (Sign.string_of_term thy t) t trns;
   472     ("generating expression " ^ (quote o Sign.string_of_term thy) t) t trns;
   474 
   473 
   475 fun get_defgens thy defs =
   474 fun get_defgens thy defs =
   476   (map (apsnd (fn (dg, _) => dg thy defs)) o #defgens o #gens o CodegenData.get) thy;
   475   (map (apsnd (fn (dg, _) => dg thy defs)) o #defgens o #gens o CodegenData.get) thy;
   477 
   476 
   478 fun ensure_def_class thy defs cls_or_inst trns =
   477 fun ensure_def_class thy defs cls_or_inst trns =
   479   if cls_or_inst = "ClassSimple.Eq_proto" then error ("Krach!")
   478   trns
   480   else trns
   479   |> debug 4 (fn _ => "generating class or instance " ^ quote cls_or_inst)
   481   |> gen_ensure_def (get_defgens thy defs) ("class/instance " ^ quote cls_or_inst) cls_or_inst
   480   |> gen_ensure_def (get_defgens thy defs) ("generating class/instance " ^ quote cls_or_inst) cls_or_inst
   482   |> pair cls_or_inst;
   481   |> pair cls_or_inst;
   483 
   482 
   484 fun ensure_def_tyco thy defs tyco trns =
   483 fun ensure_def_tyco thy defs tyco trns =
   485   if NameSpace.is_qualified tyco
   484   if NameSpace.is_qualified tyco
   486   then case Option.mapPartial (Symtab.lookup (get_lookups_tyco thy)) (tname_of_idf thy tyco)
   485   then case Option.mapPartial (Symtab.lookup (get_lookups_tyco thy)) (tname_of_idf thy tyco)
   487    of NONE =>
   486    of NONE =>
   488         trns
   487         trns
   489         |> gen_ensure_def (get_defgens thy defs) ("type constructor " ^ quote tyco) tyco
   488         |> debug 4 (fn _ => "generating type constructor " ^ quote tyco)
       
   489         |> gen_ensure_def (get_defgens thy defs) ("generating type constructor " ^ quote tyco) tyco
   490         |> pair tyco
   490         |> pair tyco
   491     | SOME tyco =>
   491     | SOME tyco =>
   492         trns
   492         trns
   493         |> pair tyco
   493         |> pair tyco
   494   else (tyco, trns);
   494   else (tyco, trns);
   496 fun ensure_def_const thy defs f trns =
   496 fun ensure_def_const thy defs f trns =
   497   if NameSpace.is_qualified f
   497   if NameSpace.is_qualified f
   498   then case Option.mapPartial (find_lookup_expr thy) (cname_of_idf thy defs f)
   498   then case Option.mapPartial (find_lookup_expr thy) (cname_of_idf thy defs f)
   499    of NONE =>
   499    of NONE =>
   500         trns
   500         trns
   501         |> invoke_cg_type thy defs (Sign.the_const_constraint thy (cname_of_idf thy defs f |> the |> fst))
   501         |> debug 4 (fn _ => "generating constant " ^ quote f)
   502         ||> gen_ensure_def (get_defgens thy defs) ("constant " ^ quote f) f
   502         |> invoke_cg_type thy defs (cname_of_idf thy defs f |> the |> snd)
       
   503         ||> gen_ensure_def (get_defgens thy defs) ("generating constant " ^ quote f) f
   503         |-> (fn ty' => pair f)
   504         |-> (fn ty' => pair f)
   504     | SOME (IConst (f, ty)) =>
   505     | SOME (IConst (f, ty)) =>
   505         trns
   506         trns
   506         |> pair f
   507         |> pair f
   507   else (f, trns);
   508   else (f, trns);
   509 fun mk_fun thy defs eqs ty trns = 
   510 fun mk_fun thy defs eqs ty trns = 
   510   let
   511   let
   511     val sortctxt = ClassPackage.extract_sortctxt thy ty;
   512     val sortctxt = ClassPackage.extract_sortctxt thy ty;
   512     fun mk_sortvar (v, sort) trns =
   513     fun mk_sortvar (v, sort) trns =
   513       trns
   514       trns
   514       |> fold_map (invoke_cg_class thy defs) sort
   515       |> invoke_cg_sort thy defs sort
   515       |-> (fn sort => pair (unprefix "'" v, sort))
   516       |-> (fn sort => pair (unprefix "'" v, sort))
   516     fun mk_eq (args, rhs) trns =
   517     fun mk_eq (args, rhs) trns =
   517       trns
   518       trns
   518       |> fold_map (invoke_cg_expr thy defs) args
   519       |> fold_map (invoke_cg_expr thy defs) args
   519       ||>> invoke_cg_expr thy defs rhs
   520       ||>> invoke_cg_expr thy defs rhs
   526     |-> (fn ((eqs, ty), sortctxt) => pair (Fun (eqs, (sortctxt, ty))))
   527     |-> (fn ((eqs, ty), sortctxt) => pair (Fun (eqs, (sortctxt, ty))))
   527   end;
   528   end;
   528 
   529 
   529 fun mk_app thy defs f ty_use args trns =
   530 fun mk_app thy defs f ty_use args trns =
   530   let
   531   let
       
   532     val _ = debug 5 (fn _ => "making application of " ^ quote f) ();
   531     val ty_def = Sign.the_const_constraint thy f;
   533     val ty_def = Sign.the_const_constraint thy f;
       
   534     val _ = debug 10 (fn _ => "making application (2)") ();
   532     fun mk_lookup (ClassPackage.Instance (i, ls)) trns =
   535     fun mk_lookup (ClassPackage.Instance (i, ls)) trns =
   533           trns
   536           trns
   534           |> invoke_cg_class thy defs ((idf_of_name thy nsp_class o fst) i)
   537           |> ensure_def_class thy defs ((idf_of_name thy nsp_class o fst) i)
   535           ||>> ensure_def_class thy defs (idf_of_inst thy defs i)
   538           ||>> ensure_def_class thy defs (idf_of_inst thy defs i)
   536           ||>> (fold_map o fold_map) mk_lookup ls
   539           ||>> (fold_map o fold_map) mk_lookup ls
   537           |-> (fn ((cls, i), ls) => pair (ClassPackage.Instance ((cls, i), ls)))
   540           |-> (fn ((cls, i), ls) => pair (ClassPackage.Instance ((cls, i), ls)))
   538       | mk_lookup (ClassPackage.Lookup (clss, (v, i))) trns =
   541       | mk_lookup (ClassPackage.Lookup (clss, (v, i))) trns =
   539           trns
   542           trns
   540           |> fold_map (ensure_def_class thy defs) (map (idf_of_name thy nsp_class) clss)
   543           |> fold_map (ensure_def_class thy defs) (map (idf_of_name thy nsp_class) clss)
   541           |-> (fn clss => pair (ClassPackage.Lookup (clss, (name_of_tvar (TFree (v, [])), i))));
   544           |-> (fn clss => pair (ClassPackage.Lookup (clss, (name_of_tvar (TFree (v, [])), i))));
       
   545     val _ = debug 10 (fn _ => "making application (3)") ();
   542     fun mk_itapp e [] = e
   546     fun mk_itapp e [] = e
   543       | mk_itapp e lookup = IInst (e, lookup);
   547       | mk_itapp e lookup = IInst (e, lookup);
   544   in 
   548   in 
   545     trns
   549     trns
       
   550     |> debug 10 (fn _ => "making application (4): " ^ f ^ "::" ^ Sign.string_of_typ thy ty_use)
   546     |> ensure_def_const thy defs (idf_of_cname thy defs (f, ty_use))
   551     |> ensure_def_const thy defs (idf_of_cname thy defs (f, ty_use))
       
   552     |> debug 10 (fn _ => "making application (5)")
   547     ||>> fold_map (invoke_cg_expr thy defs) args
   553     ||>> fold_map (invoke_cg_expr thy defs) args
       
   554     |> debug 10 (fn _ => "making application (6)")
   548     ||>> (fold_map o fold_map) mk_lookup (ClassPackage.extract_sortlookup thy (ty_def, ty_use))
   555     ||>> (fold_map o fold_map) mk_lookup (ClassPackage.extract_sortlookup thy (ty_def, ty_use))
       
   556     |> debug 10 (fn _ => "making application (7)")
   549     ||>> invoke_cg_type thy defs ty_use
   557     ||>> invoke_cg_type thy defs ty_use
       
   558     |> debug 10 (fn _ => "making application (8)")
   550     |-> (fn (((f, args), lookup), ty_use) =>
   559     |-> (fn (((f, args), lookup), ty_use) =>
   551            pair (mk_apps (mk_itapp (IConst (f, ty_use)) lookup, args)))
   560            pair (mk_apps (mk_itapp (IConst (f, ty_use)) lookup, args)))
   552   end;
   561   end;
   553 
   562 
   554 
   563 
   561   infix 4 `$$;
   570   infix 4 `$$;
   562 in
   571 in
   563 
   572 
   564 (* code generators *)
   573 (* code generators *)
   565 
   574 
   566 fun codegen_class_default thy defs cls trns =
   575 fun codegen_sort_default thy defs sort trns =
   567   trns
   576   trns
   568   |> ensure_def_class thy defs cls
   577   |> fold_map (ensure_def_class thy defs)
   569   |-> (fn cls => succeed cls)
   578        (sort |> filter (ClassPackage.is_class thy) |> map (idf_of_name thy nsp_class))
       
   579   |-> (fn sort => succeed sort)
   570 
   580 
   571 fun codegen_type_default thy defs (v as TVar (_, sort)) trns =
   581 fun codegen_type_default thy defs (v as TVar (_, sort)) trns =
   572       trns
   582       trns
   573       |> fold_map (invoke_cg_class thy defs) (sort |> filter (ClassPackage.is_class thy) |> map (idf_of_name thy nsp_class))
   583       |> invoke_cg_sort thy defs sort
   574       |-> (fn sort => succeed (IVarT (name_of_tvar v, sort)))
   584       |-> (fn sort => succeed (IVarT (name_of_tvar v, sort)))
   575   | codegen_type_default thy defs (v as TFree (_, sort)) trns =
   585   | codegen_type_default thy defs (v as TFree (_, sort)) trns =
   576       trns
   586       trns
   577       |> fold_map (invoke_cg_class thy defs) (sort |> filter (ClassPackage.is_class thy) |> map (idf_of_name thy nsp_class))
   587       |> invoke_cg_sort thy defs sort
   578       |-> (fn sort => succeed (IVarT (name_of_tvar v, sort)))
   588       |-> (fn sort => succeed (IVarT (name_of_tvar v, sort)))
   579   | codegen_type_default thy defs (Type ("fun", [t1, t2])) trns =
   589   | codegen_type_default thy defs (Type ("fun", [t1, t2])) trns =
   580       trns
   590       trns
   581       |> invoke_cg_type thy defs t1
   591       |> invoke_cg_type thy defs t1
   582       ||>> invoke_cg_type thy defs t2
   592       ||>> invoke_cg_type thy defs t2
   649   in cg_neg u end;
   659   in cg_neg u end;
   650 
   660 
   651 
   661 
   652 (* definition generators *)
   662 (* definition generators *)
   653 
   663 
   654 fun defgen_fallback_tyco thy defs tyco trns =
   664 fun defgen_tyco_fallback thy defs tyco trns =
   655   if Symtab.fold (fn (_, { syntax_tyco, ... }) => fn b => b orelse Symtab.defined syntax_tyco tyco)
   665   if Symtab.fold (fn (_, { syntax_tyco, ... }) => fn b => b orelse Symtab.defined syntax_tyco tyco)
   656     ((#serialize_data o CodegenData.get) thy) false 
   666     ((#serialize_data o CodegenData.get) thy) false 
   657   then
   667   then
   658     trns
   668     trns
       
   669     |> debug 5 (fn _ => "trying defgen tyco fallback for " ^ quote tyco)
   659     |> succeed (Nop, [])
   670     |> succeed (Nop, [])
   660   else
   671   else
   661     trns
   672     trns
   662     |> fail ("no code generation fallback for " ^ quote tyco)
   673     |> fail ("no code generation fallback for " ^ quote tyco)
   663 
   674 
   664 fun defgen_fallback_const thy defs f trns =
   675 fun defgen_const_fallback thy defs f trns =
   665   if Symtab.fold (fn (_, { syntax_const, ... }) => fn b => b orelse Symtab.defined syntax_const f)
   676   if Symtab.fold (fn (_, { syntax_const, ... }) => fn b => b orelse Symtab.defined syntax_const f)
   666     ((#serialize_data o CodegenData.get) thy) false 
   677     ((#serialize_data o CodegenData.get) thy) false 
   667   then
   678   then
   668     trns
   679     trns
       
   680     |> debug 5 (fn _ => "trying defgen const fallback for " ^ quote f)
   669     |> succeed (Nop, [])
   681     |> succeed (Nop, [])
   670   else
   682   else
   671     trns
   683     trns
   672     |> fail ("no code generation fallback for " ^ quote f)
   684     |> fail ("no code generation fallback for " ^ quote f)
   673 
   685 
   674 fun defgen_defs thy (defs as (_, defs', _)) f trns =
   686 fun defgen_defs thy (defs as (_, defs', _)) f trns =
   675   case Symtab.lookup defs' f
   687   case Symtab.lookup defs' f
   676    of SOME (args, rhs, ty) =>
   688    of SOME (args, rhs, ty) =>
   677         trns
   689         trns
       
   690         |> debug 5 (fn _ => "trying defgen def for " ^ quote f)
   678         |> mk_fun thy defs [(args, rhs)] ty
   691         |> mk_fun thy defs [(args, rhs)] ty
   679         |-> (fn def => succeed (def, []))
   692         |-> (fn def => succeed (def, []))
   680       | _ => trns |> fail ("no definition found for " ^ quote f);
   693       | _ => trns |> fail ("no definition found for " ^ quote f);
   681 
   694 
   682 fun defgen_clsdecl thy defs cls trns =
   695 fun defgen_clsdecl thy defs cls trns =
   683   case name_of_idf thy nsp_class cls
   696   case name_of_idf thy nsp_class cls
   684    of SOME cls =>
   697    of SOME cls =>
   685         trns
   698         trns
   686         |> debug 5 (fn _ => "generating class decl " ^ quote cls)
   699         |> debug 5 (fn _ => "trying defgen class declaration for " ^ quote cls)
   687         |> fold_map (ensure_def_class thy defs)
   700         |> fold_map (ensure_def_class thy defs)
   688              (map (idf_of_name thy nsp_class) (ClassPackage.get_superclasses thy cls))
   701              (map (idf_of_name thy nsp_class) (ClassPackage.get_superclasses thy cls))
   689         |-> (fn supcls => succeed (Class (supcls, [], []),
   702         |-> (fn supcls => succeed (Class (supcls, [], []),
   690              map (idf_of_name thy nsp_mem) (ClassPackage.the_consts thy cls)
   703              map (idf_of_name thy nsp_mem) (ClassPackage.the_consts thy cls)
   691              @ map (curry (idf_of_inst thy defs) cls) ((map snd o ClassPackage.the_tycos thy) cls)))
   704              @ map (curry (idf_of_inst thy defs) cls) ((map fst o ClassPackage.the_tycos thy) cls)))
   692     | _ =>
   705     | _ =>
   693         trns
   706         trns
   694         |> fail ("no class definition found for " ^ quote cls);
   707         |> fail ("no class definition found for " ^ quote cls);
   695 
   708 
   696 fun defgen_clsmem thy (defs as (_, _, _)) f trns =
   709 fun defgen_clsmem thy (defs as (_, _, _)) f trns =
   699         let
   712         let
   700           val cls = idf_of_name thy nsp_class ((the o ClassPackage.lookup_const_class thy) clsmem);
   713           val cls = idf_of_name thy nsp_class ((the o ClassPackage.lookup_const_class thy) clsmem);
   701           val (tvar, ty) = ClassPackage.get_const_sign thy clsmem;
   714           val (tvar, ty) = ClassPackage.get_const_sign thy clsmem;
   702         in
   715         in
   703           trns
   716           trns
       
   717           |> debug 5 (fn _ => "trying defgen class member for " ^ quote f)
   704           |> invoke_cg_type thy defs ty
   718           |> invoke_cg_type thy defs ty
   705           |-> (fn ty => succeed (Classmember (cls, name_of_tvar (TFree (tvar, [])), ty), []))
   719           |-> (fn ty => succeed (Classmember (cls, name_of_tvar (TFree (tvar, [])), ty), []))
   706         end
   720         end
   707     | _ =>
   721     | _ =>
   708         trns |> fail ("no class member found for " ^ quote f)
   722         trns |> fail ("no class member found for " ^ quote f)
   717             (ClassPackage.the_consts thy cls);
   731             (ClassPackage.the_consts thy cls);
   718           val instmem_idfs = map (idf_of_cname thy defs)
   732           val instmem_idfs = map (idf_of_cname thy defs)
   719             (ClassPackage.get_inst_consts_sign thy (tyco, cls));
   733             (ClassPackage.get_inst_consts_sign thy (tyco, cls));
   720         in
   734         in
   721           trns
   735           trns
       
   736           |> debug 5 (fn _ => "trying defgen class instance for (" ^ quote cls ^ ", " ^ quote tyco ^ ")")
   722           |> ensure_def_class thy defs (idf_of_name thy nsp_class cls)
   737           |> ensure_def_class thy defs (idf_of_name thy nsp_class cls)
   723           ||>> ensure_def_tyco thy defs (idf_of_tname thy tyco)
   738           ||>> ensure_def_tyco thy defs (idf_of_tname thy tyco)
   724           ||>> (fold_map o fold_map) (ensure_def_class thy defs) arity
   739           ||>> (fold_map o fold_map) (ensure_def_class thy defs) arity
   725           ||>> fold_map (ensure_def_const thy defs) clsmems
   740           ||>> fold_map (ensure_def_const thy defs) clsmems
   726           ||>> fold_map (ensure_def_const thy defs) instmem_idfs
   741           ||>> fold_map (ensure_def_const thy defs) instmem_idfs
   787           handle TERM _
   802           handle TERM _
   788           => fail ("not a number: " ^ Sign.string_of_term thy bin))
   803           => fail ("not a number: " ^ Sign.string_of_term thy bin))
   789   | codegen_number_of dest_binum mk_int_to_nat thy defs (Const ("Numeral.number_of",
   804   | codegen_number_of dest_binum mk_int_to_nat thy defs (Const ("Numeral.number_of",
   790       Type ("fun", [_, Type ("nat", [])])) $ bin) trns =
   805       Type ("fun", [_, Type ("nat", [])])) $ bin) trns =
   791       trns
   806       trns
   792       |> debug 8 (fn _ => "generating nat for " ^ Sign.string_of_term thy bin)
       
   793       |> invoke_cg_expr thy defs (mk_int_to_nat bin)
   807       |> invoke_cg_expr thy defs (mk_int_to_nat bin)
   794       |-> (fn expr => succeed expr)
   808       |-> (fn expr => succeed expr)
   795   | codegen_number_of dest_binum mk_int_to_nat thy defs t trns =
   809   | codegen_number_of dest_binum mk_int_to_nat thy defs t trns =
   796       trns
   810       trns
   797       |> fail ("not a number: " ^ Sign.string_of_term thy t);
   811       |> fail ("not a number: " ^ Sign.string_of_term thy t);
   800   case tname_of_idf thy tyco
   814   case tname_of_idf thy tyco
   801    of SOME dtname =>
   815    of SOME dtname =>
   802         (case get_datatype thy tyco
   816         (case get_datatype thy tyco
   803          of SOME (vs, cnames) =>
   817          of SOME (vs, cnames) =>
   804               trns
   818               trns
       
   819               |> debug 5 (fn _ => "trying defgen datatype for " ^ quote dtname)
   805               |> succeed (Datatype (map (rpair [] o unprefix "'") vs, [], []),
   820               |> succeed (Datatype (map (rpair [] o unprefix "'") vs, [], []),
   806                    cnames
   821                    cnames
   807                    |> map (idf_of_name thy nsp_const)
   822                    |> map (idf_of_name thy nsp_const)
   808                    |> map (fn "0" => "const.Zero" | c => c))
   823                    |> map (fn "0" => "const.Zero" | c => c))
   809               (*! VARIABLEN, EQTYPE !*)
   824               (*! VARIABLEN, EQTYPE !*)
   828           (case the_type c
   843           (case the_type c
   829             of SOME dtname =>
   844             of SOME dtname =>
   830                  (case get_datacons thy (c, dtname)
   845                  (case get_datacons thy (c, dtname)
   831                    of SOME tyargs =>
   846                    of SOME tyargs =>
   832                        trns
   847                        trns
       
   848                        |> debug 5 (fn _ => "trying defgen datatype constructor for " ^ quote c)
   833                        |> ensure_def_tyco thy defs (idf_of_tname thy dtname)
   849                        |> ensure_def_tyco thy defs (idf_of_tname thy dtname)
   834                        ||>> fold_map (invoke_cg_type thy defs) tyargs
   850                        ||>> fold_map (invoke_cg_type thy defs) tyargs
   835                        |-> (fn (dtname, tys) => succeed (Datatypecons (dtname, tys), []))
   851                        |-> (fn (dtname, tys) => succeed (Datatypecons (dtname, tys), []))
   836                     | NONE =>
   852                     | NONE =>
   837                        trns
   853                        trns
   851           val (eqs, ty) = get_equations thy (f, ty);
   867           val (eqs, ty) = get_equations thy (f, ty);
   852         in
   868         in
   853           case eqs
   869           case eqs
   854            of (_::_) =>
   870            of (_::_) =>
   855                 trns
   871                 trns
       
   872                 |> debug 5 (fn _ => "trying defgen recfun for " ^ quote f)
   856                 |> mk_fun thy defs eqs ty
   873                 |> mk_fun thy defs eqs ty
   857                 |-> (fn def => succeed (def, []))
   874                 |-> (fn def => succeed (def, []))
   858             | _ =>
   875             | _ =>
   859                 trns
   876                 trns
   860                 |> fail ("no recursive definition found for " ^ quote f)
   877                 |> fail ("no recursive definition found for " ^ quote f)
   899                     (((perhaps o Symtab.lookup) ((fst o #alias o #logic_data o CodegenData.get) thy) nm)
   916                     (((perhaps o Symtab.lookup) ((fst o #alias o #logic_data o CodegenData.get) thy) nm)
   900                      ^ "_" ^ mangle_tyname (ty_decl, ty))
   917                      ^ "_" ^ mangle_tyname (ty_decl, ty))
   901             val overl_lookups = map
   918             val overl_lookups = map
   902               (fn (ty, (_, (args, rhs))) => (ty, mk_idf (name, ty), args, rhs)) ds;
   919               (fn (ty, (_, (args, rhs))) => (ty, mk_idf (name, ty), args, rhs)) ds;
   903           in
   920           in
   904             (*!!!*)
       
   905             ((overl |> Symtab.update_new (name, map (fn (ty, idf, _, _) => (ty, idf)) overl_lookups),
   921             ((overl |> Symtab.update_new (name, map (fn (ty, idf, _, _) => (ty, idf)) overl_lookups),
   906               overl_rev |> fold Symtab.update_new (map (fn (ty, idf, _, _) => (idf, (name, ty))) overl_lookups)),
   922               overl_rev |> fold Symtab.update_new (map (fn (ty, idf, _, _) => (idf, (name, ty))) overl_lookups)),
   907              defs |> fold Symtab.update_new (map (fn (ty, idf, args, rhs) => (idf, (args, rhs, ty))) overl_lookups),
   923              defs |> fold Symtab.update_new (map (fn (ty, idf, args, rhs) => (idf, (args, rhs, ty))) overl_lookups),
   908              clstab)
   924              clstab)
   909           end;
   925           end;
   910     fun mk_instname thyname (cls, tyco) =
   926     fun mk_instname thyname (cls, tyco) =
   911       idf_of_name thy nsp_inst
   927       idf_of_name thy nsp_inst
   912         (NameSpace.append thyname (NameSpace.base cls ^ "_" ^ NameSpace.base tyco))
   928         (NameSpace.append thyname (NameSpace.base cls ^ "_" ^ NameSpace.base tyco))
   913     fun add_clsmems classtab (overl, defs, (clstab, clstab_rev, clsmems)) =
   929     fun add_clsmems classtab ((overl, overl_rev), defs, (clstab, clstab_rev, clsmems)) =
   914       (overl, defs,
   930       ((overl
       
   931         |> Symtab.fold
       
   932              (fn (class, (clsmems, _)) =>
       
   933                fold
       
   934                  (fn clsmem =>
       
   935                    Symtab.default (clsmem, [])
       
   936                    #> Symtab.map_entry clsmem
       
   937                         (cons (Sign.the_const_type thy clsmem, idf_of_name thy nsp_mem clsmem))
       
   938                  ) clsmems
       
   939              ) classtab,
       
   940         overl_rev
       
   941         |> Symtab.fold
       
   942              (fn (class, (clsmems, _)) =>
       
   943                fold
       
   944                  (fn clsmem =>
       
   945                    Symtab.update_new
       
   946                      (idf_of_name thy nsp_mem clsmem, (clsmem, Sign.the_const_type thy clsmem))
       
   947                  ) clsmems
       
   948              ) classtab),
       
   949        defs,
   915        (clstab
   950        (clstab
   916         |> Symtab.fold
   951         |> Symtab.fold
   917              (fn (cls, (_, clsinsts)) => fold
   952              (fn (cls, (_, clsinsts)) => fold
   918                 (fn (tyco, thyname) => Insttab.update ((cls, tyco), mk_instname thyname (cls, tyco))) clsinsts)
   953                 (fn (tyco, thyname) => Insttab.update ((cls, tyco), mk_instname thyname (cls, tyco))) clsinsts)
   919              classtab,
   954              classtab,
   923                 (fn (tyco, thyname) => Symtab.update (mk_instname thyname (cls, tyco), (cls, tyco))) clsinsts)
   958                 (fn (tyco, thyname) => Symtab.update (mk_instname thyname (cls, tyco), (cls, tyco))) clsinsts)
   924              classtab,
   959              classtab,
   925         clsmems
   960         clsmems
   926         |> Symtab.fold
   961         |> Symtab.fold
   927              (fn (class, (clsmems, _)) => fold
   962              (fn (class, (clsmems, _)) => fold
   928                 (fn clsmem => Symtab.update (idf_of_name thy nsp_mem clsmem, (class, (clsmem, Sign.the_const_constraint thy clsmem)))) clsmems)
   963                 (fn clsmem => Symtab.update (clsmem, class)) clsmems)
   929              classtab))
   964              classtab))
   930   in 
   965   in 
   931     ((Symtab.empty, Symtab.empty), Symtab.empty, (Insttab.empty, Symtab.empty, Symtab.empty))
   966     ((Symtab.empty, Symtab.empty), Symtab.empty, (Insttab.empty, Symtab.empty, Symtab.empty))
   932     |> fold add_def (Codegen.mk_deftab thy |> Symtab.dest)
   967     |> fold add_def (Codegen.mk_deftab thy |> Symtab.dest)
   933     |> add_clsmems (ClassPackage.get_classtab thy)
   968     |> add_clsmems (ClassPackage.get_classtab thy)
   934   end;
   969   end;
   935 
   970 
   936 fun expand_module gen thy =
   971 fun expand_module defs gen thy =
   937   let
   972   let
   938     val defs = mk_deftab thy;
       
   939     fun put_module modl =
   973     fun put_module modl =
   940       map_codegen_data (fn (_, gens, lookups, serialize_data, logic_data) =>
   974       map_codegen_data (fn (_, gens, lookups, serialize_data, logic_data) =>
   941         (modl, gens, lookups, serialize_data, logic_data));
   975         (modl, gens, lookups, serialize_data, logic_data));
   942     val _ = put_module : module -> theory -> theory;
   976     val _ = put_module : module -> theory -> theory;
   943   in
   977   in
   947   end;
   981   end;
   948 
   982 
   949 
   983 
   950 (* syntax *)
   984 (* syntax *)
   951 
   985 
   952 fun gen_add_syntax_tyco prep_tyco prep_mfx prep_primname serializer ((raw_tyco, raw_mfx), primdef) thy =
   986 fun gen_add_syntax_tyco prep_tyco prep_mfx prep_primname serial_name ((raw_tyco, raw_mfx), primdef) thy =
   953   let
   987   let
   954     val tyco = prep_tyco thy raw_tyco;
   988     val tyco = prep_tyco thy raw_tyco;
   955     val _ = if member (op =) prims tyco
   989     val _ = if member (op =) prims tyco
   956       then error ("attempted to re-define primitive " ^ quote tyco)
   990       then error ("attempted to re-define primitive " ^ quote tyco)
   957       else ()
   991       else ()
   962     thy
   996     thy
   963     |> prep_mfx raw_mfx
   997     |> prep_mfx raw_mfx
   964     |-> (fn mfx => map_codegen_data
   998     |-> (fn mfx => map_codegen_data
   965       (fn (modl, gens, lookups, serialize_data, logic_data) =>
   999       (fn (modl, gens, lookups, serialize_data, logic_data) =>
   966          (modl, gens, lookups,
  1000          (modl, gens, lookups,
   967           serialize_data |> Symtab.map_entry serializer
  1001           serialize_data |> Symtab.map_entry serial_name
   968             (map_serialize_data
  1002             (map_serialize_data
   969               (fn (primitives, syntax_tyco, syntax_const) =>
  1003               (fn (primitives, syntax_tyco, syntax_const) =>
   970                (primitives |> add_primdef primdef,
  1004                (primitives |> add_primdef primdef,
   971                 syntax_tyco |> Symtab.update_new (tyco, mfx),
  1005                 syntax_tyco |> Symtab.update_new (tyco, mfx),
   972                 syntax_const))),
  1006                 syntax_const))),
   991           (typ_of o read_ctyp thy) mfx;
  1025           (typ_of o read_ctyp thy) mfx;
   992         fun generate thy defs = fold_map (invoke_cg_type thy defs)
  1026         fun generate thy defs = fold_map (invoke_cg_type thy defs)
   993           (Codegen.quotes_of proto_mfx);
  1027           (Codegen.quotes_of proto_mfx);
   994       in
  1028       in
   995         thy
  1029         thy
   996         |> expand_module generate
  1030         |> expand_module (mk_deftab thy) generate
   997         |-> (fn tys => pair (Codegen.replace_quotes tys proto_mfx))
  1031         |-> (fn tys => pair (Codegen.replace_quotes tys proto_mfx))
   998       end;
  1032       end;
   999   in
  1033   in
  1000     gen_add_syntax_tyco (fn thy => idf_of_tname thy o Sign.intern_type thy)
  1034     gen_add_syntax_tyco (fn thy => idf_of_tname thy o Sign.intern_type thy)
  1001       prep_mfx mk_name
  1035       prep_mfx mk_name
  1002   end;
  1036   end;
  1003 
  1037 
  1004 fun gen_add_syntax_const prep_const prep_mfx prep_primname serializer ((raw_f, raw_mfx), primdef) thy =
  1038 fun gen_add_syntax_const prep_const prep_mfx prep_primname serial_name ((raw_f, raw_mfx), primdef) thy =
  1005   let
  1039   let
  1006     val f = prep_const thy raw_f;
  1040     val f = prep_const thy raw_f;
  1007     val _ = if member (op =) prims f
  1041     val _ = if member (op =) prims f
  1008       then error ("attempted to re-define primitive " ^ quote f)
  1042       then error ("attempted to re-define primitive " ^ quote f)
  1009       else ()
  1043       else ()
  1014     thy
  1048     thy
  1015     |> prep_mfx raw_mfx
  1049     |> prep_mfx raw_mfx
  1016     |-> (fn mfx => map_codegen_data
  1050     |-> (fn mfx => map_codegen_data
  1017       (fn (modl, gens, lookups, serialize_data, logic_data) =>
  1051       (fn (modl, gens, lookups, serialize_data, logic_data) =>
  1018          (modl, gens, lookups,
  1052          (modl, gens, lookups,
  1019           serialize_data |> Symtab.map_entry serializer
  1053           serialize_data |> Symtab.map_entry serial_name
  1020             (map_serialize_data
  1054             (map_serialize_data
  1021               (fn (primitives, syntax_tyco, syntax_const) =>
  1055               (fn (primitives, syntax_tyco, syntax_const) =>
  1022                (primitives |> add_primdef primdef,
  1056                (primitives |> add_primdef primdef,
  1023                 syntax_tyco,
  1057                 syntax_tyco,
  1024                 syntax_const |> Symtab.update_new (f, mfx)))),
  1058                 syntax_const |> Symtab.update_new (f, mfx)))),
  1052           (term_of o read_cterm thy o rpair TypeInfer.logicT) mfx;
  1086           (term_of o read_cterm thy o rpair TypeInfer.logicT) mfx;
  1053         fun generate thy defs = fold_map (invoke_cg_expr thy defs)
  1087         fun generate thy defs = fold_map (invoke_cg_expr thy defs)
  1054           (Codegen.quotes_of proto_mfx);
  1088           (Codegen.quotes_of proto_mfx);
  1055       in
  1089       in
  1056         thy
  1090         thy
  1057         |> expand_module generate
  1091         |> expand_module (mk_deftab thy) generate
  1058         |-> (fn es => pair (Codegen.replace_quotes es proto_mfx))
  1092         |-> (fn es => pair (Codegen.replace_quotes es proto_mfx))
  1059       end;
  1093       end;
  1060   in
  1094   in
  1061     gen_add_syntax_const prep_const prep_mfx mk_name
  1095     gen_add_syntax_const prep_const prep_mfx mk_name
  1062   end;
  1096   end;
  1063 
  1097 
  1064 
  1098 
  1065 (* code generation *)
  1099 (* code generation *)
  1066 
  1100 
  1067 fun generate_code consts thy =
  1101 fun get_serializer thy serial_name =
  1068   let
  1102   (#serializer o (fn data => (the oo Symtab.lookup) data serial_name)
  1069     fun generate thy defs = fold_map (ensure_def_const thy defs) consts
  1103     o #serialize_data o CodegenData.get) thy;
       
  1104 
       
  1105 fun mk_const thy f =
       
  1106   let
       
  1107     val f' = Sign.intern_const thy f;
       
  1108   in (f', Sign.the_const_constraint thy f') end;
       
  1109 
       
  1110 fun gen_generate_code consts thy =
       
  1111   let
       
  1112     val defs = mk_deftab thy;
       
  1113     val consts' = map (idf_of_cname thy defs) consts;
       
  1114     fun generate thy defs = fold_map (ensure_def_const thy defs) consts'
  1070   in
  1115   in
  1071     thy
  1116     thy
  1072     |> expand_module generate
  1117     |> expand_module defs generate
  1073     |-> (fn _ => I)
  1118     |-> (fn _ => pair consts')
  1074   end;
  1119   end;
       
  1120 
       
  1121 fun generate_code consts thy =
       
  1122   gen_generate_code (map (mk_const thy) consts) thy;
  1075 
  1123 
  1076 fun serialize_code serial_name filename consts thy =
  1124 fun serialize_code serial_name filename consts thy =
  1077   let
  1125   let
  1078     fun mk_sfun tab name args f =
  1126     fun mk_sfun tab name args f =
  1079       Symtab.lookup tab name
  1127       Symtab.lookup tab name
  1081     val serialize_data =
  1129     val serialize_data =
  1082       thy
  1130       thy
  1083       |> CodegenData.get
  1131       |> CodegenData.get
  1084       |> #serialize_data
  1132       |> #serialize_data
  1085       |> (fn data => (the oo Symtab.lookup) data serial_name)
  1133       |> (fn data => (the oo Symtab.lookup) data serial_name)
  1086     val serializer = #serializer serialize_data
  1134     val serializer' = (get_serializer thy serial_name)
  1087       ((mk_sfun o #syntax_tyco) serialize_data)
  1135       ((mk_sfun o #syntax_tyco) serialize_data)
  1088       ((mk_sfun o #syntax_const) serialize_data)
  1136       ((mk_sfun o #syntax_const) serialize_data)
  1089       (#primitives serialize_data)
  1137       (#primitives serialize_data);
       
  1138     val _ = serializer' : string list option -> module -> Pretty.T;
  1090     val compile_it = serial_name = "ml" andalso filename = "-";
  1139     val compile_it = serial_name = "ml" andalso filename = "-";
  1091     fun use_code code = 
  1140     fun use_code code = 
  1092       if compile_it
  1141       if compile_it
  1093       then use_text Context.ml_output false code
  1142       then use_text Context.ml_output false code
  1094       else File.write (Path.unpack filename) (code ^ "\n");
  1143       else File.write (Path.unpack filename) (code ^ "\n");
       
  1144     val consts' = Option.map (map (mk_const thy)) consts;
  1095   in
  1145   in
  1096     thy
  1146     thy
  1097     |> (if is_some consts then generate_code (the consts) else I)
  1147     |> (if is_some consts then gen_generate_code (the consts') else pair [])
  1098     |> `(serializer consts o #modl o CodegenData.get)
  1148     |-> (fn [] => `(serializer' NONE o #modl o CodegenData.get)
       
  1149           | consts => `(serializer' (SOME consts) o #modl o CodegenData.get))
  1099     |-> (fn code => ((use_code o Pretty.output) code; I))
  1150     |-> (fn code => ((use_code o Pretty.output) code; I))
  1100   end;
  1151   end;
  1101 
  1152 
  1102 
  1153 
  1103 (* toplevel interface *)
  1154 (* toplevel interface *)
  1114 
  1165 
  1115 val generateP =
  1166 val generateP =
  1116   OuterSyntax.command generateK "generate executable code for constants" K.thy_decl ( 
  1167   OuterSyntax.command generateK "generate executable code for constants" K.thy_decl ( 
  1117     Scan.repeat1 P.name
  1168     Scan.repeat1 P.name
  1118     >> (fn consts =>
  1169     >> (fn consts =>
  1119           Toplevel.theory (generate_code consts))
  1170           Toplevel.theory (generate_code consts #> snd))
  1120   );
  1171   );
  1121 
  1172 
  1122 val serializeP =
  1173 val serializeP =
  1123   OuterSyntax.command generateK "serialize executable code for constants" K.thy_decl ( 
  1174   OuterSyntax.command serializeK "serialize executable code for constants" K.thy_decl ( 
  1124     P.name
  1175     P.name
  1125     -- P.name
  1176     -- P.name
  1126     -- Scan.option (
  1177     -- Scan.option (
  1127          P.$$$ serializeK
  1178          P.$$$ extractingK
  1128          |-- Scan.repeat1 P.name
  1179          |-- Scan.repeat1 P.name
  1129        )
  1180        )
  1130     >> (fn ((serial_name, filename), consts) =>
  1181     >> (fn ((serial_name, filename), consts) =>
  1131           Toplevel.theory (serialize_code serial_name filename consts))
  1182           Toplevel.theory (serialize_code serial_name filename consts))
  1132   );
  1183   );
  1147               P.$$$ definedK
  1198               P.$$$ definedK
  1148               |-- Scan.option (P.$$$ "(" |-- P.string --| P.$$$ ")")
  1199               |-- Scan.option (P.$$$ "(" |-- P.string --| P.$$$ ")")
  1149               -- (P.string -- Scan.optional (P.$$$ dependingK |-- P.list1 P.string) [])
  1200               -- (P.string -- Scan.optional (P.$$$ dependingK |-- P.list1 P.string) [])
  1150             )
  1201             )
  1151        )
  1202        )
  1152     >> (fn (serializer, xs) =>
  1203     >> (fn (serial_name, xs) =>
  1153           (Toplevel.theory oo fold)
  1204           (Toplevel.theory oo fold)
  1154             (fn ((tyco, raw_mfx), raw_def) =>
  1205             (fn ((tyco, raw_mfx), raw_def) =>
  1155               add_syntax_tyco serializer ((tyco, raw_mfx), raw_def)) xs)
  1206               add_syntax_tyco serial_name ((tyco, raw_mfx), raw_def)) xs)
  1156   );
  1207   );
  1157 
  1208 
  1158 val syntax_constP =
  1209 val syntax_constP =
  1159   OuterSyntax.command syntax_constK "define code syntax for constant" K.thy_decl (
  1210   OuterSyntax.command syntax_constK "define code syntax for constant" K.thy_decl (
  1160     P.string
  1211     P.string
  1164               P.$$$ definedK
  1215               P.$$$ definedK
  1165               |-- Scan.option (P.$$$ "(" |-- P.string --| P.$$$ ")")
  1216               |-- Scan.option (P.$$$ "(" |-- P.string --| P.$$$ ")")
  1166               -- (P.string -- Scan.optional (P.$$$ dependingK |-- P.list1 P.string) [])
  1217               -- (P.string -- Scan.optional (P.$$$ dependingK |-- P.list1 P.string) [])
  1167             )
  1218             )
  1168        )
  1219        )
  1169     >> (fn (serializer, xs) =>
  1220     >> (fn (serial_name, xs) =>
  1170           (Toplevel.theory oo fold)
  1221           (Toplevel.theory oo fold)
  1171             (fn ((f, raw_mfx), raw_def) =>
  1222             (fn ((f, raw_mfx), raw_def) =>
  1172               add_syntax_const serializer ((f, raw_mfx), raw_def)) xs)
  1223               add_syntax_const serial_name ((f, raw_mfx), raw_def)) xs)
  1173   );
  1224   );
  1174 
  1225 
  1175 val _ = OuterSyntax.add_parsers [generateP, serializeP, aliasP, syntax_tycoP, syntax_constP];
  1226 val _ = OuterSyntax.add_parsers [generateP, serializeP, aliasP, syntax_tycoP, syntax_constP];
  1176 val _ = OuterSyntax.add_keywords [extractingK, definedK, dependingK];
  1227 val _ = OuterSyntax.add_keywords [extractingK, definedK, dependingK];
  1177 
  1228 
  1186     fun pair t1 t2 = Type ("*", [t1, t2]);
  1237     fun pair t1 t2 = Type ("*", [t1, t2]);
  1187     val A = TVar (("'a", 0), []);
  1238     val A = TVar (("'a", 0), []);
  1188     val B = TVar (("'b", 0), []);
  1239     val B = TVar (("'b", 0), []);
  1189   in Context.add_setup [
  1240   in Context.add_setup [
  1190     CodegenData.init,
  1241     CodegenData.init,
  1191     add_codegen_class ("default", codegen_class_default),
  1242     add_codegen_sort ("default", codegen_sort_default),
  1192     add_codegen_type ("default", codegen_type_default),
  1243     add_codegen_type ("default", codegen_type_default),
  1193     add_codegen_expr ("default", codegen_expr_default),
  1244     add_codegen_expr ("default", codegen_expr_default),
  1194 (*     add_codegen_expr ("eq", codegen_eq),  *)
  1245 (*     add_codegen_expr ("eq", codegen_eq),  *)
  1195     add_codegen_expr ("neg", codegen_neg),
  1246     add_codegen_expr ("neg", codegen_neg),
  1196     add_defgen ("clsdecl", defgen_clsdecl),
  1247     add_defgen ("clsdecl", defgen_clsdecl),
  1197     add_defgen ("fallback_tyco", defgen_fallback_tyco),
  1248     add_defgen ("tyco_fallback", defgen_tyco_fallback),
  1198     add_defgen ("fallback_const", defgen_fallback_const),
  1249     add_defgen ("const_fallback", defgen_const_fallback),
  1199     add_defgen ("defs", defgen_defs),
  1250     add_defgen ("defs", defgen_defs),
  1200     add_defgen ("clsmem", defgen_clsmem),
  1251     add_defgen ("clsmem", defgen_clsmem),
  1201     add_defgen ("clsinst", defgen_clsinst),
  1252     add_defgen ("clsinst", defgen_clsinst),
  1202     add_alias ("op <>", "neq"),
  1253     add_alias ("op <>", "neq"),
  1203     add_alias ("op >=", "ge"),
  1254     add_alias ("op >=", "ge"),
  1206     add_alias ("op @", "append"),
  1257     add_alias ("op @", "append"),
  1207     add_lookup_tyco ("bool", type_bool),
  1258     add_lookup_tyco ("bool", type_bool),
  1208     add_lookup_tyco ("IntDef.int", type_integer),
  1259     add_lookup_tyco ("IntDef.int", type_integer),
  1209     add_lookup_tyco ("List.list", type_list),
  1260     add_lookup_tyco ("List.list", type_list),
  1210     add_lookup_tyco ("*", type_pair),
  1261     add_lookup_tyco ("*", type_pair),
  1211     add_lookup_const (("True", bool),Cons_true),
  1262     add_lookup_const (("True", bool), Cons_true),
  1212     add_lookup_const (("False", bool), Cons_false),
  1263     add_lookup_const (("False", bool), Cons_false),
  1213     add_lookup_const (("Not", bool --> bool), Fun_not),
  1264     add_lookup_const (("Not", bool --> bool), Fun_not),
  1214     add_lookup_const (("op &", bool --> bool --> bool), Fun_and),
  1265     add_lookup_const (("op &", bool --> bool --> bool), Fun_and),
  1215     add_lookup_const (("op |", bool --> bool --> bool), Fun_or),
  1266     add_lookup_const (("op |", bool --> bool --> bool), Fun_or),
  1216     add_lookup_const (("HOL.If", bool --> A --> A --> A), Fun_if),
  1267     add_lookup_const (("HOL.If", bool --> A --> A --> A), Fun_if),
  1217     add_lookup_const (("List.list.Cons", A --> list A --> list A),  Cons_cons),
  1268     add_lookup_const (("List.list.Cons", A --> list A --> list A), Cons_cons),
  1218     add_lookup_const (("List.list.Nil", list A), Cons_nil),
  1269     add_lookup_const (("List.list.Nil", list A), Cons_nil),
  1219     add_lookup_const (("Pair", A --> B --> pair A B), Cons_pair),
  1270     add_lookup_const (("Pair", A --> B --> pair A B), Cons_pair),
  1220     add_lookup_const (("fst", pair A B --> A), Fun_fst),
  1271     add_lookup_const (("fst", pair A B --> A), Fun_fst),
  1221     add_lookup_const (("snd", pair A B --> B), Fun_snd),
  1272     add_lookup_const (("snd", pair A B --> B), Fun_snd),
  1222     add_lookup_const (("1", nat),
  1273     add_lookup_const (("1", nat),