src/Pure/Tools/codegen_package.ML
changeset 19597 8ced57ffc090
parent 19571 0d673faf560c
child 19607 07eeb832f28d
equal deleted inserted replaced
19596:7b07dac44e09 19597:8ced57ffc090
    11   type auxtab;
    11   type auxtab;
    12   type appgen = theory -> auxtab
    12   type appgen = theory -> auxtab
    13     -> (string * typ) * term list -> CodegenThingol.transact
    13     -> (string * typ) * term list -> CodegenThingol.transact
    14     -> CodegenThingol.iexpr * CodegenThingol.transact;
    14     -> CodegenThingol.iexpr * CodegenThingol.transact;
    15 
    15 
    16   val add_appconst: string * ((int * int) * appgen) -> theory -> theory;
    16   val add_appconst: xstring * ((int * int) * appgen) -> theory -> theory;
    17   val add_appconst_i: xstring * ((int * int) * appgen) -> theory -> theory;
    17   val add_appconst_i: string * ((int * int) * appgen) -> theory -> theory;
    18   val add_prim_class: xstring -> (string * string)
    18   val add_prim_class: xstring -> (string * string)
    19     -> theory -> theory;
    19     -> theory -> theory;
    20   val add_prim_tyco: xstring -> (string * string)
    20   val add_prim_tyco: xstring -> (string * string)
    21     -> theory -> theory;
    21     -> theory -> theory;
    22   val add_prim_const: xstring -> (string * string)
    22   val add_prim_const: xstring -> (string * string)
    44   val appgen_default: appgen;
    44   val appgen_default: appgen;
    45   val appgen_let: (int -> term -> term list * term)
    45   val appgen_let: (int -> term -> term list * term)
    46     -> appgen;
    46     -> appgen;
    47   val appgen_split: (int -> term -> term list * term)
    47   val appgen_split: (int -> term -> term list * term)
    48     -> appgen;
    48     -> appgen;
    49   val appgen_number_of: (term -> term) -> (theory -> term -> IntInf.int) -> string -> string
    49   val appgen_number_of: (theory -> term -> IntInf.int) -> appgen;
    50     -> appgen;
       
    51   val appgen_wfrec: appgen;
    50   val appgen_wfrec: appgen;
    52   val add_case_const: (theory -> string -> (string * int) list option) -> xstring
    51   val add_case_const: string -> (string * int) list -> theory -> theory;
    53     -> theory -> theory;
       
    54   val add_case_const_i: (theory -> string -> (string * int) list option) -> string
       
    55     -> theory -> theory;
       
    56 
    52 
    57   val print_code: theory -> unit;
    53   val print_code: theory -> unit;
    58   val rename_inconsistent: theory -> theory;
    54   val rename_inconsistent: theory -> theory;
    59   val ensure_datatype_case_consts: (theory -> string list)
       
    60     -> (theory -> string -> (string * int) list option)
       
    61     -> theory -> theory;
       
    62 
    55 
    63   (*debugging purpose only*)
    56   (*debugging purpose only*)
    64   structure InstNameMangler: NAME_MANGLER;
    57   structure InstNameMangler: NAME_MANGLER;
    65   structure ConstNameMangler: NAME_MANGLER;
    58   structure ConstNameMangler: NAME_MANGLER;
    66   structure DatatypeconsNameMangler: NAME_MANGLER;
    59   structure DatatypeconsNameMangler: NAME_MANGLER;
   322     syntax_tyco = Symtab.merge (eq_snd (op =)) (syntax_tyco1, syntax_tyco2),
   315     syntax_tyco = Symtab.merge (eq_snd (op =)) (syntax_tyco1, syntax_tyco2),
   323     syntax_const = Symtab.merge (eq_snd (op =)) (syntax_const1, syntax_const2) } : target_data;
   316     syntax_const = Symtab.merge (eq_snd (op =)) (syntax_const1, syntax_const2) } : target_data;
   324 
   317 
   325 structure CodegenData = TheoryDataFun
   318 structure CodegenData = TheoryDataFun
   326 (struct
   319 (struct
   327   val name = "Pure/codegen_package";
   320   val name = "Pure/CodegenPackage";
   328   type T = {
   321   type T = {
   329     modl: module,
   322     modl: module,
   330     gens: gens,
   323     gens: gens,
   331     logic_data: logic_data,
   324     logic_data: logic_data,
   332     target_data: target_data Symtab.table
   325     target_data: target_data Symtab.table
   824         |-> (fn ((((de, dty), se), be), e0) => pair (ICase (((de, dty), [(se, be)]), e0)))
   817         |-> (fn ((((de, dty), se), be), e0) => pair (ICase (((de, dty), [(se, be)]), e0)))
   825     | _ =>
   818     | _ =>
   826         trns
   819         trns
   827         |> appgen_default thy tabs app;
   820         |> appgen_default thy tabs app;
   828 
   821 
   829 fun appgen_number_of mk_int_to_nat bin_to_int tyco_int tyco_nat thy tabs ((_,
   822 fun appgen_number_of bin_to_int thy tabs ((_, Type (_, [_, ty])), [bin]) trns =
   830   Type (_, [_, ty as Type (tyco, [])])), [bin]) trns =
   823   let
   831     if tyco = tyco_nat then
   824     val i = bin_to_int thy bin;
   832       trns
   825       (*preprocessor eliminates nat and negative numerals*)
   833       |> exprgen_term thy tabs (mk_int_to_nat bin) (*should be a preprocessor's work*)
   826     val _ = if i < 0 then error ("negative numeral: " ^ IntInf.toString i) else ();
   834     else
   827   in
   835       let
   828     trns
   836         val i = bin_to_int thy bin;
   829     |> exprgen_type thy tabs ty
   837         val _ = if i < 0 then error ("negative numeral: " ^ IntInf.toString i) else ();
   830     |-> (fn ty => pair (CodegenThingol.INum ((i, ty), ())))
   838           (*should be a preprocessor's work*)
   831   end;
   839       in
       
   840         trns
       
   841         |> exprgen_type thy tabs ty
       
   842         |-> (fn ty => pair (CodegenThingol.INum ((i, ty), ())))
       
   843       end;
       
   844 
   832 
   845 fun appgen_wfrec thy tabs ((c, ty), [_, tf, tx]) trns =
   833 fun appgen_wfrec thy tabs ((c, ty), [_, tf, tx]) trns =
   846   let
   834   let
   847     val ty_def = (op ---> o apfst tl o strip_type o Sign.the_const_type thy) c;
   835     val ty_def = (op ---> o apfst tl o strip_type o Type.unvarifyT o Sign.the_const_type thy) c;
   848     val ty' = (op ---> o apfst tl o strip_type) ty;
   836     val ty' = (op ---> o apfst tl o strip_type) ty;
   849     val idf = idf_of_const thy tabs (c, ty);
   837     val idf = idf_of_const thy tabs (c, ty);
   850   in
   838   in
   851     trns
   839     trns
   852     |> ensure_def [("wfrec", (K o succeed) Undef)] ("generating wfrec") idf
   840     |> ensure_def [("wfrec", (K o succeed) Undef)] ("generating wfrec") idf
   856     ||>> exprsgen_type thy tabs [ty_def]
   844     ||>> exprsgen_type thy tabs [ty_def]
   857     ||>> exprgen_term thy tabs tf
   845     ||>> exprgen_term thy tabs tf
   858     ||>> exprgen_term thy tabs tx
   846     ||>> exprgen_term thy tabs tx
   859     |-> (fn ((((_, ls), [ty]), tf), tx) => pair (IConst (idf, (ls, ty)) `$ tf `$ tx))
   847     |-> (fn ((((_, ls), [ty]), tf), tx) => pair (IConst (idf, (ls, ty)) `$ tf `$ tx))
   860   end;
   848   end;
   861 
       
   862 fun eqextr_eq f fals thy tabs ("op =", ty) =
       
   863       (case ty
       
   864        of Type ("fun", [Type (dtco, _), _]) =>
       
   865             (case f thy dtco
       
   866              of [] => NONE
       
   867               | [eq] => SOME ((the o CodegenTheorems.preprocess_fun thy) [eq], NONE)
       
   868               | eqs => SOME ((the o CodegenTheorems.preprocess_fun thy) eqs, SOME fals))
       
   869         | _ => NONE) |> Option.map (fn ((ty, eqs), default) => ((eqs, default), ty))
       
   870   | eqextr_eq f fals thy tabs _ =
       
   871       NONE;
       
   872 
   849 
   873 fun appgen_datatype_case cos thy tabs (app as ((_, ty), ts)) trns =
   850 fun appgen_datatype_case cos thy tabs (app as ((_, ty), ts)) trns =
   874   let
   851   let
   875     val (ts', t) = split_last ts;
   852     val (ts', t) = split_last ts;
   876     val (tys, dty) = (split_last o fst o strip_type) ty;
   853     val (tys, dty) = (split_last o fst o strip_type) ty;
   896     ||>> fold_map cg_case_d ((cos ~~ tys) ~~ ts')
   873     ||>> fold_map cg_case_d ((cos ~~ tys) ~~ ts')
   897     ||>> appgen_default thy tabs app
   874     ||>> appgen_default thy tabs app
   898     |-> (fn (((de, dty), bses), e0) => pair (ICase (((de, dty), bses), e0)))
   875     |-> (fn (((de, dty), bses), e0) => pair (ICase (((de, dty), bses), e0)))
   899   end;
   876   end;
   900 
   877 
   901 fun gen_add_case_const prep_c get_case_const_data raw_c thy =
   878 fun add_case_const c cos thy =
   902   let
   879   let
   903     val c = prep_c thy raw_c;
       
   904     val (tys, dty) = (split_last o fst o strip_type o Sign.the_const_type thy) c;
       
   905     val cos = (the o get_case_const_data thy) c;
       
   906     val n_eta = length cos + 1;
   880     val n_eta = length cos + 1;
   907   in
   881   in
   908     thy
   882     thy
   909     |> add_appconst_i (c, ((n_eta, n_eta), appgen_datatype_case cos))
   883     |> add_appconst_i (c, ((n_eta, n_eta), appgen_datatype_case cos))
   910   end;
   884   end;
   911 
       
   912 val add_case_const = gen_add_case_const Sign.intern_const;
       
   913 val add_case_const_i = gen_add_case_const (K I);
       
   914 
   885 
   915 
   886 
   916 
   887 
   917 (** theory interface **)
   888 (** theory interface **)
   918 
   889 
  1004 * *all* overloaded defintitions for a constant have to be purged
   975 * *all* overloaded defintitions for a constant have to be purged
  1005 * precondition: improved representation of definitions hidden by customary serializations
   976 * precondition: improved representation of definitions hidden by customary serializations
  1006 *)
   977 *)
  1007 
   978 
  1008 fun expand_module init gen arg thy =
   979 fun expand_module init gen arg thy =
  1009   (#modl o CodegenData.get) thy
   980   thy
  1010   |> start_transact init (gen thy (mk_tabs thy) arg)
   981   |> CodegenTheorems.notify_dirty
  1011   |-> (fn x:'a => fn modl => (x, map_module (K modl) thy));
   982   |> `(#modl o CodegenData.get)
       
   983   |> (fn (modl, thy) =>
       
   984         (start_transact init (gen thy (mk_tabs thy) arg) modl, thy))
       
   985   |-> (fn (x, modl) => map_module (K modl) #> pair x);
  1012 
   986 
  1013 fun rename_inconsistent thy =
   987 fun rename_inconsistent thy =
  1014   let
   988   let
  1015     fun get_inconsistent thyname =
   989     fun get_inconsistent thyname =
  1016       let
   990       let
  1031     fun add (src, dst) thy =
  1005     fun add (src, dst) thy =
  1032       if (is_some oo Symtab.lookup o fst o #alias o #logic_data o CodegenData.get) thy src
  1006       if (is_some oo Symtab.lookup o fst o #alias o #logic_data o CodegenData.get) thy src
  1033       then (warning ("code generator alias already defined for " ^ quote src ^ ", will not overwrite"); thy)
  1007       then (warning ("code generator alias already defined for " ^ quote src ^ ", will not overwrite"); thy)
  1034       else add_alias (src, dst) thy
  1008       else add_alias (src, dst) thy
  1035   in fold add inconsistent thy end;
  1009   in fold add inconsistent thy end;
  1036 
       
  1037 fun ensure_datatype_case_consts get_datatype_case_consts get_case_const_data thy =
       
  1038   let
       
  1039     fun ensure case_c thy =
       
  1040       if
       
  1041         Symtab.defined ((#appconst o #gens o CodegenData.get) thy) case_c
       
  1042       then
       
  1043         (warning ("case constant " ^ quote case_c ^ " already present in application table, will not overwrite"); thy)
       
  1044       else
       
  1045         add_case_const_i get_case_const_data case_c thy;
       
  1046   in
       
  1047     fold ensure (get_datatype_case_consts thy) thy
       
  1048   end;
       
  1049 
  1010 
  1050 fun codegen_term t thy =
  1011 fun codegen_term t thy =
  1051   thy
  1012   thy
  1052   |> expand_module NONE exprsgen_term [CodegenTheorems.preprocess_term thy t]
  1013   |> expand_module NONE exprsgen_term [CodegenTheorems.preprocess_term thy t]
  1053   |-> (fn [t] => pair t);
  1014   |-> (fn [t] => pair t);