src/Pure/Tools/codegen_package.ML
changeset 18702 7dc7dcd63224
parent 18517 788fa99aba33
child 18704 2c86ced392a8
equal deleted inserted replaced
18701:98e6a0a011f3 18702:7dc7dcd63224
    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 auxtab;
    14   type auxtab;
    15   type appgen;
    15   type eqextr = theory -> auxtab
       
    16     -> (string * typ) -> (thm list * typ) option;
    16   type defgen;
    17   type defgen;
       
    18   type appgen = theory -> auxtab
       
    19     -> (string * typ) * term list -> CodegenThingol.transact -> CodegenThingol.iexpr * CodegenThingol.transact;
       
    20 
    17   val add_appconst: string * ((int * int) * appgen) -> theory -> theory;
    21   val add_appconst: string * ((int * int) * appgen) -> theory -> theory;
    18   val add_appconst_i: xstring * ((int * int) * appgen) -> theory -> theory;
    22   val add_appconst_i: xstring * ((int * int) * appgen) -> theory -> theory;
       
    23   val add_eqextr: string * eqextr -> theory -> theory;
    19   val add_defgen: string * defgen -> theory -> theory;
    24   val add_defgen: string * defgen -> theory -> theory;
    20   val add_prim_class: xstring -> string list -> (string * string)
    25   val add_prim_class: xstring -> string list -> (string * string)
    21     -> theory -> theory;
    26     -> theory -> theory;
    22   val add_prim_tyco: xstring -> string list -> (string * string)
    27   val add_prim_tyco: xstring -> string list -> (string * string)
    23     -> theory -> theory;
    28     -> theory -> theory;
    24   val add_prim_const: xstring * string option -> string list -> (string * string)
    29   val add_prim_const: xstring * string option -> string list -> (string * string)
    25     -> theory -> theory;
    30     -> theory -> theory;
    26   val add_prim_i: string -> string list -> (string * Pretty.T)
    31   val add_prim_i: string -> string list -> (string * Pretty.T)
    27     -> theory -> theory;
    32     -> theory -> theory;
    28   val add_syntax_tyco: xstring -> (string * (string * CodegenSerializer.fixity))
       
    29     -> theory -> theory;
       
    30   val add_syntax_tyco_i: string -> (string * (CodegenThingol.itype Codegen.mixfix list * CodegenSerializer.fixity))
       
    31       -> theory -> theory;
       
    32   val add_syntax_const: (xstring * string option) -> (string * (string * CodegenSerializer.fixity))
       
    33       -> theory -> theory;
       
    34   val add_syntax_const_i: string -> (string * (CodegenThingol.iexpr Codegen.mixfix list * CodegenSerializer.fixity))
       
    35     -> theory -> theory;
       
    36   val add_lookup_tyco: string * string -> theory -> theory;
       
    37   val add_lookup_const: (string * typ) * CodegenThingol.iexpr -> theory -> theory;
       
    38   val add_alias: string * string -> theory -> theory;
    33   val add_alias: string * string -> theory -> theory;
    39   val set_is_datatype: (theory -> string -> bool) -> theory -> theory;
    34   val set_is_datatype: (theory -> string -> bool) -> theory -> theory;
    40   val set_get_all_datatype_cons : (theory -> (string * string) list)
    35   val set_get_all_datatype_cons : (theory -> (string * string) list)
    41     -> theory -> theory;
    36     -> theory -> theory;
       
    37   val set_int_tyco: string -> theory -> theory;
    42 
    38 
    43   val exprgen_type: theory -> auxtab
    39   val exprgen_type: theory -> auxtab
    44     -> typ -> CodegenThingol.transact -> CodegenThingol.itype * CodegenThingol.transact;
    40     -> typ -> CodegenThingol.transact -> CodegenThingol.itype * CodegenThingol.transact;
    45   val exprgen_term: theory -> auxtab
    41   val exprgen_term: theory -> auxtab
    46     -> term -> CodegenThingol.transact -> CodegenThingol.iexpr * CodegenThingol.transact;
    42     -> term -> CodegenThingol.transact -> CodegenThingol.iexpr * CodegenThingol.transact;
    47   val ensure_def_tyco: theory -> auxtab
    43   val appgen_default: appgen;
    48     -> string -> CodegenThingol.transact -> string * CodegenThingol.transact;
       
    49   val ensure_def_const: theory -> auxtab
       
    50     -> string * typ -> CodegenThingol.transact -> string * CodegenThingol.transact;
       
    51 
    44 
    52   val appgen_let: (int -> term -> term list * term)
    45   val appgen_let: (int -> term -> term list * term)
    53     -> appgen;
    46     -> appgen;
    54   val appgen_split: (int -> term -> term list * term)
    47   val appgen_split: (int -> term -> term list * term)
    55     -> appgen;
    48     -> appgen;
    56   val appgen_number_of: (term -> IntInf.int) -> (term -> term)
    49   val appgen_number_of: (term -> term) -> (term -> IntInf.int) -> string -> string
    57     -> appgen;
    50     -> appgen;
    58   val appgen_datatype_case: (string * int) list
    51   val add_case_const: (theory -> string -> (string * int) list option) -> xstring
    59     -> appgen;
       
    60   val add_cg_case_const: (theory -> string -> (string * int) list option) -> xstring
       
    61     -> theory -> theory;
    52     -> theory -> theory;
    62   val add_cg_case_const_i: (theory -> string -> (string * int) list option) -> string
    53   val add_case_const_i: (theory -> string -> (string * int) list option) -> string
    63     -> theory -> theory;
    54     -> theory -> theory;
    64   val defgen_datatype: (theory -> string -> ((string * sort) list * string list) option)
    55   val defgen_datatype: (theory -> string -> ((string * sort) list * string list) option)
    65     -> (theory -> string * string -> typ list option)
    56     -> (theory -> string * string -> typ list option)
    66     -> defgen;
       
    67   val defgen_datacons: (theory -> string * string -> typ list option)
       
    68     -> defgen;
       
    69   val defgen_recfun: (theory -> string * typ -> (term list * term) list * typ)
       
    70     -> defgen;
    57     -> defgen;
    71 
    58 
    72   val print_codegen_generated: theory -> unit;
    59   val print_codegen_generated: theory -> unit;
    73   val rename_inconsistent: theory -> theory;
    60   val rename_inconsistent: theory -> theory;
    74   val ensure_datatype_case_consts: (theory -> string list)
    61   val ensure_datatype_case_consts: (theory -> string list)
   103 fun devarify_type ty = (fst o Type.freeze_thaw_type) ty;
    90 fun devarify_type ty = (fst o Type.freeze_thaw_type) ty;
   104 fun devarify_term t = (fst o Type.freeze_thaw) t;
    91 fun devarify_term t = (fst o Type.freeze_thaw) t;
   105 
    92 
   106 val is_number = is_some o Int.fromString;
    93 val is_number = is_some o Int.fromString;
   107 
    94 
   108 fun newline_correct s =
    95 fun merge_opt _ (x1, NONE) = x1
   109   s
    96   | merge_opt _ (NONE, x2) = x2
   110   |> space_explode "\n"
    97   | merge_opt eq (SOME x1, SOME x2) =
   111   |> map (implode o (fn [] => []
    98       if eq (x1, x2) then SOME x1 else error ("incompatible options during merge");
   112                       | (" "::xs) => xs
    99 
   113                       | xs => xs) o explode)
   100 
   114   |> space_implode "\n";
   101 (* shallow name spaces *)
   115 
       
   116 
       
   117 (* shallo name spaces *)
       
   118 
   102 
   119 val nsp_class = "class";
   103 val nsp_class = "class";
   120 val nsp_tyco = "tyco";
   104 val nsp_tyco = "tyco";
   121 val nsp_const = "const";
   105 val nsp_const = "const";
   122 val nsp_overl = "overl";
   106 val nsp_overl = "overl";
   123 val nsp_dtcon = "dtcon";
   107 val nsp_dtcon = "dtcon";
   124 val nsp_mem = "mem";
   108 val nsp_mem = "mem";
   125 val nsp_inst = "inst";
   109 val nsp_inst = "inst";
   126 val nsp_eq_inst = "eq_inst";
   110 
   127 val nsp_eq_pred = "eq";
   111 
   128 
   112 (* code generator basics *)
   129 
       
   130 (* code generator data types *)
       
   131 
   113 
   132 structure InstNameMangler = NameManglerFun (
   114 structure InstNameMangler = NameManglerFun (
   133   type ctxt = theory;
   115   type ctxt = theory;
   134   type src = string * (class * string);
   116   type src = string * (class * string);
   135   val ord = prod_ord string_ord (prod_ord string_ord string_ord);
   117   val ord = prod_ord string_ord (prod_ord string_ord string_ord);
   169 
   151 
   170 structure DatatypeconsNameMangler = NameManglerFun (
   152 structure DatatypeconsNameMangler = NameManglerFun (
   171   type ctxt = theory;
   153   type ctxt = theory;
   172   type src = string * string;
   154   type src = string * string;
   173   val ord = prod_ord string_ord string_ord;
   155   val ord = prod_ord string_ord string_ord;
   174   fun mk thy (("0", "nat"), _) =
   156   fun mk thy ((co, dtco), i) =
   175          "Nat.Zero"
       
   176     | mk thy ((co, dtco), i) =
       
   177         let
   157         let
   178           fun basename 0 = NameSpace.base co
   158           fun basename 0 = NameSpace.base co
   179             | basename 1 = NameSpace.base dtco ^ "_" ^ NameSpace.base co
   159             | basename 1 = NameSpace.base dtco ^ "_" ^ NameSpace.base co
   180             | basename i = NameSpace.base dtco ^ "_" ^ NameSpace.base co ^ "_" ^ (implode oo replicate) (i-1) "'";
   160             | basename i = NameSpace.base dtco ^ "_" ^ NameSpace.base co ^ "_" ^ (implode oo replicate) (i-1) "'";
   181           fun strip_dtco name =
   161           fun strip_dtco name =
   192   fun is_valid _ _ = true;
   172   fun is_valid _ _ = true;
   193   fun maybe_unique _ _ = NONE;
   173   fun maybe_unique _ _ = NONE;
   194   fun re_mangle _ dst = error ("no such datatype constructor: " ^ quote dst);
   174   fun re_mangle _ dst = error ("no such datatype constructor: " ^ quote dst);
   195 );
   175 );
   196 
   176 
   197 type auxtab = ((typ * (term list * term)) Symtab.table * string Symtab.table)
   177 type auxtab = ((typ * thm) list Symtab.table * string Symtab.table)
   198   * (InstNameMangler.T * ((typ * typ list) Symtab.table * ConstNameMangler.T) * DatatypeconsNameMangler.T);
   178   * (InstNameMangler.T * ((typ * typ list) Symtab.table * ConstNameMangler.T) * DatatypeconsNameMangler.T);
   199 
   179 type eqextr = theory -> auxtab
   200 type appgen = theory -> auxtab -> ((string * typ) * term list, iexpr) gen_exprgen;
   180   -> (string * typ) -> (thm list * typ) option;
   201 type defgen = theory -> auxtab -> gen_defgen;
   181 type defgen = theory -> auxtab -> gen_defgen;
   202 
   182 type appgen = theory -> auxtab -> (string * typ) * term list -> transact -> iexpr * transact;
   203 
   183 
   204 (* serializer *)
   184 val serializers = ref (
   205 
   185   Symtab.empty
   206 val serializer_ml =
   186   |> Symtab.update (
   207   let
   187        #ml CodegenSerializer.serializers
   208     val name_root = "Generated";
   188        |> apsnd (fn seri => seri
   209     val nsp_conn = [
   189             (nsp_dtcon, nsp_class, "")
   210       [nsp_class, nsp_tyco], [nsp_const, nsp_overl, nsp_dtcon, nsp_mem, nsp_inst, nsp_eq_inst, nsp_eq_pred]
   190             [[nsp_class, nsp_tyco], [nsp_const, nsp_overl, nsp_dtcon, nsp_mem, nsp_inst]]
   211     ];
   191           )
   212   in CodegenSerializer.ml_from_thingol nsp_conn nsp_class name_root end;
   192      )
   213 
   193   |> Symtab.update (
   214 val serializer_hs =
   194        #haskell CodegenSerializer.serializers
   215   let
   195        |> apsnd (fn seri => seri
   216     val name_root = "Generated";
   196             nsp_dtcon
   217     val nsp_conn = [
   197             [[nsp_class], [nsp_tyco], [nsp_const, nsp_overl, nsp_mem], [nsp_dtcon], [nsp_inst]]
   218       [nsp_class], [nsp_tyco], [nsp_const, nsp_overl, nsp_mem, nsp_eq_pred], [nsp_dtcon], [nsp_inst, nsp_eq_inst]
   198           )
   219     ];
   199      )
   220   in CodegenSerializer.haskell_from_thingol nsp_conn nsp_dtcon name_root end;
   200 );
   221 
   201 
   222 
   202 
   223 (* theory data for code generator *)
   203 (* theory data for code generator *)
   224 
   204 
   225 type gens = {
   205 type gens = {
   226   appconst: ((int * int) * (appgen * stamp)) Symtab.table,
   206   appconst: ((int * int) * (appgen * stamp)) Symtab.table,
       
   207   eqextrs: (string * (eqextr * stamp)) list,
   227   defgens: (string * (defgen * stamp)) list
   208   defgens: (string * (defgen * stamp)) list
   228 };
   209 };
   229 
   210 
   230 fun map_gens f { appconst, defgens } =
   211 fun map_gens f { appconst, eqextrs, defgens } =
   231   let
   212   let
   232     val (appconst, defgens) =
   213     val (appconst, eqextrs, defgens) =
   233       f (appconst, defgens)
   214       f (appconst, eqextrs, defgens)
   234   in { appconst = appconst, defgens = defgens } : gens end;
   215   in { appconst = appconst, eqextrs = eqextrs, defgens = defgens } : gens end;
   235 
   216 
   236 fun merge_gens
   217 fun merge_gens
   237   ({ appconst = appconst1 , defgens = defgens1 },
   218   ({ appconst = appconst1 , eqextrs = eqextrs1, defgens = defgens1 },
   238    { appconst = appconst2 , defgens = defgens2 }) =
   219    { appconst = appconst2 , eqextrs = eqextrs2, defgens = defgens2 }) =
   239   { appconst = Symtab.merge
   220   { appconst = Symtab.merge
   240       (fn ((bounds1, (_, stamp1)), (bounds2, (_, stamp2))) => bounds1 = bounds2 andalso stamp1 = stamp2)
   221       (fn ((bounds1, (_, stamp1)), (bounds2, (_, stamp2))) => bounds1 = bounds2 andalso stamp1 = stamp2)
   241       (appconst1, appconst2),
   222       (appconst1, appconst2),
   242     defgens = AList.merge (op =) (eq_snd (op =)) (defgens1, defgens2) } : gens;
   223     eqextrs = AList.merge (op =) (eq_snd (op =)) (eqextrs1, eqextrs2),
   243 
   224     defgens = AList.merge (op =) (eq_snd (op =)) (defgens1, defgens2)
   244 type lookups = {
   225   } : gens;
   245   lookups_tyco: string Symtab.table,
       
   246   lookups_const: (typ * iexpr) list Symtab.table
       
   247 }
       
   248 
       
   249 fun map_lookups f { lookups_tyco, lookups_const } =
       
   250   let
       
   251     val (lookups_tyco, lookups_const) =
       
   252       f (lookups_tyco, lookups_const)
       
   253   in { lookups_tyco = lookups_tyco, lookups_const = lookups_const } : lookups end;
       
   254 
       
   255 fun merge_lookups
       
   256   ({ lookups_tyco = lookups_tyco1, lookups_const = lookups_const1 },
       
   257    { lookups_tyco = lookups_tyco2, lookups_const = lookups_const2 }) =
       
   258   { lookups_tyco = Symtab.merge (op =) (lookups_tyco1, lookups_tyco2),
       
   259     lookups_const = Symtab.merge (op =) (lookups_const1, lookups_const2) } : lookups;
       
   260 
   226 
   261 type logic_data = {
   227 type logic_data = {
   262   is_datatype: ((theory -> string -> bool) * stamp) option,
   228   is_datatype: ((theory -> string -> bool) * stamp) option,
   263   get_all_datatype_cons: ((theory -> (string * string) list) * stamp) option,
   229   get_all_datatype_cons: ((theory -> (string * string) list) * stamp) option,
   264   alias: string Symtab.table * string Symtab.table
   230   alias: string Symtab.table * string Symtab.table
   266 
   232 
   267 fun map_logic_data f { is_datatype, get_all_datatype_cons, alias } =
   233 fun map_logic_data f { is_datatype, get_all_datatype_cons, alias } =
   268   let
   234   let
   269     val ((is_datatype, get_all_datatype_cons), alias) =
   235     val ((is_datatype, get_all_datatype_cons), alias) =
   270       f ((is_datatype, get_all_datatype_cons), alias)
   236       f ((is_datatype, get_all_datatype_cons), alias)
   271   in { is_datatype = is_datatype, get_all_datatype_cons = get_all_datatype_cons, alias = alias } : logic_data end;
   237   in { is_datatype = is_datatype, get_all_datatype_cons = get_all_datatype_cons,
       
   238     alias = alias } : logic_data end;
   272 
   239 
   273 fun merge_logic_data
   240 fun merge_logic_data
   274   ({ is_datatype = is_datatype1, get_all_datatype_cons = get_all_datatype_cons1, alias = alias1 },
   241   ({ is_datatype = is_datatype1, get_all_datatype_cons = get_all_datatype_cons1,
   275    { is_datatype = is_datatype2, get_all_datatype_cons = get_all_datatype_cons2, alias = alias2 }) =
   242        alias = alias1 },
   276   let
   243    { is_datatype = is_datatype2, get_all_datatype_cons = get_all_datatype_cons2,
   277     fun merge_opt _ (x1, NONE) = x1
   244        alias = alias2 }) =
   278       | merge_opt _ (NONE, x2) = x2
   245   let
   279       | merge_opt eq (SOME x1, SOME x2) =
       
   280           if eq (x1, x2) then SOME x1 else error ("incompatible options during merge");
       
   281   in
   246   in
   282     { is_datatype = merge_opt (eq_snd (op =)) (is_datatype1, is_datatype2),
   247     { is_datatype = merge_opt (eq_snd (op =)) (is_datatype1, is_datatype2),
   283       get_all_datatype_cons = merge_opt (eq_snd (op =)) (get_all_datatype_cons1, get_all_datatype_cons2),
   248       get_all_datatype_cons = merge_opt (eq_snd (op =)) (get_all_datatype_cons1, get_all_datatype_cons2),
   284       alias = (Symtab.merge (op =) (fst alias1, fst alias2),
   249       alias = (Symtab.merge (op =) (fst alias1, fst alias2),
   285                Symtab.merge (op =) (snd alias1, snd alias2)) } : logic_data
   250                Symtab.merge (op =) (snd alias1, snd alias2)) } : logic_data
   286   end;
   251   end;
   287 
   252 
   288 type serialize_data = {
   253 type target_data = {
   289   serializer: CodegenSerializer.serializer,
       
   290   syntax_tyco: (itype CodegenSerializer.pretty_syntax * stamp) Symtab.table,
   254   syntax_tyco: (itype CodegenSerializer.pretty_syntax * stamp) Symtab.table,
   291   syntax_const: (iexpr CodegenSerializer.pretty_syntax * stamp) Symtab.table
   255   syntax_const: (iexpr CodegenSerializer.pretty_syntax * stamp) Symtab.table
   292 };
   256 };
   293 
   257 
   294 fun map_serialize_data f { serializer, syntax_tyco, syntax_const } =
   258 fun map_target_data f { syntax_tyco, syntax_const } =
   295   let
   259   let
   296     val (syntax_tyco, syntax_const) =
   260     val (syntax_tyco, syntax_const) =
   297       f (syntax_tyco, syntax_const)
   261       f (syntax_tyco, syntax_const)
   298   in { serializer = serializer,
   262   in { syntax_tyco = syntax_tyco, syntax_const = syntax_const } : target_data
   299        syntax_tyco = syntax_tyco, syntax_const = syntax_const } : serialize_data
   263   end;
   300   end;
   264 
   301 
   265 fun merge_target_data
   302 fun merge_serialize_data
   266   ({ syntax_tyco = syntax_tyco1, syntax_const = syntax_const1 },
   303   ({ serializer = serializer,
   267    { syntax_tyco = syntax_tyco2, syntax_const = syntax_const2 }) =
   304      syntax_tyco = syntax_tyco1, syntax_const = syntax_const1 },
   268   { syntax_tyco = Symtab.merge (eq_snd (op =)) (syntax_tyco1, syntax_tyco2),
   305    {serializer = _,
   269     syntax_const = Symtab.merge (eq_snd (op =)) (syntax_const1, syntax_const2) } : target_data;
   306      syntax_tyco = syntax_tyco2, syntax_const = syntax_const2 }) =
       
   307   { serializer = serializer,
       
   308     syntax_tyco = Symtab.merge (eq_snd (op =)) (syntax_tyco1, syntax_tyco2),
       
   309     syntax_const = Symtab.merge (eq_snd (op =)) (syntax_const1, syntax_const2) } : serialize_data;
       
   310 
   270 
   311 structure CodegenData = TheoryDataFun
   271 structure CodegenData = TheoryDataFun
   312 (struct
   272 (struct
   313   val name = "Pure/codegen_package";
   273   val name = "Pure/codegen_package";
   314   type T = {
   274   type T = {
   315     modl: module,
   275     modl: module,
   316     gens: gens,
   276     gens: gens,
   317     lookups: lookups,
       
   318     logic_data: logic_data,
   277     logic_data: logic_data,
   319     serialize_data: serialize_data Symtab.table
   278     target_data: target_data Symtab.table
   320   };
   279   };
   321   val empty = {
   280   val empty = {
   322     modl = empty_module,
   281     modl = empty_module,
   323     gens = { appconst = Symtab.empty, defgens = [] } : gens,
   282     gens = { appconst = Symtab.empty, eqextrs = [], defgens = [] } : gens,
   324     lookups = { lookups_tyco = Symtab.empty, lookups_const = Symtab.empty } : lookups,
       
   325     logic_data = { is_datatype = NONE, get_all_datatype_cons = NONE,
   283     logic_data = { is_datatype = NONE, get_all_datatype_cons = NONE,
   326       alias = (Symtab.empty, Symtab.empty) } : logic_data,
   284       alias = (Symtab.empty, Symtab.empty) } : logic_data,
   327     serialize_data =
   285     target_data =
   328       Symtab.empty
   286       Symtab.empty
   329       |> Symtab.update ("ml",
   287       |> Symtab.fold (fn (target, _) =>
   330           { serializer = serializer_ml : CodegenSerializer.serializer,
   288            Symtab.update (target, { syntax_tyco = Symtab.empty, syntax_const = Symtab.empty })
   331             syntax_tyco = Symtab.empty, syntax_const = Symtab.empty })
   289          ) (! serializers)
   332       |> Symtab.update ("haskell",
       
   333           { serializer = serializer_hs : CodegenSerializer.serializer,
       
   334             syntax_tyco = Symtab.empty, syntax_const = Symtab.empty })
       
   335   } : T;
   290   } : T;
   336   val copy = I;
   291   val copy = I;
   337   val extend = I;
   292   val extend = I;
   338   fun merge _ (
   293   fun merge _ (
   339     { modl = modl1, gens = gens1, lookups = lookups1,
   294     { modl = modl1, gens = gens1,
   340       serialize_data = serialize_data1, logic_data = logic_data1 },
   295       target_data = target_data1, logic_data = logic_data1 },
   341     { modl = modl2, gens = gens2, lookups = lookups2,
   296     { modl = modl2, gens = gens2,
   342       serialize_data = serialize_data2, logic_data = logic_data2 }
   297       target_data = target_data2, logic_data = logic_data2 }
   343   ) = {
   298   ) = {
   344     modl = merge_module (modl1, modl2),
   299     modl = merge_module (modl1, modl2),
   345     gens = merge_gens (gens1, gens2),
   300     gens = merge_gens (gens1, gens2),
   346     lookups = merge_lookups (lookups1, lookups2),
       
   347     logic_data = merge_logic_data (logic_data1, logic_data2),
   301     logic_data = merge_logic_data (logic_data1, logic_data2),
   348     serialize_data = Symtab.join (K (merge_serialize_data #> SOME))
   302     target_data = Symtab.join (K (merge_target_data #> SOME))
   349       (serialize_data1, serialize_data2)
   303       (target_data1, target_data2)
   350   };
   304   };
   351   fun print thy _ = writeln "sorry, this stuff is too complicated...";
   305   fun print thy _ = writeln "sorry, this stuff is too complicated...";
   352 end);
   306 end);
   353 
   307 
   354 fun map_codegen_data f thy =
   308 fun map_codegen_data f thy =
   355   case CodegenData.get thy
   309   case CodegenData.get thy
   356    of { modl, gens, lookups, serialize_data, logic_data } =>
   310    of { modl, gens, target_data, logic_data } =>
   357       let val (modl, gens, lookups, serialize_data, logic_data) =
   311       let val (modl, gens, target_data, logic_data) =
   358         f (modl, gens, lookups, serialize_data, logic_data)
   312         f (modl, gens, target_data, logic_data)
   359       in CodegenData.put { modl = modl, gens = gens, lookups = lookups,
   313       in CodegenData.put { modl = modl, gens = gens,
   360            serialize_data = serialize_data, logic_data = logic_data } thy end;
   314            target_data = target_data, logic_data = logic_data } thy end;
   361 
   315 
   362 fun print_codegen_generated thy =
   316 fun print_codegen_generated thy =
   363   let
   317   let
   364     val module = (#modl o CodegenData.get) thy;
   318     val module = (#modl o CodegenData.get) thy;
   365   in
   319   in
   368 
   322 
   369 fun gen_add_appconst prep_const (raw_c, (bounds, ag)) thy =
   323 fun gen_add_appconst prep_const (raw_c, (bounds, ag)) thy =
   370   let
   324   let
   371     val c = prep_const thy raw_c;
   325     val c = prep_const thy raw_c;
   372   in map_codegen_data
   326   in map_codegen_data
   373     (fn (modl, gens, lookups, serialize_data, logic_data) =>
   327     (fn (modl, gens, target_data, logic_data) =>
   374        (modl,
   328        (modl,
   375         gens |> map_gens
   329         gens |> map_gens
   376           (fn (appconst, defgens) =>
   330           (fn (appconst, eqextrs, defgens) =>
   377             (appconst
   331             (appconst
   378              |> Symtab.update (c, (bounds, (ag, stamp ()))),
   332              |> Symtab.update (c, (bounds, (ag, stamp ()))),
   379              defgens)), lookups, serialize_data, logic_data)) thy
   333              eqextrs, defgens)), target_data, logic_data)) thy
   380   end;
   334   end;
   381 
   335 
   382 val add_appconst = gen_add_appconst Sign.intern_const;
   336 val add_appconst = gen_add_appconst Sign.intern_const;
   383 val add_appconst_i = gen_add_appconst (K I);
   337 val add_appconst_i = gen_add_appconst (K I);
   384 
   338 
   385 fun add_defgen (name, dg) =
   339 fun add_defgen (name, dg) =
   386   map_codegen_data
   340   map_codegen_data
   387     (fn (modl, gens, lookups, serialize_data, logic_data) =>
   341     (fn (modl, gens, target_data, logic_data) =>
   388        (modl,
   342        (modl,
   389         gens |> map_gens
   343         gens |> map_gens
   390           (fn (appconst, defgens) =>
   344           (fn (appconst, eqextrs, defgens) =>
   391             (appconst, defgens
   345             (appconst, eqextrs, defgens
   392              |> Output.update_warn (op =) ("overwriting existing definition definition generator " ^ name) (name, (dg, stamp ())))),
   346              |> Output.update_warn (op =) ("overwriting existing definition definition generator " ^ name) (name, (dg, stamp ())))),
   393              lookups, serialize_data, logic_data));
   347              target_data, logic_data));
   394 
   348 
   395 fun get_defgens thy tabs =
   349 fun get_defgens thy tabs =
   396   (map (apsnd (fn (dg, _) => dg thy tabs)) o #defgens o #gens o CodegenData.get) thy;
   350   (map (apsnd (fn (dg, _) => dg thy tabs)) o #defgens o #gens o CodegenData.get) thy;
   397 
   351 
   398 fun add_lookup_tyco (src, dst) =
   352 fun add_eqextr (name, eqx) =
   399   map_codegen_data
   353   map_codegen_data
   400     (fn (modl, gens, lookups, serialize_data, logic_data) =>
   354     (fn (modl, gens, target_data, logic_data) =>
   401        (modl, gens,
   355        (modl,
   402         lookups |> map_lookups
   356         gens |> map_gens
   403           (fn (lookups_tyco, lookups_const) =>
   357           (fn (appconst, eqextrs, defgens) =>
   404             (lookups_tyco |> Symtab.update_new (src, dst),
   358             (appconst, eqextrs
   405              lookups_const)),
   359              |> Output.update_warn (op =) ("overwriting existing equation extractor " ^ name) (name, (eqx, stamp ())),
   406         serialize_data, logic_data));
   360              defgens)),
   407 
   361              target_data, logic_data));
   408 val lookup_tyco = Symtab.lookup o #lookups_tyco o #lookups o CodegenData.get;
   362 
   409 
   363 fun get_eqextrs thy tabs =
   410 fun add_lookup_const ((src, ty), dst) =
   364   (map (fn (_, (eqx, _)) => eqx thy tabs) o #eqextrs o #gens o CodegenData.get) thy;
   411   map_codegen_data
       
   412     (fn (modl, gens, lookups, serialize_data, logic_data) =>
       
   413        (modl, gens,
       
   414         lookups |> map_lookups
       
   415           (fn (lookups_tyco, lookups_const) =>
       
   416             (lookups_tyco,
       
   417              lookups_const |> Symtab.update_multi (src, (ty, dst)))),
       
   418         serialize_data, logic_data));
       
   419 
       
   420 fun lookup_const thy (f, ty) =
       
   421   (Symtab.lookup_multi o #lookups_const o #lookups o CodegenData.get) thy f
       
   422   |> (fn tab => AList.lookup (Sign.typ_instance thy) tab ty);
       
   423 
       
   424 fun set_is_datatype f =
       
   425   map_codegen_data
       
   426     (fn (modl, gens, lookups, serialize_data, logic_data) =>
       
   427        (modl, gens, lookups, serialize_data,
       
   428         logic_data
       
   429         |> map_logic_data ((apfst o apfst) (K (SOME (f, stamp ()))))));
       
   430 
   365 
   431 fun is_datatype thy =
   366 fun is_datatype thy =
   432   case (#is_datatype o #logic_data o CodegenData.get) thy
   367   case (#is_datatype o #logic_data o CodegenData.get) thy
   433    of NONE => K false
   368    of NONE => K false
   434     | SOME (f, _) => f thy;
   369     | SOME (f, _) => f thy;
   435 
   370 
   436 fun set_get_all_datatype_cons f =
       
   437   map_codegen_data
       
   438     (fn (modl, gens, lookups, serialize_data, logic_data) =>
       
   439        (modl, gens, lookups, serialize_data,
       
   440         logic_data
       
   441         |> map_logic_data ((apfst o apsnd) (K (SOME (f, stamp ()))))));
       
   442 
       
   443 fun get_all_datatype_cons thy =
   371 fun get_all_datatype_cons thy =
   444   case (#get_all_datatype_cons o #logic_data o CodegenData.get) thy
   372   case (#get_all_datatype_cons o #logic_data o CodegenData.get) thy
   445    of NONE => []
   373    of NONE => []
   446     | SOME (f, _) => f thy;
   374     | SOME (f, _) => f thy;
   447 
   375 
   448 fun add_alias (src, dst) =
   376 fun add_alias (src, dst) =
   449   map_codegen_data
   377   map_codegen_data
   450     (fn (modl, gens, lookups, serialize_data, logic_data) =>
   378     (fn (modl, gens, target_data, logic_data) =>
   451        (modl, gens, lookups, serialize_data,
   379        (modl, gens, target_data,
   452         logic_data |> map_logic_data
   380         logic_data |> map_logic_data
   453           (apsnd (fn (tab, tab_rev) =>
   381           (apsnd (fn (tab, tab_rev) =>
   454             (tab |> Symtab.update (src, dst),
   382             (tab |> Symtab.update (src, dst),
   455              tab_rev |> Symtab.update (dst, src))))));
   383              tab_rev |> Symtab.update (dst, src))))));
   456 
   384 
   457 
   385 
   458 (* name handling *)
   386 (* name handling *)
   459 
       
   460 val nsp_class = "class";
       
   461 val nsp_tyco = "tyco";
       
   462 val nsp_const = "const";
       
   463 val nsp_overl = "overl";
       
   464 val nsp_dtcon = "dtcon";
       
   465 val nsp_mem = "mem";
       
   466 val nsp_inst = "inst";
       
   467 val nsp_eq_inst = "eq_inst";
       
   468 val nsp_eq_pred = "eq";
       
   469 
   387 
   470 val alias_get = perhaps o Symtab.lookup o fst o #alias o #logic_data o CodegenData.get;
   388 val alias_get = perhaps o Symtab.lookup o fst o #alias o #logic_data o CodegenData.get;
   471 val alias_rev = perhaps o Symtab.lookup o snd o #alias o #logic_data o CodegenData.get;
   389 val alias_rev = perhaps o Symtab.lookup o snd o #alias o #logic_data o CodegenData.get;
   472 
   390 
   473 fun add_nsp shallow name =
   391 fun add_nsp shallow name =
   475   |> NameSpace.unpack
   393   |> NameSpace.unpack
   476   |> split_last
   394   |> split_last
   477   |> apsnd (single #> cons shallow)
   395   |> apsnd (single #> cons shallow)
   478   |> (op @)
   396   |> (op @)
   479   |> NameSpace.pack;
   397   |> NameSpace.pack;
       
   398 
   480 fun dest_nsp nsp idf =
   399 fun dest_nsp nsp idf =
   481   let
   400   let
   482     val idf' = NameSpace.unpack idf;
   401     val idf' = NameSpace.unpack idf;
   483     val (idf'', idf_base) = split_last idf';
   402     val (idf'', idf_base) = split_last idf';
   484     val (modl, shallow) = split_last idf'';
   403     val (modl, shallow) = split_last idf'';
   487     then (SOME o NameSpace.pack) (modl @ [idf_base])
   406     then (SOME o NameSpace.pack) (modl @ [idf_base])
   488     else NONE
   407     else NONE
   489   end;
   408   end;
   490 
   409 
   491 fun idf_of_name thy shallow name =
   410 fun idf_of_name thy shallow name =
   492   if is_number name
   411   name
   493   then name
   412   |> alias_get thy
   494   else
   413   |> add_nsp shallow;
   495     name
   414 
   496     |> alias_get thy
       
   497     |> add_nsp shallow;
       
   498 fun name_of_idf thy shallow idf =
   415 fun name_of_idf thy shallow idf =
   499   idf
   416   idf
   500   |> dest_nsp shallow
   417   |> dest_nsp shallow
   501   |> Option.map (alias_rev thy);
   418   |> Option.map (alias_rev thy);
   502 
   419 
       
   420 fun set_is_datatype f =
       
   421   map_codegen_data
       
   422     (fn (modl, gens, target_data, logic_data) =>
       
   423        (modl, gens, target_data,
       
   424         logic_data
       
   425         |> map_logic_data (apfst (fn (is_datatype, get_all_datatype_cons)
       
   426              => (SOME (f, stamp ()), get_all_datatype_cons)))));
       
   427 
       
   428 fun set_get_all_datatype_cons f =
       
   429   map_codegen_data
       
   430     (fn (modl, gens, target_data, logic_data) =>
       
   431        (modl, gens, target_data,
       
   432         logic_data
       
   433         |> map_logic_data ((apfst (fn (is_datatype, get_all_datatype_cons)
       
   434              => (is_datatype, SOME (f, stamp ())))))));
       
   435 
       
   436 fun set_int_tyco tyco thy =
       
   437   (serializers := (
       
   438     ! serializers
       
   439     |> Symtab.update (
       
   440          #ml CodegenSerializer.serializers
       
   441          |> apsnd (fn seri => seri
       
   442               (nsp_dtcon, nsp_class, idf_of_name thy nsp_tyco tyco)
       
   443               [[nsp_class, nsp_tyco], [nsp_const, nsp_overl, nsp_dtcon, nsp_mem, nsp_inst]]
       
   444             )
       
   445        )
       
   446     ); thy);
       
   447 
   503 
   448 
   504 (* code generator instantiation *)
   449 (* code generator instantiation *)
   505 
   450 
   506 fun ensure_def_class thy tabs cls trns =
   451 fun ensure_def_class thy tabs cls trns =
   507   let
   452   let
   513     |> pair cls'
   458     |> pair cls'
   514   end;
   459   end;
   515 
   460 
   516 fun ensure_def_inst thy (tabs as (_, (insttab, _, _))) (cls, tyco) trns =
   461 fun ensure_def_inst thy (tabs as (_, (insttab, _, _))) (cls, tyco) trns =
   517   let
   462   let
   518     val thyname = (the o AList.lookup (op =) (ClassPackage.the_tycos thy cls)) tyco;
   463     val thyname = (the o AList.lookup (op =) (ClassPackage.the_instances thy cls)) tyco;
   519     val inst = idf_of_name thy nsp_inst (InstNameMangler.get thy insttab (thyname, (cls, tyco)));
   464     val inst = idf_of_name thy nsp_inst (InstNameMangler.get thy insttab (thyname, (cls, tyco)));
   520   in
   465   in
   521     trns
   466     trns
   522     |> debug 4 (fn _ => "generating instance " ^ quote cls ^ " / " ^ quote tyco)
   467     |> debug 4 (fn _ => "generating instance " ^ quote cls ^ " / " ^ quote tyco)
   523     |> gen_ensure_def (get_defgens thy tabs) ("generating instance " ^ quote cls ^ " / " ^ quote tyco) inst
   468     |> gen_ensure_def (get_defgens thy tabs) ("generating instance " ^ quote cls ^ " / " ^ quote tyco) inst
   525   end;
   470   end;
   526 
   471 
   527 fun ensure_def_tyco thy tabs tyco trns =
   472 fun ensure_def_tyco thy tabs tyco trns =
   528   let
   473   let
   529     val tyco' = idf_of_name thy nsp_tyco tyco;
   474     val tyco' = idf_of_name thy nsp_tyco tyco;
   530   in case lookup_tyco thy tyco
   475   in
   531    of NONE =>
   476     trns
   532         trns
   477     |> debug 4 (fn _ => "generating type constructor " ^ quote tyco)
   533         |> debug 4 (fn _ => "generating type constructor " ^ quote tyco)
   478     |> gen_ensure_def (get_defgens thy tabs) ("generating type constructor " ^ quote tyco) tyco'
   534         |> gen_ensure_def (get_defgens thy tabs) ("generating type constructor " ^ quote tyco) tyco'
   479     |> pair tyco'
   535         |> pair tyco'
       
   536     | SOME tyco =>
       
   537         trns
       
   538         |> pair tyco
       
   539   end;
   480   end;
   540 
   481 
   541 fun idf_of_const thy (tabs as ((_, clsmemtab), (_, (overltab1, overltab2), dtcontab))) (c, ty) =
   482 fun idf_of_const thy (tabs as ((_, clsmemtab), (_, (overltab1, overltab2), dtcontab))) (c, ty) =
   542   let
   483   let
   543     fun get_overloaded (c, ty) =
   484     fun get_overloaded (c, ty) =
   551     fun get_datatypecons (c, ty) =
   492     fun get_datatypecons (c, ty) =
   552       case (snd o strip_type) ty
   493       case (snd o strip_type) ty
   553        of Type (tyco, _) =>
   494        of Type (tyco, _) =>
   554             try (DatatypeconsNameMangler.get thy dtcontab) (c, tyco)
   495             try (DatatypeconsNameMangler.get thy dtcontab) (c, tyco)
   555         | _ => NONE;
   496         | _ => NONE;
   556   in case get_overloaded (c, ty)
   497   in case get_datatypecons (c, ty)
       
   498    of SOME c' => idf_of_name thy nsp_dtcon c'
       
   499     | NONE => case get_overloaded (c, ty)
   557    of SOME idf => idf
   500    of SOME idf => idf
   558     | NONE => case get_datatypecons (c, ty)
       
   559    of SOME c' => idf_of_name thy nsp_dtcon c'
       
   560     | NONE => case Symtab.lookup clsmemtab c
   501     | NONE => case Symtab.lookup clsmemtab c
   561    of SOME _ => idf_of_name thy nsp_mem c
   502    of SOME _ => idf_of_name thy nsp_mem c
   562     | NONE => idf_of_name thy nsp_const c
   503     | NONE => idf_of_name thy nsp_const c
   563   end;
   504   end;
   564 
   505 
   565 fun recconst_of_idf thy (_, (_, (_, overltab2), _)) idf =
   506 fun recconst_of_idf thy (_, (_, (_, overltab2), _)) idf =
   566   case name_of_idf thy nsp_const idf
   507   case name_of_idf thy nsp_const idf
   567    of SOME c => SOME (c, Sign.the_const_constraint thy c)
   508    of SOME c => SOME (c, Sign.the_const_type thy c)
   568     | NONE => (
   509     | NONE => (
   569         case dest_nsp nsp_overl idf
   510         case dest_nsp nsp_overl idf
   570          of SOME _ =>
   511          of SOME _ =>
   571               idf
   512               idf
   572               |> ConstNameMangler.rev thy overltab2
   513               |> ConstNameMangler.rev thy overltab2
   577       );
   518       );
   578 
   519 
   579 fun ensure_def_const thy (tabs as ((_, clsmemtab), (_, overltab, dtcontab))) (c, ty) trns =
   520 fun ensure_def_const thy (tabs as ((_, clsmemtab), (_, overltab, dtcontab))) (c, ty) trns =
   580   let
   521   let
   581     val c' = idf_of_const thy tabs (c, ty);
   522     val c' = idf_of_const thy tabs (c, ty);
   582   in case lookup_const thy (c, ty)
   523   in
   583    of NONE =>
   524     trns
   584         trns
   525     |> debug 4 (fn _ => "generating constant " ^ quote c)
   585         |> debug 4 (fn _ => "generating constant " ^ quote c)
   526     |> gen_ensure_def (get_defgens thy tabs) ("generating constant " ^ quote c) c'
   586         |> gen_ensure_def (get_defgens thy tabs) ("generating constant " ^ quote c) c'
   527     |> pair c'
   587         |> pair c'
   528   end;
   588     | SOME (IConst (c, ty)) =>
   529 
   589         trns
   530 (* fun ensure_def_eq thy tabs (dtco, (eqpred, arity)) trns =
   590         |> pair c
       
   591   end;
       
   592 
       
   593 fun ensure_def_eq thy tabs (dtco, (eqpred, arity)) trns =
       
   594   let
   531   let
   595     val name_dtco = (the ooo name_of_idf) thy nsp_tyco dtco;
   532     val name_dtco = (the ooo name_of_idf) thy nsp_tyco dtco;
   596     val idf_eqinst = idf_of_name thy nsp_eq_inst name_dtco;
   533     val idf_eqinst = idf_of_name thy nsp_eq_inst name_dtco;
   597     val idf_eqpred = idf_of_name thy nsp_eq_pred name_dtco;
   534     val idf_eqpred = idf_of_name thy nsp_eq_pred name_dtco;
   598     val inst_sortlookup = map (fn (v, _) => [ClassPackage.Lookup ([], (v, 0))]) arity;
   535     val inst_sortlookup = map (fn (v, _) => [ClassPackage.Lookup ([], (v, 0))]) arity;
   599     fun mk_eq_pred _ trns =
   536     fun mk_eq_pred _ trns =
   600       trns
   537       trns
   601       |> succeed (eqpred, [])
   538       |> succeed (eqpred)
   602     fun mk_eq_inst _ trns =
   539     fun mk_eq_inst _ trns =
   603       trns
   540       trns
   604       |> gen_ensure_def [("eqpred", mk_eq_pred)] ("generating equality predicate for " ^ quote dtco) idf_eqpred
   541       |> gen_ensure_def [("eqpred", mk_eq_pred)] ("generating equality predicate for " ^ quote dtco) idf_eqpred
   605       |> succeed (Classinst ((class_eq, (dtco, arity)), ([], [(fun_eq, (idf_eqpred, inst_sortlookup))])), []);
   542       |> succeed (Classinst ((class_eq, (dtco, arity)), ([], [(fun_eq, (idf_eqpred, inst_sortlookup))])));
   606   in
   543   in
   607     trns
   544     trns
   608     |> gen_ensure_def [("eqinst", mk_eq_inst)] ("generating equality instance for " ^ quote dtco) idf_eqinst
   545     |> gen_ensure_def [("eqinst", mk_eq_inst)] ("generating equality instance for " ^ quote dtco) idf_eqinst
   609   end;
   546   end; *)
   610 
   547 
   611 
   548 
   612 (* expression generators *)
   549 (* expression generators *)
   613 
   550 
   614 fun exprgen_sort thy tabs sort trns =
   551 fun exprgen_tyvar_sort thy tabs (v, sort) trns =
   615   trns
   552   trns
   616   |> fold_map (ensure_def_class thy tabs) (ClassPackage.syntactic_sort_of thy sort)
   553   |> fold_map (ensure_def_class thy tabs) (ClassPackage.syntactic_sort_of thy sort)
   617   |-> (fn sort => pair sort);
   554   |-> (fn sort => pair (unprefix "'" v, sort));
   618 
   555 
   619 fun exprgen_type thy tabs (TVar _) trns =
   556 fun exprgen_type thy tabs (TVar _) trns =
   620       error "TVar encountered during code generation"
   557       error "TVar encountered during code generation"
   621   | exprgen_type thy tabs (TFree (v, sort)) trns =
   558   | exprgen_type thy tabs (TFree v_s) trns =
   622       trns
   559       trns
   623       |> exprgen_sort thy tabs sort
   560       |> exprgen_tyvar_sort thy tabs v_s
   624       |-> (fn sort => pair (IVarT (v |> unprefix "'", sort)))
   561       |-> (fn v_s => pair (IVarT v_s))
   625   | exprgen_type thy tabs (Type ("fun", [t1, t2])) trns =
   562   | exprgen_type thy tabs (Type ("fun", [t1, t2])) trns =
   626       trns
   563       trns
   627       |> exprgen_type thy tabs t1
   564       |> exprgen_type thy tabs t1
   628       ||>> exprgen_type thy tabs t2
   565       ||>> exprgen_type thy tabs t2
   629       |-> (fn (t1', t2') => pair (t1' `-> t2'))
   566       |-> (fn (t1', t2') => pair (t1' `-> t2'))
   642   | mk_lookup thy tabs (ClassPackage.Lookup (clss, (v, i))) trns =
   579   | mk_lookup thy tabs (ClassPackage.Lookup (clss, (v, i))) trns =
   643       trns
   580       trns
   644       |> fold_map (ensure_def_class thy tabs) clss
   581       |> fold_map (ensure_def_class thy tabs) clss
   645       |-> (fn clss => pair (ClassPackage.Lookup (clss, (v |> unprefix "'", i))));
   582       |-> (fn clss => pair (ClassPackage.Lookup (clss, (v |> unprefix "'", i))));
   646 
   583 
   647 fun mk_itapp e [] = e
   584 fun appgen_default thy tabs ((c, ty), ts) trns =
   648   | mk_itapp e lookup = IInst (e, lookup);
   585   trns
   649 
   586   |> ensure_def_const thy tabs (c, ty)
   650 fun appgen thy tabs ((f, ty), ts) trns =
   587   ||>> (fold_map o fold_map) (mk_lookup thy tabs)
       
   588     (ClassPackage.extract_sortlookup thy (c, ty))
       
   589   ||>> exprgen_type thy tabs ty
       
   590   ||>> fold_map (exprgen_term thy tabs) ts
       
   591   |-> (fn (((c, ls), ty), es) =>
       
   592          pair (Library.foldl IInst ((IConst (c, ty)), ls) `$$ es))
       
   593 and appgen thy tabs ((f, ty), ts) trns =
   651   case Symtab.lookup ((#appconst o #gens o CodegenData.get) thy) f
   594   case Symtab.lookup ((#appconst o #gens o CodegenData.get) thy) f
   652    of SOME ((imin, imax), (ag, _)) =>
   595    of SOME ((imin, imax), (ag, _)) =>
   653         let
   596         if length ts < imin then
   654           fun invoke ts trns =
       
   655             trns
       
   656             |> gen_invoke [("const application", ag thy tabs)] ("generating application " ^ f ^ "::" ^ (Sign.string_of_typ thy) ty
       
   657               ^ " " ^ enclose "(" ")" (commas (map (Sign.string_of_term thy) ts)))
       
   658               ((f, ty), ts)
       
   659         in if length ts < imin then
       
   660           let
   597           let
   661             val d = imin - length ts;
   598             val d = imin - length ts;
   662             val vs = Term.invent_names (add_term_names (Const (f, ty), [])) "x" d;
   599             val vs = Term.invent_names (add_term_names (Const (f, ty), [])) "x" d;
   663             val tys = Library.take (d, ((fst o strip_type) ty));
   600             val tys = Library.take (d, ((fst o strip_type) ty));
   664           in
   601           in
   665             trns
   602             trns
   666             |> debug 10 (fn _ => "eta-expanding")
   603             |> debug 10 (fn _ => "eta-expanding")
   667             |> fold_map (exprgen_type thy tabs) tys
   604             |> fold_map (exprgen_type thy tabs) tys
   668             ||>> invoke (ts @ map2 (curry Free) vs tys)
   605             ||>> ag thy tabs ((f, ty), ts @ map2 (curry Free) vs tys)
   669             |-> (fn (tys, e) => pair ((vs ~~ tys) `|--> e))
   606             |-> (fn (tys, e) => pair ((vs ~~ tys) `|--> e))
   670           end
   607           end
   671         else if length ts > imax then
   608         else if length ts > imax then
   672           trns
   609           trns
   673           |> debug 10 (fn _ => "splitting arguments (" ^ string_of_int imax ^ ", " ^ string_of_int (length ts) ^ ")")
   610           |> debug 10 (fn _ => "splitting arguments (" ^ string_of_int imax ^ ", " ^ string_of_int (length ts) ^ ")")
   674           |> invoke  (Library.take (imax, ts))
   611           |> ag thy tabs ((f, ty), Library.take (imax, ts))
   675           ||>> fold_map (exprgen_term thy tabs) (Library.drop (imax, ts))
   612           ||>> fold_map (exprgen_term thy tabs) (Library.drop (imax, ts))
   676           |-> (fn es => pair (mk_apps es))
   613           |-> (fn es => pair (mk_apps es))
   677         else
   614         else
   678           trns
   615           trns
   679           |> debug 10 (fn _ => "keeping arguments")
   616           |> debug 10 (fn _ => "keeping arguments")
   680           |> invoke ts
   617           |> ag thy tabs ((f, ty), ts)
   681         end
       
   682     | NONE =>
   618     | NONE =>
   683         trns
   619         trns
   684         |> ensure_def_const thy tabs (f, ty)
   620         |> appgen_default thy tabs ((f, ty), ts)
   685         ||>> (fold_map o fold_map) (mk_lookup thy tabs)
       
   686           (ClassPackage.extract_sortlookup thy (Sign.the_const_constraint thy f, ty))
       
   687         ||>> exprgen_type thy tabs ty
       
   688         ||>> fold_map (exprgen_term thy tabs) ts
       
   689         |-> (fn (((f, lookup), ty), es) =>
       
   690                pair (mk_itapp (IConst (f, ty)) lookup `$$ es))
       
   691 and exprgen_term thy tabs (Const (f, ty)) trns =
   621 and exprgen_term thy tabs (Const (f, ty)) trns =
   692       trns
   622       trns
   693       |> appgen thy tabs ((f, ty), [])
   623       |> appgen thy tabs ((f, ty), [])
   694       |-> (fn e => pair e)
   624       |-> (fn e => pair e)
   695   | exprgen_term thy tabs (Var ((v, i), ty)) trns =
   625   | exprgen_term thy tabs (Var ((v, i), ty)) trns =
   721       end;
   651       end;
   722 
   652 
   723 
   653 
   724 (* application generators *)
   654 (* application generators *)
   725 
   655 
   726 fun appgen_neg thy tabs (("neg", Type ("fun", [ty, _])), ts) trns =
   656 (* fun appgen_eq thy tabs (("op =", Type ("fun", [ty, _])), [t1, t2]) trns =
   727   trns
       
   728   |> exprgen_term thy tabs (Const ("op >", ty --> ty --> Type ("bool", [])) $ Const ("0", ty))
       
   729   |-> succeed;
       
   730 
       
   731 fun appgen_eq thy tabs (("op =", Type ("fun", [ty, _])), [t1, t2]) trns =
       
   732   trns
   657   trns
   733   |> invoke_eq (exprgen_type thy tabs) (ensure_def_eq thy tabs) ty
   658   |> invoke_eq (exprgen_type thy tabs) (ensure_def_eq thy tabs) ty
   734   |-> (fn false => error ("could not derive equality for " ^ Sign.string_of_typ thy ty)
   659   |-> (fn false => error ("could not derive equality for " ^ Sign.string_of_typ thy ty)
   735         | true => fn trns => trns
   660         | true => fn trns => trns
   736   |> exprgen_term thy tabs t1
   661   |> exprgen_term thy tabs t1
   737   ||>> exprgen_term thy tabs t2
   662   ||>> exprgen_term thy tabs t2
   738   |-> (fn (e1, e2) => succeed (Fun_eq `$ e1 `$ e2)));
   663   |-> (fn (e1, e2) => pair (Fun_eq `$ e1 `$ e2))); *)
       
   664 
       
   665 
       
   666 (* function extractors *)
       
   667 
       
   668 fun mk_fun thy tabs (c, ty) trns =
       
   669   case get_first (fn eqx => eqx (c, ty)) (get_eqextrs thy tabs)
       
   670    of SOME (eq_thms, ty) =>
       
   671         let
       
   672           val sortctxt = ClassPackage.extract_sortctxt thy ty;
       
   673           fun dest_eqthm eq_thm =
       
   674             eq_thm
       
   675             |> prop_of
       
   676             |> Logic.dest_equals
       
   677             |> apfst (strip_comb #> snd);
       
   678           fun mk_eq (args, rhs) trns =
       
   679             trns
       
   680             |> fold_map (exprgen_term thy tabs o devarify_term) args
       
   681             ||>> (exprgen_term thy tabs o devarify_term) rhs
       
   682             |-> (fn (args, rhs) => pair (map ipat_of_iexpr args, rhs))
       
   683         in
       
   684           trns
       
   685           |> fold_map (mk_eq o dest_eqthm) eq_thms
       
   686           ||>> exprgen_type thy tabs (devarify_type ty)
       
   687           ||>> fold_map (exprgen_tyvar_sort thy tabs) sortctxt
       
   688           |-> (fn ((eqs, ty), sortctxt) => (pair o SOME) (eqs, (sortctxt, ty)))
       
   689         end
       
   690     | NONE => (NONE, trns);
       
   691 
       
   692 fun eqextr_defs thy ((deftab, _), _) (c, ty) =
       
   693   let
       
   694     fun eq_typ (ty1, ty2) = 
       
   695       Sign.typ_instance thy (ty1, ty2)
       
   696       andalso Sign.typ_instance thy (ty2, ty1)
       
   697   in
       
   698     Option.mapPartial (get_first (fn (ty', thm) => if eq_typ (ty, ty')
       
   699       then SOME ([thm], ty')
       
   700       else NONE
       
   701     )) (Symtab.lookup deftab c)
       
   702   end;
   739 
   703 
   740 
   704 
   741 (* definition generators *)
   705 (* definition generators *)
   742 
   706 
   743 fun mk_fun thy tabs eqs ty trns =
   707 fun defgen_clsdecl thy (tabs as (_, (insttab, _, _))) cls trns =
   744   let
       
   745     val sortctxt = ClassPackage.extract_sortctxt thy ty;
       
   746     fun mk_sortvar (v, sort) trns =
       
   747       trns
       
   748       |> exprgen_sort thy tabs sort
       
   749       |-> (fn sort => pair (unprefix "'" v, sort))
       
   750     fun mk_eq (args, rhs) trns =
       
   751       trns
       
   752       |> fold_map (exprgen_term thy tabs o devarify_term) args
       
   753       ||>> (exprgen_term thy tabs o devarify_term) rhs
       
   754       |-> (fn (args, rhs) => pair (map ipat_of_iexpr args, rhs))
       
   755   in
       
   756     trns
       
   757     |> fold_map mk_eq eqs
       
   758     ||>> exprgen_type thy tabs (devarify_type ty)
       
   759     ||>> fold_map mk_sortvar sortctxt
       
   760     |-> (fn ((eqs, ty), sortctxt) => pair (Fun (eqs, (sortctxt, ty))))
       
   761   end;
       
   762 
       
   763 fun defgen_tyco_fallback thy tabs tyco trns =
       
   764   if Symtab.fold (fn (_, { syntax_tyco, ... }) => fn b => b orelse Symtab.defined syntax_tyco tyco)
       
   765     ((#serialize_data o CodegenData.get) thy) false
       
   766   then
       
   767     trns
       
   768     |> debug 5 (fn _ => "trying defgen tyco fallback for " ^ quote tyco)
       
   769     |> succeed (Nop, [])
       
   770   else
       
   771     trns
       
   772     |> fail ("no code generation fallback for " ^ quote tyco)
       
   773 
       
   774 fun defgen_const_fallback thy tabs c trns =
       
   775   if Symtab.fold (fn (_, { syntax_const, ... }) => fn b => b orelse Symtab.defined syntax_const c)
       
   776     ((#serialize_data o CodegenData.get) thy) false
       
   777   then
       
   778     trns
       
   779     |> debug 5 (fn _ => "trying defgen const fallback for " ^ quote c)
       
   780     |> succeed (Nop, [])
       
   781   else
       
   782     trns
       
   783     |> fail ("no code generation fallback for " ^ quote c)
       
   784 
       
   785 fun defgen_defs thy (tabs as ((deftab, _), _)) c trns =
       
   786   case Symtab.lookup deftab c
       
   787    of SOME (ty, (args, rhs)) =>
       
   788         trns
       
   789         |> debug 5 (fn _ => "trying defgen def for " ^ quote c)
       
   790         |> mk_fun thy tabs [(args, rhs)] (devarify_type ty)
       
   791         |-> (fn def => succeed (def, []))
       
   792       | _ => trns |> fail ("no definition found for " ^ quote c);
       
   793 
       
   794 fun defgen_clsdecl thy (tabs as (_, (insttab, _, _))) (cls : string) trns =
       
   795   case name_of_idf thy nsp_class cls
   708   case name_of_idf thy nsp_class cls
   796    of SOME cls =>
   709    of SOME cls =>
   797         let
   710         let
   798           val memnames = ClassPackage.the_consts thy (cls : string);
   711           val cs = (snd o ClassPackage.the_consts_sign thy) cls;
   799           val memtypes = map (devarify_type o ClassPackage.get_const_sign thy "'a") memnames;
   712           val sortctxts = map (ClassPackage.extract_sortctxt thy o snd) cs;
   800           val memctxt = map (ClassPackage.extract_sortctxt thy) memtypes;
   713           val idfs = map (idf_of_name thy nsp_mem o fst) cs;
   801           val memidfs = map (idf_of_name thy nsp_mem) memnames;
       
   802           fun mk_instname (tyco, thyname) = idf_of_name thy nsp_inst (InstNameMangler.get thy insttab (thyname, (cls, tyco)))
       
   803           val instnames = map mk_instname (ClassPackage.the_tycos thy cls);
       
   804         in
   714         in
   805           trns
   715           trns
   806           |> debug 5 (fn _ => "trying defgen class declaration for " ^ quote cls)
   716           |> debug 5 (fn _ => "trying defgen class declaration for " ^ quote cls)
   807           |> fold_map (ensure_def_class thy tabs) (ClassPackage.get_superclasses thy cls)
   717           |> fold_map (ensure_def_class thy tabs) (ClassPackage.the_superclasses thy cls)
   808           ||>> fold_map (exprgen_type thy tabs) memtypes
   718           ||>> fold_map (exprgen_type thy tabs o snd) cs
   809           |-> (fn (supcls, memtypes) => succeed (Class (supcls, "a", memidfs ~~ (memctxt ~~ memtypes), []),
   719           ||>> (fold_map o fold_map) (exprgen_tyvar_sort thy tabs) sortctxts
   810                  memidfs @ instnames))
   720           |-> (fn ((supcls, memtypes), sortctxts) => succeed
       
   721             (Class ((supcls, ("a", idfs ~~ (sortctxts ~~ memtypes))), [])))
   811         end
   722         end
   812     | _ =>
   723     | _ =>
   813         trns
   724         trns
   814         |> fail ("no class definition found for " ^ quote cls);
   725         |> fail ("no class definition found for " ^ quote cls);
       
   726 
       
   727 fun defgen_funs thy tabs c trns =
       
   728   case recconst_of_idf thy tabs c
       
   729    of SOME (c, ty) =>
       
   730         trns
       
   731         |> mk_fun thy tabs (c, ty)
       
   732         |-> (fn (SOME funn) => succeed (Fun funn)
       
   733               | NONE => fail ("no defining equations found for " ^ quote c))
       
   734     | NONE =>
       
   735         trns
       
   736         |> fail ("not a constant: " ^ quote c);
       
   737 
       
   738 fun defgen_datatypecons thy (tabs as (_, (_, _, dtcontab))) co trns =
       
   739   case Option.map (DatatypeconsNameMangler.rev thy dtcontab) (name_of_idf thy nsp_dtcon co)
       
   740    of SOME (co, dtco) =>
       
   741         trns
       
   742         |> debug 5 (fn _ => "trying defgen datatype constructor for " ^ quote co)
       
   743         |> ensure_def_tyco thy tabs dtco
       
   744         |-> (fn dtco => succeed Undef)
       
   745     | _ =>
       
   746         trns
       
   747         |> fail ("not a datatype constructor: " ^ quote co);
   815 
   748 
   816 fun defgen_clsmem thy tabs m trns =
   749 fun defgen_clsmem thy tabs m trns =
   817   case name_of_idf thy nsp_mem m
   750   case name_of_idf thy nsp_mem m
   818    of SOME m =>
   751    of SOME m =>
   819         trns
   752         trns
   820         |> debug 5 (fn _ => "trying defgen class member for " ^ quote m)
   753         |> debug 5 (fn _ => "trying defgen class member for " ^ quote m)
   821         |> ensure_def_class thy tabs ((the o ClassPackage.lookup_const_class thy) m)
   754         |> ensure_def_class thy tabs ((the o ClassPackage.lookup_const_class thy) m)
   822         |-> (fn cls => succeed (Classmember cls, []))
   755         |-> (fn cls => succeed Undef)
   823     | _ =>
   756     | _ =>
   824         trns |> fail ("no class member found for " ^ quote m)
   757         trns |> fail ("no class member found for " ^ quote m)
   825 
   758 
   826 fun defgen_clsinst thy (tabs as (_, (insttab, _, _))) inst trns =
   759 fun defgen_clsinst thy (tabs as (_, (insttab, _, _))) inst trns =
   827   case Option.map (InstNameMangler.rev thy insttab) (name_of_idf thy nsp_inst inst)
   760   case Option.map (InstNameMangler.rev thy insttab) (name_of_idf thy nsp_inst inst)
   828    of SOME (_, (cls, tyco)) =>
   761    of SOME (_, (cls, tyco)) =>
   829         let
   762         let
   830           val arity = ClassPackage.get_arities thy [cls] tyco;
   763           val (arity, memdefs) = ClassPackage.the_inst_sign thy (cls, tyco);
   831           val ms = map (fn m => (m, Sign.the_const_constraint thy m)) (ClassPackage.the_consts thy cls);
   764           fun gen_membr (m, ty) trns =
   832           val instmem_idfs = ClassPackage.get_inst_consts_sign thy (tyco, cls);
   765             trns
   833           val supclss = ClassPackage.get_superclasses thy cls;
   766             |> mk_fun thy tabs (m, ty)
   834           fun add_vars arity clsmems (trns as (_, modl)) =
   767             |-> (fn SOME funn => pair (m, funn)
   835             case get_def modl (idf_of_name thy nsp_class cls)
   768                   | NONE => error ("could not derive definition for member " ^ quote m));
   836              of Class (_, _, members, _) => ((Term.invent_names
       
   837               (tvars_of_itypes ((map (snd o snd)) members)) "a" (length arity) ~~ arity, clsmems), trns)
       
   838           val ad_hoc_arity = map (fn (v, sort) => map_index (fn (i, _) => (ClassPackage.Lookup ([], (v, i)))) sort);
       
   839           (*! THIS IS ACTUALLY VERY AD-HOC... !*)
       
   840         in
   769         in
   841           (trns
   770           trns
   842           |> debug 5 (fn _ => "trying defgen class instance for (" ^ quote cls ^ ", " ^ quote tyco ^ ")")
   771           |> debug 5 (fn _ => "trying defgen class instance for (" ^ quote cls ^ ", " ^ quote tyco ^ ")")
   843           |> (fold_map o fold_map) (ensure_def_class thy tabs) arity
   772           |> ensure_def_class thy tabs cls
   844           ||>> fold_map (ensure_def_const thy tabs) ms
       
   845           |-> (fn (arity, ms) => add_vars arity ms)
       
   846           ||>> ensure_def_class thy tabs cls
       
   847           ||>> ensure_def_tyco thy tabs tyco
   773           ||>> ensure_def_tyco thy tabs tyco
   848           ||>> fold_map (fn supcls => ensure_def_inst thy tabs (supcls, tyco)) supclss
   774           ||>> fold_map (exprgen_tyvar_sort thy tabs) arity
   849           ||>> fold_map (fn supcls => (fold_map o fold_map) (mk_lookup thy tabs)
   775           ||>> fold_map gen_membr memdefs
   850                  (ClassPackage.extract_sortlookup thy
   776           |-> (fn (((cls, tyco), arity), memdefs) =>
   851                    (Type (tyco, map_index (fn (i, _) => TVar (("'a", i), [])) (ClassPackage.get_arities thy [supcls] tyco)),
   777                  succeed (Classinst ((cls, (tyco, arity)), memdefs)))
   852                     Type (tyco, map_index (fn (i, sort) => TFree (string_of_int i, sort)) arity)))) supclss
       
   853           ||>> fold_map (ensure_def_const thy tabs) instmem_idfs)
       
   854           |-> (fn ((((((arity, ms), cls), tyco), supinsts), supinstlookup), instmem_idfs) 
       
   855                 : ((((((string * string list) list * string list) * string) * string)
       
   856                 * string list) * ClassPackage.sortlookup list list list) * string list
       
   857                 =>
       
   858                  succeed (Classinst ((cls, (tyco, arity)), (supclss ~~ (supinsts ~~ supinstlookup), ms ~~ map (rpair (ad_hoc_arity arity)) instmem_idfs)), [])) 
       
   859         end
   778         end
   860     | _ =>
   779     | _ =>
   861         trns |> fail ("no class instance found for " ^ quote inst);
   780         trns |> fail ("no class instance found for " ^ quote inst);
   862 
   781 
   863 
   782 
   864 (*    trns
       
   865     |> ensure_def_const thy tabs (f, ty)
       
   866 
       
   867     ||>> exprgen_type thy tabs ty
       
   868     ||>> fold_map (exprgen_term thy tabs) ts
       
   869     |-> (fn (((f, lookup), ty), es) =>
       
   870            succeed (mk_itapp (IConst (f, ty)) lookup `$$ es))*)
       
   871 
       
   872 
       
   873 (* parametrized generators, for instantiation in HOL *)
   783 (* parametrized generators, for instantiation in HOL *)
   874 
   784 
   875 fun appgen_let strip_abs thy tabs (c, [t2, t3]) trns =
   785 fun appgen_let strip_abs thy tabs ((c, ty), [t2, t3]) trns =
   876   let
   786   let
   877     fun dest_let (l as Const ("Let", _) $ t $ u) =
   787     fun dest_let (l as Const (c', _) $ t $ u) =
   878           (case strip_abs 1 u
   788           if c = c' then
   879            of ([p], u') => apfst (cons (p, t)) (dest_let u')
   789             case strip_abs 1 u
   880             | _ => ([], l))
   790              of ([p], u') => apfst (cons (p, t)) (dest_let u')
       
   791               | _ => ([], l)
       
   792           else ([], t)
   881       | dest_let t = ([], t);
   793       | dest_let t = ([], t);
   882     fun mk_let (l, r) trns =
   794     fun mk_let (l, r) trns =
   883       trns
   795       trns
   884       |> exprgen_term thy tabs l
   796       |> exprgen_term thy tabs l
   885       ||>> exprgen_term thy tabs r
   797       ||>> exprgen_term thy tabs r
   886       |-> (fn (l, r) => pair (r, ipat_of_iexpr l));
   798       |-> (fn (l, r) => pair (r, ipat_of_iexpr l));
   887     val (lets, body) = dest_let (Const c $ t2 $ t3)
   799     val (lets, body) = dest_let (Const (c, ty) $ t2 $ t3)
   888   in
   800   in
   889     trns
   801     trns
   890     |> fold_map mk_let lets
   802     |> fold_map mk_let lets
   891     ||>> exprgen_term thy tabs body
   803     ||>> exprgen_term thy tabs body
   892     |-> (fn (lets, body) =>
   804     |-> (fn (lets, body) =>
   893          succeed (Library.foldr (fn ((e, p), body) => ICase (e, [(p, body)])) (lets, body)))
   805          pair (Library.foldr (fn ((e, p), body) => ICase (e, [(p, body)])) (lets, body)))
   894   end
   806   end
   895 
   807 
   896 fun appgen_split strip_abs thy tabs (c, [t2]) trns =
   808 fun appgen_split strip_abs thy tabs (c, [t2]) trns =
   897   let
   809   let
   898     val ([p], body) = strip_abs 1 (Const c $ t2)
   810     val ([p], body) = strip_abs 1 (Const c $ t2)
   899   in
   811   in
   900     trns
   812     trns
   901     |> exprgen_term thy tabs p
   813     |> exprgen_term thy tabs p
   902     ||>> exprgen_term thy tabs body
   814     ||>> exprgen_term thy tabs body
   903     |-> (fn (IVarE v, body) => succeed (IAbs (v, body)))
   815     |-> (fn (IVarE v, body) => pair (IAbs (v, body)))
   904   end;
   816   end;
   905 
   817 
   906 fun appgen_number_of dest_binum mk_int_to_nat thy tabs (("Numeral.number_of",
   818 fun appgen_number_of mk_int_to_nat bin_to_int tyco_int tyco_nat thy tabs ((_,
   907       Type ("fun", [_, Type ("IntDef.int", [])])), [bin]) trns =
   819   Type (_, [_, ty as Type (tyco, [])])), [bin]) trns =
   908         trns
   820     if tyco = tyco_int then
   909         |> (succeed (IConst ((IntInf.toString o dest_binum) bin, Type_integer))
   821       trns
   910             handle TERM _
   822       |> exprgen_type thy tabs ty
   911             => error ("not a number: " ^ Sign.string_of_term thy bin))
   823       |-> (fn ty => pair (CodegenThingol.IConst ((IntInf.toString o bin_to_int) bin, ty)))
   912   | appgen_number_of dest_binum mk_int_to_nat thy tabs (("Numeral.number_of",
   824     else if tyco = tyco_nat then
   913       Type ("fun", [_, Type ("nat", [])])), [bin]) trns =
   825       trns
   914         trns
   826       |> exprgen_term thy tabs (mk_int_to_nat bin)
   915         |> exprgen_term thy tabs (mk_int_to_nat bin)
   827     else error ("invalid type constructor for numeral: " ^ quote tyco);
   916         |-> succeed;
       
   917 
   828 
   918 fun appgen_datatype_case cos thy tabs ((_, ty), ts) trns =
   829 fun appgen_datatype_case cos thy tabs ((_, ty), ts) trns =
   919   let
   830   let
   920     val (ts', t) = split_last ts;
   831     val (ts', t) = split_last ts;
   921     val (tys, dty) = (split_last o fst o strip_type) ty;
   832     val (tys, dty) = (split_last o fst o strip_type) ty;
   936       end;
   847       end;
   937   in
   848   in
   938     trns
   849     trns
   939     |> exprgen_term thy tabs t
   850     |> exprgen_term thy tabs t
   940     ||>> fold_map cg_case_d ((cos ~~ tys) ~~ ts')
   851     ||>> fold_map cg_case_d ((cos ~~ tys) ~~ ts')
   941     |-> (fn (t, ds) => succeed (ICase (t, ds)))
   852     |-> (fn (t, ds) => pair (ICase (t, ds)))
   942   end;
   853   end;
   943 
   854 
   944 fun gen_add_cg_case_const prep_c get_case_const_data raw_c thy =
   855 fun gen_add_case_const prep_c get_case_const_data raw_c thy =
   945   let
   856   let
   946     val c = prep_c thy raw_c;
   857     val c = prep_c thy raw_c;
   947     val (tys, dty) = (split_last o fst o strip_type o Sign.the_const_constraint thy) c;
   858     val (tys, dty) = (split_last o fst o strip_type o Sign.the_const_type thy) c;
   948     val cos = (the o get_case_const_data thy) c;
   859     val cos = (the o get_case_const_data thy) c;
   949     val n_eta = length cos + 1;
   860     val n_eta = length cos + 1;
   950   in
   861   in
   951     thy
   862     thy
   952     |> add_appconst_i (c, ((n_eta, n_eta), appgen_datatype_case cos))
   863     |> add_appconst_i (c, ((n_eta, n_eta), appgen_datatype_case cos))
   953   end;
   864   end;
   954 
   865 
   955 val add_cg_case_const = gen_add_cg_case_const Sign.intern_const;
   866 val add_case_const = gen_add_case_const Sign.intern_const;
   956 val add_cg_case_const_i = gen_add_cg_case_const (K I);
   867 val add_case_const_i = gen_add_case_const (K I);
   957 
   868 
   958 fun defgen_datatype get_datatype get_datacons thy (tabs as (_, (_, _, dtcontab))) dtco trns =
   869 fun defgen_datatype get_datatype get_datacons thy (tabs as (_, (_, _, dtcontab))) dtco trns =
   959   case name_of_idf thy nsp_tyco dtco
   870   case name_of_idf thy nsp_tyco dtco
   960    of SOME dtco =>
   871    of SOME dtco =>
   961         (case get_datatype thy dtco
   872         (case get_datatype thy dtco
   965                 val coidfs = map (fn co => (DatatypeconsNameMangler.get thy dtcontab (co, dtco)) |>
   876                 val coidfs = map (fn co => (DatatypeconsNameMangler.get thy dtcontab (co, dtco)) |>
   966                   idf_of_name thy nsp_dtcon) cos;
   877                   idf_of_name thy nsp_dtcon) cos;
   967               in
   878               in
   968                 trns
   879                 trns
   969                 |> debug 5 (fn _ => "trying defgen datatype for " ^ quote dtco)
   880                 |> debug 5 (fn _ => "trying defgen datatype for " ^ quote dtco)
   970                 |> fold_map (exprgen_sort thy tabs) (map snd vars)
   881                 |> fold_map (exprgen_tyvar_sort thy tabs) vars
   971                 ||>> (fold_map o fold_map) (exprgen_type thy tabs o devarify_type) cotys
   882                 ||>> (fold_map o fold_map) (exprgen_type thy tabs o devarify_type) cotys
   972                 |-> (fn (sorts, tys) => succeed (Datatype
   883                 |-> (fn (sorts, tys) => succeed (Datatype
   973                      (map2 (fn (v, _) => fn sort => (unprefix "'" v, sort)) vars sorts, coidfs ~~ tys, []),
   884                      ((sorts, coidfs ~~ tys), [])))
   974                      coidfs))
       
   975               end
   885               end
   976           | NONE =>
   886           | NONE =>
   977               trns
   887               trns
   978               |> fail ("no datatype found for " ^ quote dtco))
   888               |> fail ("no datatype found for " ^ quote dtco))
   979     | NONE =>
   889     | NONE =>
   980         trns
   890         trns
   981         |> fail ("not a type constructor: " ^ quote dtco)
   891         |> fail ("not a type constructor: " ^ quote dtco)
   982 
   892 
   983 fun defgen_datacons get_datacons thy (tabs as (_, (_, _, dtcontab))) co trns =
       
   984   case Option.map (DatatypeconsNameMangler.rev thy dtcontab) (name_of_idf thy nsp_dtcon co)
       
   985    of SOME (co, dtco) =>
       
   986         trns
       
   987         |> debug 5 (fn _ => "trying defgen datatype constructor for " ^ quote co)
       
   988         |> ensure_def_tyco thy tabs dtco
       
   989         ||>> fold_map (exprgen_type thy tabs) ((the o get_datacons thy) (co, dtco))
       
   990         |-> (fn (tyco, _) => succeed (Datatypecons tyco, []))
       
   991     | _ =>
       
   992         trns
       
   993         |> fail ("not a datatype constructor: " ^ quote co);
       
   994 
       
   995 fun defgen_recfun get_equations thy tabs c trns =
       
   996   case recconst_of_idf thy tabs c
       
   997    of SOME (c, ty) =>
       
   998         let
       
   999           val (eqs, ty) = get_equations thy (c, ty);
       
  1000         in
       
  1001           case eqs
       
  1002            of (_::_) =>
       
  1003                 trns
       
  1004                 |> debug 5 (fn _ => "trying defgen recfun for " ^ quote c)
       
  1005                 |> mk_fun thy tabs eqs (devarify_type ty)
       
  1006                 |-> (fn def => succeed (def, []))
       
  1007             | _ =>
       
  1008                 trns
       
  1009                 |> fail ("no recursive definition found for " ^ quote c)
       
  1010         end
       
  1011     | NONE =>
       
  1012         trns
       
  1013         |> fail ("not a constant: " ^ quote c);
       
  1014 
       
  1015 
   893 
  1016 
   894 
  1017 (** theory interface **)
   895 (** theory interface **)
  1018 
   896 
  1019 fun mk_tabs thy =
   897 fun mk_tabs thy =
  1020   let
   898   let
  1021     fun extract_defs thy =
   899     fun extract_defs thy =
  1022       let
   900       let
  1023         fun dest t =
   901         fun dest tm =
  1024           let
   902           let
  1025             val (lhs, rhs) = Logic.dest_equals t;
   903             val (lhs, rhs) = Logic.dest_equals (prop_of tm);
  1026             val (c, args) = strip_comb lhs;
   904             val (t, args) = strip_comb lhs;
  1027             val (s, T) = dest_Const c
   905             val (c, ty) = dest_Const t
  1028           in if forall is_Var args then SOME (s, (T, (args, rhs))) else NONE
   906           in if forall is_Var args then SOME ((c, ty), tm) else NONE
  1029           end handle TERM _ => NONE;
   907           end handle TERM _ => NONE;
  1030         fun prep_def def = (case Codegen.preprocess thy [def] of
   908         fun prep_def def = (case Codegen.preprocess thy [def] of
  1031           [def'] => prop_of def' | _ => error "mk_auxtab: bad preprocessor");
   909           [def'] => def' | _ => error "mk_auxtab: bad preprocessor");
  1032         fun add_def (name, t) defs = (case dest t of
   910         fun add_def (name, _) =
  1033             NONE => defs
   911           case (dest o prep_def o Thm.get_axiom thy) name
  1034           | SOME _ => (case (dest o prep_def oo Thm.get_axiom) thy name of
   912            of SOME ((c, ty), tm) =>
  1035               NONE => defs
   913                 Symtab.default (c, []) #> Symtab.map_entry c (cons (ty, tm))
  1036             | SOME (s, (T, (args, rhs))) => Symtab.update
   914             | NONE => I
  1037                 (s, (T, (split_last (args @ [rhs]))) ::
       
  1038                 if_none (Symtab.lookup defs s) []) defs))
       
  1039       in
   915       in
  1040         Symtab.empty
   916         Symtab.empty
  1041         |> fold (Symtab.fold add_def) (map
   917         |> fold (Symtab.fold add_def o snd o #axioms o Theory.rep_theory)
  1042              (snd o #axioms o Theory.rep_theory) (thy :: Theory.ancestors_of thy))
   918              (thy :: Theory.ancestors_of thy)
  1043       end;
   919       end;
  1044     fun mk_insttab thy =
   920     fun mk_insttab thy =
  1045       InstNameMangler.empty
   921       InstNameMangler.empty
  1046       |> Symtab.fold_map
   922       |> Symtab.fold_map
  1047           (fn (cls, (_, clsinsts)) => fold_map
   923           (fn (cls, (clsmems, clsinsts)) => fold_map
  1048             (fn (tyco, thyname) => InstNameMangler.declare thy (thyname, (cls, tyco))) clsinsts)
   924             (fn (tyco, thyname) => InstNameMangler.declare thy (thyname, (cls, tyco))) clsinsts)
  1049                  (ClassPackage.get_classtab thy)
   925                  (ClassPackage.get_classtab thy)
  1050       |-> (fn _ => I);
   926       |-> (fn _ => I);
  1051     fun mk_overltabs thy defs =
   927     fun mk_overltabs thy deftab =
  1052       (Symtab.empty, ConstNameMangler.empty)
   928       (Symtab.empty, ConstNameMangler.empty)
  1053       |> Symtab.fold
   929       |> Symtab.fold
  1054           (fn (c, [_]) => I
   930           (fn (c, [_]) => I
  1055             | ("0", _) => I
       
  1056             | (c, tytab) =>
   931             | (c, tytab) =>
  1057                 (fn (overltab1, overltab2) => (
   932                 (fn (overltab1, overltab2) => (
  1058                   overltab1
   933                   overltab1
  1059                   |> Symtab.update_new (c, (Sign.the_const_constraint thy c, map fst tytab)),
   934                   |> Symtab.update_new (c, (Sign.the_const_constraint thy c, map fst tytab)),
  1060                   overltab2
   935                   overltab2
  1061                   |> fold (fn (ty, _) => ConstNameMangler.declare thy (idf_of_name thy nsp_overl c, (Sign.the_const_constraint thy c, ty)) #> snd) tytab
   936                   |> fold (fn (ty, _) => ConstNameMangler.declare thy (idf_of_name thy nsp_overl c, (Sign.the_const_constraint thy c, ty)) #> snd) tytab
  1062                 ))) defs;
   937                 ))) deftab;
  1063     fun mk_dtcontab thy =
   938     fun mk_dtcontab thy =
  1064       DatatypeconsNameMangler.empty
   939       DatatypeconsNameMangler.empty
  1065       |> fold_map
   940       |> fold_map
  1066           (fn (_, co_dtco) => DatatypeconsNameMangler.declare_multi thy co_dtco)
   941           (fn (_, co_dtco) => DatatypeconsNameMangler.declare_multi thy co_dtco)
  1067             (fold (fn (co, dtco) =>
   942             (fold (fn (co, dtco) =>
  1068               let
   943               let
  1069                 val key = ((NameSpace.drop_base o NameSpace.drop_base) co, NameSpace.base co)
   944                 val key = ((NameSpace.drop_base o NameSpace.drop_base) co, NameSpace.base co)
  1070               in AList.default (op =) (key, []) #> AList.map_entry (op =) key (cons (co, dtco)) end
   945               in AList.default (op =) (key, []) #> AList.map_entry (op =) key (cons (co, dtco)) end
  1071             ) (get_all_datatype_cons thy) [])
   946             ) (get_all_datatype_cons thy) [])
  1072       |-> (fn _ => I);
   947       |-> (fn _ => I);
  1073     fun mk_deftab thy defs overltab =
       
  1074       Symtab.empty
       
  1075       |> Symtab.fold
       
  1076           (fn (c, [ty_cdef]) =>
       
  1077                 Symtab.update_new (idf_of_name thy nsp_const c, ty_cdef)
       
  1078             | ("0", _) => I
       
  1079             | (c, cdefs) => fold (fn (ty, cdef) =>
       
  1080                 let
       
  1081                   val c' = ConstNameMangler.get thy overltab
       
  1082                     (idf_of_name thy nsp_overl c, (Sign.the_const_constraint thy c, ty))
       
  1083                 in Symtab.update_new (c', (ty, cdef)) end) cdefs) defs;
       
  1084     fun mk_clsmemtab thy =
   948     fun mk_clsmemtab thy =
  1085       Symtab.empty
   949       Symtab.empty
  1086       |> Symtab.fold
   950       |> Symtab.fold
  1087           (fn (class, (clsmems, _)) => fold
   951           (fn (class, (clsmems, _)) => fold
  1088             (fn clsmem => Symtab.update (clsmem, class)) clsmems)
   952             (fn clsmem => Symtab.update (clsmem, class)) clsmems)
  1089               (ClassPackage.get_classtab thy);
   953               (ClassPackage.get_classtab thy);
  1090     val defs = extract_defs thy;
   954     val deftab = extract_defs thy;
  1091     val insttab = mk_insttab thy;
   955     val insttab = mk_insttab thy;
  1092     val overltabs = mk_overltabs thy defs;
   956     val overltabs = mk_overltabs thy deftab;
  1093     val dtcontab = mk_dtcontab thy;
   957     val dtcontab = mk_dtcontab thy;
  1094     val deftab = mk_deftab thy defs (snd overltabs);
       
  1095     val clsmemtab = mk_clsmemtab thy;
   958     val clsmemtab = mk_clsmemtab thy;
  1096   in ((deftab, clsmemtab), (insttab, overltabs, dtcontab)) end;
   959   in ((deftab, clsmemtab), (insttab, overltabs, dtcontab)) end;
  1097 
   960 
  1098 fun check_for_serializer serial_name serialize_data =
   961 fun check_for_target thy target =
  1099   if Symtab.defined serialize_data serial_name
   962   if (Symtab.defined o #target_data o CodegenData.get) thy target
  1100   then serialize_data
   963   then ()
  1101   else error ("unknown code serializer: " ^ quote serial_name);
   964   else error ("unknown code target language: " ^ quote target);
  1102 
   965 
  1103 fun map_module f =
   966 fun map_module f =
  1104   map_codegen_data (fn (modl, gens, lookups, serialize_data, logic_data) =>
   967   map_codegen_data (fn (modl, gens, target_data, logic_data) =>
  1105     (f modl, gens, lookups, serialize_data, logic_data));
   968     (f modl, gens, target_data, logic_data));
  1106 
   969 
  1107 fun expand_module defs gen thy =
   970 fun expand_module gen thy =
  1108   (#modl o CodegenData.get) thy
   971   (#modl o CodegenData.get) thy
  1109   |> start_transact (gen thy defs)
   972   |> start_transact (gen thy (mk_tabs thy))
  1110   |-> (fn x:'a => fn modl => (x, map_module (K modl) thy));
   973   |-> (fn x:'a => fn modl => (x, map_module (K modl) thy));
  1111 
   974 
  1112 fun rename_inconsistent thy =
   975 fun rename_inconsistent thy =
  1113   let
   976   let
  1114     fun get_inconsistent thyname =
   977     fun get_inconsistent thyname =
  1139       if
  1002       if
  1140         Symtab.defined ((#appconst o #gens o CodegenData.get) thy) case_c
  1003         Symtab.defined ((#appconst o #gens o CodegenData.get) thy) case_c
  1141       then
  1004       then
  1142         (warning ("case constant " ^ quote case_c ^ " already present in application table, will not overwrite"); thy)
  1005         (warning ("case constant " ^ quote case_c ^ " already present in application table, will not overwrite"); thy)
  1143       else
  1006       else
  1144         add_cg_case_const_i get_case_const_data case_c thy;
  1007         add_case_const_i get_case_const_data case_c thy;
  1145   in
  1008   in
  1146     fold ensure (get_datatype_case_consts thy) thy
  1009     fold ensure (get_datatype_case_consts thy) thy
  1147   end;
  1010   end;
  1148 
  1011 
  1149 
  1012 
  1150 
  1013 
  1151 (** target languages **)
  1014 (** target languages **)
  1152 
  1015 
  1153 (* primitive definitions *)
  1016 (* primitive definitions *)
  1154 
  1017 
       
  1018 fun read_typ thy =
       
  1019   Sign.read_typ (thy, K NONE);
       
  1020 
  1155 fun read_const thy (raw_c, raw_ty) =
  1021 fun read_const thy (raw_c, raw_ty) =
  1156   let
  1022   let
  1157     val c = Sign.intern_const thy raw_c;
  1023     val c = Sign.intern_const thy raw_c;
       
  1024     val _ = if Sign.declared_const thy c
       
  1025       then ()
       
  1026       else error ("no such constant: " ^ quote c);
  1158     val ty = case raw_ty
  1027     val ty = case raw_ty
  1159      of NONE => Sign.the_const_constraint thy c
  1028      of NONE => Sign.the_const_constraint thy c
  1160       | SOME raw_ty => Sign.read_typ (thy, K NONE) raw_ty;
  1029       | SOME raw_ty => read_typ thy raw_ty;
  1161   in (c, ty) end;
  1030   in (c, ty) end;
  1162 
  1031 
       
  1032 fun read_quote reader gen raw thy =
       
  1033   expand_module
       
  1034     (fn thy => fn tabs => gen thy tabs (reader thy raw))
       
  1035     thy;
       
  1036 
  1163 fun gen_add_prim prep_name prep_primdef raw_name deps (target, raw_primdef) thy =
  1037 fun gen_add_prim prep_name prep_primdef raw_name deps (target, raw_primdef) thy =
  1164   let
  1038   let
  1165     val _ = if Symtab.defined ((#serialize_data o CodegenData.get) thy) target
  1039     val _ = if Symtab.defined ((#target_data o CodegenData.get) thy) target
  1166       then () else error ("unknown target language: " ^ quote target);
  1040       then () else error ("unknown target language: " ^ quote target);
  1167     val tabs = mk_tabs thy;
  1041     val tabs = mk_tabs thy;
  1168     val name = prep_name thy tabs raw_name;
  1042     val name = prep_name thy tabs raw_name;
  1169     val primdef = prep_primdef raw_primdef;
  1043     val primdef = prep_primdef raw_primdef;
  1170   in
  1044   in
  1173   end;
  1047   end;
  1174 
  1048 
  1175 val add_prim_i = gen_add_prim ((K o K) I) I;
  1049 val add_prim_i = gen_add_prim ((K o K) I) I;
  1176 val add_prim_class = gen_add_prim
  1050 val add_prim_class = gen_add_prim
  1177   (fn thy => K (idf_of_name thy nsp_class o Sign.intern_class thy))
  1051   (fn thy => K (idf_of_name thy nsp_class o Sign.intern_class thy))
  1178   (Pretty.str o newline_correct o Symbol.strip_blanks);
  1052   (Pretty.str o CodegenSerializer.parse_targetdef I);
  1179 val add_prim_tyco = gen_add_prim
  1053 val add_prim_tyco = gen_add_prim
  1180   (fn thy => K (idf_of_name thy nsp_tyco o Sign.intern_type thy))
  1054   (fn thy => K (idf_of_name thy nsp_tyco o Sign.intern_type thy))
  1181   (Pretty.str o newline_correct o Symbol.strip_blanks);
  1055   (Pretty.str o CodegenSerializer.parse_targetdef I);
  1182 val add_prim_const = gen_add_prim
  1056 val add_prim_const = gen_add_prim
  1183   (fn thy => fn tabs => idf_of_const thy tabs o read_const thy)
  1057   (fn thy => fn tabs => idf_of_const thy tabs o read_const thy)
  1184   (Pretty.str o newline_correct o Symbol.strip_blanks);
  1058   (Pretty.str o CodegenSerializer.parse_targetdef I);
  1185 
  1059 
  1186 val ensure_prim = (map_module o CodegenThingol.ensure_prim);
  1060 val ensure_prim = (map_module oo CodegenThingol.ensure_prim);
  1187 
  1061 
  1188 
  1062 
  1189 (* syntax *)
  1063 (* syntax *)
  1190 
  1064 
  1191 fun gen_prep_mfx read_quote mk_quote tabs mfx thy =
  1065 val parse_syntax_tyco =
  1192   let
  1066   let
  1193     val proto_mfx = Codegen.parse_mixfix (read_quote thy) mfx;
  1067     fun mk reader raw_tyco target thy =
  1194     fun generate thy tabs = fold_map (mk_quote thy tabs)
  1068       let
  1195       (Codegen.quotes_of proto_mfx);
  1069         val _ = check_for_target thy target;
       
  1070         fun check_tyco tyco =
       
  1071           if Sign.declared_tyname thy tyco
       
  1072           then tyco
       
  1073           else error ("no such type constructor: " ^ quote tyco);
       
  1074         fun prep_tyco thy tyco =
       
  1075           tyco
       
  1076           |> Sign.intern_type thy
       
  1077           |> check_tyco
       
  1078           |> idf_of_name thy nsp_tyco;
       
  1079         val tyco = prep_tyco thy raw_tyco;
       
  1080       in
       
  1081         thy
       
  1082         |> ensure_prim tyco target
       
  1083         |> reader
       
  1084         |-> (fn pretty => map_codegen_data
       
  1085           (fn (modl, gens, target_data, logic_data) =>
       
  1086              (modl, gens,
       
  1087               target_data |> Symtab.map_entry target
       
  1088                 (map_target_data
       
  1089                   (fn (syntax_tyco, syntax_const) =>
       
  1090                    (syntax_tyco |> Symtab.update_new
       
  1091                       (tyco, (pretty, stamp ())),
       
  1092                     syntax_const))),
       
  1093               logic_data)))
       
  1094       end;
       
  1095   in
       
  1096     CodegenSerializer.parse_syntax (read_quote read_typ exprgen_type)
       
  1097     #-> (fn reader => pair (mk reader))
       
  1098   end;
       
  1099 
       
  1100 val parse_syntax_const =
       
  1101   let
       
  1102     fun mk reader raw_const target thy =
       
  1103       let
       
  1104         val _ = check_for_target thy target;
       
  1105         val tabs = mk_tabs thy;
       
  1106         val c = idf_of_const thy tabs (read_const thy raw_const);
       
  1107       in
       
  1108         thy
       
  1109         |> ensure_prim c target
       
  1110         |> reader
       
  1111         |-> (fn pretty => map_codegen_data
       
  1112           (fn (modl, gens, target_data, logic_data) =>
       
  1113              (modl, gens,
       
  1114               target_data |> Symtab.map_entry target
       
  1115                 (map_target_data
       
  1116                   (fn (syntax_tyco, syntax_const) =>
       
  1117                    (syntax_tyco,
       
  1118                     syntax_const
       
  1119                     |> Symtab.update_new
       
  1120                        (c, (pretty, stamp ()))))),
       
  1121               logic_data)))
       
  1122       end;
       
  1123   in
       
  1124     CodegenSerializer.parse_syntax (read_quote Sign.read_term exprgen_term)
       
  1125     #-> (fn reader => pair (mk reader))
       
  1126   end;
       
  1127 
       
  1128 
       
  1129 
       
  1130 (** code generation **)
       
  1131 
       
  1132 fun generate_code raw_consts thy =
       
  1133   let
       
  1134     val consts = map (read_const thy) raw_consts;
       
  1135     fun generate thy tabs = fold_map (ensure_def_const thy tabs) consts
  1196   in
  1136   in
  1197     thy
  1137     thy
  1198     |> expand_module tabs generate
  1138     |> expand_module generate
  1199     |-> (fn tys => pair (Codegen.replace_quotes tys proto_mfx))
  1139   end;
  1200   end;
  1140 
  1201 
  1141 fun serialize_code target filename raw_consts thy =
  1202 fun gen_add_syntax_tyco prep_tyco prep_mfx raw_tyco (serial_name, (raw_mfx, fixity)) thy =
  1142   let
  1203   let
  1143     fun get_serializer thy target =
  1204     val tyco = prep_tyco thy raw_tyco;
  1144       let
  1205     val tabs = mk_tabs thy;
  1145         val _ = check_for_target thy target;
  1206   in
  1146         val target_data =
  1207     thy
  1147           thy
  1208     |> ensure_prim tyco
  1148           |> CodegenData.get
  1209     |> prep_mfx tabs raw_mfx
  1149           |> #target_data
  1210     |-> (fn mfx => map_codegen_data
  1150           |> (fn data => (the oo Symtab.lookup) data target);
  1211       (fn (modl, gens, lookups, serialize_data, logic_data) =>
  1151       in
  1212          (modl, gens, lookups,
  1152         (the o Symtab.lookup (! serializers)) target (
  1213           serialize_data |> check_for_serializer serial_name |> Symtab.map_entry serial_name
  1153           (Option.map fst oo Symtab.lookup o #syntax_tyco) target_data,
  1214             (map_serialize_data
  1154           (Option.map fst oo Symtab.lookup o #syntax_const) target_data
  1215               (fn (syntax_tyco, syntax_const) =>
  1155         )
  1216                (syntax_tyco |> Symtab.update_new
  1156       end;
  1217                   (tyco,
       
  1218                    (((Codegen.num_args_of mfx, fixity), Codegen.fillin_mixfix mfx), stamp ())),
       
  1219                 syntax_const))),
       
  1220           logic_data)))
       
  1221   end;
       
  1222 
       
  1223 val add_syntax_tyco_i = gen_add_syntax_tyco (K I) (K pair);
       
  1224 val add_syntax_tyco = gen_add_syntax_tyco
       
  1225   (fn thy => idf_of_name thy nsp_tyco o Sign.intern_type thy)
       
  1226   (gen_prep_mfx (fn thy => typ_of o read_ctyp thy)
       
  1227     (fn thy => fn tabs => exprgen_type thy tabs o devarify_type));
       
  1228 
       
  1229 fun gen_add_syntax_const prep_const prep_mfx raw_c (serial_name, (raw_mfx, fixity)) thy =
       
  1230   let
       
  1231     val tabs = mk_tabs thy;
       
  1232     val c = prep_const thy tabs raw_c;
       
  1233   in
       
  1234     thy
       
  1235     |> ensure_prim c
       
  1236     |> prep_mfx tabs raw_mfx
       
  1237     |-> (fn mfx => map_codegen_data
       
  1238       (fn (modl, gens, lookups, serialize_data, logic_data) =>
       
  1239          (modl, gens, lookups,
       
  1240           serialize_data |> check_for_serializer serial_name |> Symtab.map_entry serial_name
       
  1241             (map_serialize_data
       
  1242               (fn (syntax_tyco, syntax_const) =>
       
  1243                (syntax_tyco,
       
  1244                 syntax_const |> Symtab.update_new
       
  1245                   (c,
       
  1246                     (((Codegen.num_args_of mfx, fixity), Codegen.fillin_mixfix mfx), stamp ()))))),
       
  1247           logic_data)))
       
  1248   end;
       
  1249 
       
  1250 val add_syntax_const_i = gen_add_syntax_const ((K o K) I) (K pair);
       
  1251 val add_syntax_const = gen_add_syntax_const
       
  1252   (fn thy => fn tabs => idf_of_const thy tabs o read_const thy)
       
  1253   (gen_prep_mfx (fn thy => term_of o read_cterm thy o rpair TypeInfer.logicT)
       
  1254     (fn thy => fn tabs => exprgen_term thy tabs o devarify_term));
       
  1255 
       
  1256 
       
  1257 
       
  1258 (** code generation **)
       
  1259 
       
  1260 fun get_serializer thy serial_name =
       
  1261   (#serializer o (fn data => (the oo Symtab.lookup) data serial_name)
       
  1262     o #serialize_data o CodegenData.get) thy;
       
  1263 
       
  1264 fun mk_const thy (f, s_ty) =
       
  1265   let
       
  1266     val f' = Sign.intern_const thy f;
       
  1267     val ty = case s_ty
       
  1268      of NONE => Sign.the_const_constraint thy f'
       
  1269       | SOME s => Sign.read_typ (thy, K NONE) s;
       
  1270   in (f', ty) end;
       
  1271 
       
  1272 fun generate_code consts thy =
       
  1273   let
       
  1274     val tabs = mk_tabs thy;
       
  1275     val consts' = map (mk_const thy) consts;
       
  1276     fun generate thy tabs = fold_map (ensure_def_const thy tabs) consts'
       
  1277   in
       
  1278     thy
       
  1279     |> expand_module tabs generate
       
  1280     |-> (fn consts => pair consts)
       
  1281   end;
       
  1282 
       
  1283 fun serialize_code serial_name filename consts thy =
       
  1284   let
       
  1285     val serialize_data =
       
  1286       thy
       
  1287       |> CodegenData.get
       
  1288       |> #serialize_data
       
  1289       |> check_for_serializer serial_name
       
  1290       |> (fn data => (the oo Symtab.lookup) data serial_name)
       
  1291     val serializer' = (get_serializer thy serial_name) serial_name
       
  1292       ((Option.map fst oo Symtab.lookup o #syntax_tyco) serialize_data)
       
  1293       ((Option.map fst oo Symtab.lookup o #syntax_const) serialize_data);
       
  1294     val compile_it = serial_name = "ml" andalso filename = "-";
       
  1295     fun use_code code =
  1157     fun use_code code =
  1296       if compile_it
  1158       if target = "ml" andalso filename = "-"
  1297       then use_text Context.ml_output false code
  1159       then use_text Context.ml_output false code
  1298       else File.write (Path.unpack filename) (code ^ "\n");
  1160       else File.write (Path.unpack filename) (code ^ "\n");
       
  1161     fun serialize thy cs =
       
  1162       let
       
  1163         val module = (#modl o CodegenData.get) thy;
       
  1164         val seri = get_serializer thy target "Generated";
       
  1165       in case cs
       
  1166        of [] => seri NONE module () |> fst |> Pretty.output |> use_code
       
  1167         | cs => seri (SOME cs) module () |> fst |> Pretty.output |> use_code
       
  1168       end;
  1299   in
  1169   in
  1300     thy
  1170     thy
  1301     |> (if is_some consts then generate_code (the consts) else pair [])
  1171     |> (if is_some raw_consts then generate_code (the raw_consts) else pair [])
  1302     |-> (fn [] => `(serializer' NONE o #modl o CodegenData.get)
  1172     |-> (fn cs => `(fn thy => serialize thy cs))
  1303           | consts => `(serializer' (SOME consts) o #modl o CodegenData.get))
  1173     |-> (fn _ => I)
  1304     |-> (fn code => ((use_code o Pretty.output) code; I))
       
  1305   end;
  1174   end;
  1306 
  1175 
  1307 
  1176 
  1308 
  1177 
  1309 (** toplevel interface **)
  1178 (** toplevel interface **)
  1345     -- P.name
  1214     -- P.name
  1346     -- Scan.option (
  1215     -- Scan.option (
  1347          P.$$$ constantsK
  1216          P.$$$ constantsK
  1348          |-- Scan.repeat1 (P.name -- Scan.option (P.$$$ "::" |-- P.typ))
  1217          |-- Scan.repeat1 (P.name -- Scan.option (P.$$$ "::" |-- P.typ))
  1349        )
  1218        )
  1350     >> (fn ((serial_name, filename), consts) =>
  1219     >> (fn ((target, filename), raw_consts) =>
  1351           Toplevel.theory (serialize_code serial_name filename consts))
  1220           Toplevel.theory (serialize_code target filename raw_consts))
  1352   );
  1221   );
  1353 
  1222 
  1354 val aliasP =
  1223 val aliasP =
  1355   OuterSyntax.command aliasK "declare an alias for a theory identifier" K.thy_decl (
  1224   OuterSyntax.command aliasK "declare an alias for a theory identifier" K.thy_decl (
  1356     P.xname
  1225     Scan.repeat1 (P.name -- P.name)
  1357     -- P.xname
  1226       >> (Toplevel.theory oo fold) add_alias
  1358       >> (fn (src, dst) => Toplevel.theory (add_alias (src, dst)))
       
  1359   );
  1227   );
  1360 
  1228 
  1361 val primclassP =
  1229 val primclassP =
  1362   OuterSyntax.command primclassK "define target-lanugage specific class" K.thy_decl (
  1230   OuterSyntax.command primclassK "define target-lanugage specific class" K.thy_decl (
  1363     P.xname
  1231     P.xname
       
  1232     -- Scan.optional (P.$$$ dependingK |--
       
  1233          P.$$$ "(" |-- P.list1 P.name --| P.$$$ ")") []
  1364     -- Scan.repeat1 (P.name -- P.text)
  1234     -- Scan.repeat1 (P.name -- P.text)
  1365     -- Scan.optional (P.$$$ dependingK |-- Scan.repeat1 P.name) []
  1235       >> (fn ((raw_class, depends), primdefs) =>
  1366       >> (fn ((raw_class, primdefs), depends) =>
       
  1367             (Toplevel.theory oo fold) (add_prim_class raw_class depends) primdefs)
  1236             (Toplevel.theory oo fold) (add_prim_class raw_class depends) primdefs)
  1368   );
  1237   );
  1369 
  1238 
  1370 val primtycoP =
  1239 val primtycoP =
  1371   OuterSyntax.command primtycoK "define target-lanugage specific type constructor" K.thy_decl (
  1240   OuterSyntax.command primtycoK "define target-lanugage specific type constructor" K.thy_decl (
  1372     P.xname
  1241     P.xname
       
  1242     -- Scan.optional (P.$$$ dependingK |--
       
  1243          P.$$$ "(" |-- P.list1 P.name --| P.$$$ ")") []
  1373     -- Scan.repeat1 (P.name -- P.text)
  1244     -- Scan.repeat1 (P.name -- P.text)
  1374     -- Scan.optional (P.$$$ dependingK |-- Scan.repeat1 P.name) []
  1245       >> (fn ((raw_tyco, depends), primdefs) =>
  1375       >> (fn ((raw_tyco, primdefs), depends) =>
       
  1376             (Toplevel.theory oo fold) (add_prim_tyco raw_tyco depends) primdefs)
  1246             (Toplevel.theory oo fold) (add_prim_tyco raw_tyco depends) primdefs)
  1377   );
  1247   );
  1378 
  1248 
  1379 val primconstP =
  1249 val primconstP =
  1380   OuterSyntax.command primconstK "define target-lanugage specific constant" K.thy_decl (
  1250   OuterSyntax.command primconstK "define target-lanugage specific constant" K.thy_decl (
  1381     (P.xname -- Scan.option P.typ)
  1251     (P.xname -- Scan.option (P.$$$ "::" |-- P.typ))
       
  1252     -- Scan.optional (P.$$$ dependingK |--
       
  1253          P.$$$ "(" |-- P.list1 P.name --| P.$$$ ")") []
  1382     -- Scan.repeat1 (P.name -- P.text)
  1254     -- Scan.repeat1 (P.name -- P.text)
  1383     -- Scan.optional (P.$$$ dependingK |-- Scan.repeat1 P.name) []
  1255       >> (fn ((raw_const, depends), primdefs) =>
  1384       >> (fn ((raw_const, primdefs), depends) =>
       
  1385             (Toplevel.theory oo fold) (add_prim_const raw_const depends) primdefs)
  1256             (Toplevel.theory oo fold) (add_prim_const raw_const depends) primdefs)
  1386   );
  1257   );
  1387 
  1258 
       
  1259 val _ : OuterParse.token list -> (string -> string -> theory -> theory) * OuterParse.token list
       
  1260  = parse_syntax_tyco;
       
  1261 
  1388 val syntax_tycoP =
  1262 val syntax_tycoP =
  1389   OuterSyntax.command syntax_tycoK "define code syntax for type constructor" K.thy_decl (
  1263   OuterSyntax.command syntax_tycoK "define code syntax for type constructor" K.thy_decl (
  1390     P.xname
  1264     Scan.repeat1 (
  1391     -- Scan.repeat1 (
  1265       P.xname
  1392          P.name -- (P.$$$ "(" |-- P.string --| P.$$$ ")")
  1266       -- Scan.repeat1 (
  1393          -- CodegenSerializer.parse_fixity
  1267            P.name -- parse_syntax_tyco
  1394        )
  1268          )
  1395     >> (fn (raw_tyco, stxs) =>
  1269     )
  1396           (Toplevel.theory oo fold)
  1270     >> (Toplevel.theory oo fold) (fn (raw_tyco, syns) =>
  1397             (fn ((target, raw_mfx), fixity) =>
  1271           fold (fn (target, modifier) => modifier raw_tyco target) syns)
  1398               add_syntax_tyco raw_tyco (target, (raw_mfx, fixity))) stxs)
       
  1399   );
  1272   );
  1400 
  1273 
  1401 val syntax_constP =
  1274 val syntax_constP =
  1402   OuterSyntax.command syntax_constK "define code syntax for constant" K.thy_decl (
  1275   OuterSyntax.command syntax_constK "define code syntax for constant" K.thy_decl (
  1403     (P.xname -- Scan.option (P.$$$ "::" |-- P.typ))
  1276     Scan.repeat1 (
  1404     -- Scan.repeat1 (
  1277       (P.xname -- Scan.option (P.$$$ "::" |-- P.typ))
  1405          P.name -- (P.$$$ "(" |-- P.string --| P.$$$ ")")
  1278       -- Scan.repeat1 (
  1406          -- CodegenSerializer.parse_fixity
  1279            P.name -- parse_syntax_const
  1407        )
  1280          )
  1408     >> (fn (raw_c, stxs) =>
  1281     )
  1409           (Toplevel.theory oo fold)
  1282     >> (Toplevel.theory oo fold) (fn (raw_c, syns) =>
  1410             (fn ((target, raw_mfx), fixity) =>
  1283           fold (fn (target, modifier) => modifier raw_c target) syns)
  1411               add_syntax_const raw_c (target, (raw_mfx, fixity))) stxs)
       
  1412   );
  1284   );
  1413 
  1285 
  1414 val _ = OuterSyntax.add_parsers [classP, generateP, serializeP, aliasP,
  1286 val _ = OuterSyntax.add_parsers [classP, generateP, serializeP, aliasP,
  1415   primclassP, primtycoP, primconstP, syntax_tycoP, syntax_constP];
  1287   primclassP, primtycoP, primconstP, syntax_tycoP, syntax_constP];
  1416 val _ = OuterSyntax.add_keywords ["\\<Rightarrow>", "=>", constantsK, dependingK];
  1288 val _ = OuterSyntax.add_keywords ["\\<Rightarrow>", "=>", constantsK, dependingK];
  1417 
  1289 
  1418 
  1290 
  1419 
  1291 
  1420 (** setup **)
  1292 (** setup **)
  1421 
  1293 
  1422 val _ =
  1294 val _ = Context.add_setup [
  1423   let
  1295   CodegenData.init,
  1424     val bool = Type ("bool", []);
  1296 (*   add_appconst_i ("op =", ((2, 2), appgen_eq)),  *)
  1425     val nat = Type ("nat", []);
  1297   add_eqextr ("defs", eqextr_defs),
  1426     val int = Type ("IntDef.int", []);
  1298   add_defgen ("clsdecl", defgen_clsdecl),
  1427     fun list t = Type ("List.list", [t]);
  1299   add_defgen ("funs", defgen_funs),
  1428     fun pair t1 t2 = Type ("*", [t1, t2]);
  1300   add_defgen ("clsmem", defgen_clsmem),
  1429     val A = TVar (("'a", 0), []);
  1301   add_defgen ("datatypecons", defgen_datatypecons)(*,
  1430     val B = TVar (("'b", 0), []);
  1302   add_defgen ("clsinst", defgen_clsinst)  *)
  1431   in Context.add_setup [
  1303 ];
  1432     CodegenData.init,
       
  1433     add_appconst_i ("neg", ((0, 0), appgen_neg)),
       
  1434     add_appconst_i ("op =", ((2, 2), appgen_eq)),
       
  1435     add_defgen ("clsdecl", defgen_clsdecl),
       
  1436     add_defgen ("tyco_fallback", defgen_tyco_fallback),
       
  1437     add_defgen ("const_fallback", defgen_const_fallback),
       
  1438     add_defgen ("defs", defgen_defs),
       
  1439     add_defgen ("clsmem", defgen_clsmem),
       
  1440     add_defgen ("clsinst", defgen_clsinst),
       
  1441     add_alias ("op -->", "HOL.op_implies"),
       
  1442     add_alias ("op +", "HOL.op_add"),
       
  1443     add_alias ("op -", "HOL.op_minus"),
       
  1444     add_alias ("op *", "HOL.op_times"),
       
  1445     add_alias ("op <=", "Orderings.op_le"),
       
  1446     add_alias ("op <", "Orderings.op_lt"),
       
  1447     add_alias ("List.op @", "List.append"),
       
  1448     add_alias ("List.op mem", "List.member"),
       
  1449     add_alias ("Divides.op div", "Divides.div"),
       
  1450     add_alias ("Divides.op dvd", "Divides.dvd"),
       
  1451     add_alias ("Divides.op mod", "Divides.mod"),
       
  1452     add_lookup_tyco ("bool", type_bool),
       
  1453     add_lookup_tyco ("*", type_pair),
       
  1454     add_lookup_tyco ("IntDef.int", type_integer),
       
  1455     add_lookup_tyco ("List.list", type_list),
       
  1456     add_lookup_const (("True", bool), Cons_true),
       
  1457     add_lookup_const (("False", bool), Cons_false),
       
  1458     add_lookup_const (("Not", bool --> bool), Fun_not),
       
  1459     add_lookup_const (("op &", bool --> bool --> bool), Fun_and),
       
  1460     add_lookup_const (("op |", bool --> bool --> bool), Fun_or),
       
  1461     add_lookup_const (("HOL.If", bool --> A --> A --> A), Fun_if),
       
  1462     add_lookup_const (("Pair", A --> B --> pair A B), Cons_pair),
       
  1463     add_lookup_const (("fst", pair A B --> A), Fun_fst),
       
  1464     add_lookup_const (("snd", pair A B --> B), Fun_snd),
       
  1465     add_lookup_const (("List.list.Cons", A --> list A --> list A), Cons_cons),
       
  1466     add_lookup_const (("List.list.Nil", list A), Cons_nil),
       
  1467     add_lookup_const (("1", nat),
       
  1468       IApp (
       
  1469         IConst ("const.Suc", IFun (IType ("type.nat", []), IFun (IType ("type.nat", []), IType ("type.nat", [])))),
       
  1470         IConst ("const.Zero", IType ("type.nat", []))
       
  1471       )),
       
  1472     add_lookup_const (("0", int), Fun_0),
       
  1473     add_lookup_const (("1", int), Fun_1),
       
  1474     add_lookup_const (("op +", int --> int --> int), Fun_add),
       
  1475     add_lookup_const (("op *", int --> int --> int), Fun_mult),
       
  1476     add_lookup_const (("uminus", int --> int), Fun_minus),
       
  1477     add_lookup_const (("op <", int --> int --> bool), Fun_lt),
       
  1478     add_lookup_const (("op <=", int --> int --> bool), Fun_le),
       
  1479     add_lookup_const (("Wellfounded_Recursion.wfrec", ((A --> B) --> A --> B) --> A --> B), Fun_wfrec)
       
  1480   ] end;
       
  1481 
       
  1482 (* "op /" ??? *)
       
  1483 
  1304 
  1484 end; (* local *)
  1305 end; (* local *)
  1485 
  1306 
  1486 end; (* struct *)
  1307 end; (* struct *)