1 (* Title: Pure/Tools/codegen_package.ML
3 Author: Florian Haftmann, TU Muenchen
5 Code generator extraction kernel. Code generator Isar setup.
8 signature CODEGEN_PACKAGE =
10 include BASIC_CODEGEN_THINGOL;
11 val codegen_term: theory -> term -> thm * iterm;
12 val eval_term: theory -> (string (*reference name!*) * 'a option ref) * term -> 'a;
13 val const_of_idf: theory -> string -> string * typ;
14 val get_root_module: theory -> CodegenThingol.code;
17 val add_appconst: string * appgen -> theory -> theory;
18 val appgen_numeral: (theory -> term -> IntInf.int) -> appgen;
19 val appgen_char: (term -> int option) -> appgen;
20 val appgen_case: (theory -> term
21 -> ((string * typ) list * ((term * typ) * (term * term) list)) option)
23 val appgen_let: appgen;
26 structure CodegenPackage : CODEGEN_PACKAGE =
29 open BasicCodegenThingol;
30 val tracing = CodegenThingol.tracing;
31 val succeed = CodegenThingol.succeed;
32 val fail = CodegenThingol.fail;
34 (** code extraction **)
38 structure Code = CodeDataFun
40 val name = "Pure/code";
41 type T = CodegenThingol.code;
42 val empty = CodegenThingol.empty_code;
43 fun merge _ = CodegenThingol.merge_code;
44 fun purge _ NONE _ = CodegenThingol.empty_code
45 | purge NONE _ _ = CodegenThingol.empty_code
46 | purge (SOME thy) (SOME cs) code =
49 map_filter (CodegenNames.const_rev thy) (Graph.keys code);
52 ((Graph.all_succs code
53 o map (CodegenNames.const thy)
54 o filter (member CodegenConsts.eq_const cs_exisiting)
60 type appgen = theory -> ((sort -> sort) * Sorts.algebra) * Consts.T
62 -> bool * string list option
63 -> (string * typ) * term list -> CodegenThingol.transact -> iterm * CodegenThingol.transact;
65 type appgens = (int * (appgen * stamp)) Symtab.table;
66 val merge_appgens : appgens * appgens -> appgens =
67 Symtab.merge (fn ((bounds1, (_, stamp1)), (bounds2, (_, stamp2))) =>
68 bounds1 = bounds2 andalso stamp1 = stamp2);
70 structure Consttab = CodegenConsts.Consttab;
71 type abstypes = typ Symtab.table * CodegenConsts.const Consttab.table;
72 fun merge_abstypes ((typs1, consts1) : abstypes, (typs2, consts2) : abstypes) =
73 (Symtab.merge (Type.eq_type Vartab.empty) (typs1, typs2),
74 Consttab.merge CodegenConsts.eq_const (consts1, consts2));
76 structure CodegenPackageData = TheoryDataFun
78 val name = "Pure/codegen_package";
79 type T = appgens * abstypes;
80 val empty = (Symtab.empty, (Symtab.empty, Consttab.empty));
83 fun merge _ ((appgens1, abstypes1), (appgens2, abstypes2)) =
84 (merge_appgens (appgens1, appgens2), merge_abstypes (abstypes1, abstypes2));
88 val _ = Context.add_setup (Code.init #> CodegenPackageData.init);
91 (* extraction kernel *)
93 fun check_strict (false, _) has_seri x =
95 | check_strict (_, SOME targets) has_seri x =
96 not (has_seri targets x)
97 | check_strict (true, _) has_seri x =
100 fun get_abstype thy (tyco, tys) = case Symtab.lookup ((fst o snd o CodegenPackageData.get) thy) tyco
101 of SOME ty => SOME ((map_atyps (fn TFree (n, _) => nth tys (the (Int.fromString n)))) ty)
104 fun ensure_def_class thy (algbr as ((proj_sort, _), _)) funcgr strct class trns =
106 val (v, cs) = (ClassPackage.the_consts_sign thy) class;
107 val superclasses = (proj_sort o Sign.super_classes thy) class;
108 val classops' = map (CodegenNames.const thy o CodegenConsts.norm_of_typ thy) cs;
109 val class' = CodegenNames.class thy class;
110 fun defgen_class trns =
112 |> fold_map (ensure_def_class thy algbr funcgr strct) superclasses
113 ||>> (fold_map (exprgen_type thy algbr funcgr strct) o map snd) cs
114 |-> (fn (superclasses, classoptyps) => succeed
115 (CodegenThingol.Class (superclasses,
116 (unprefix "'" v, classops' ~~ classoptyps))))
119 |> tracing (fn _ => "generating class " ^ quote class)
120 |> CodegenThingol.ensure_def defgen_class true
121 ("generating class " ^ quote class) class'
124 and ensure_def_tyco thy algbr funcgr strct tyco trns =
126 fun defgen_datatype trns =
127 case CodegenData.get_datatype thy tyco
130 |> fold_map (exprgen_tyvar_sort thy algbr funcgr strct) vs
131 ||>> fold_map (fn (c, tys) =>
132 fold_map (exprgen_type thy algbr funcgr strct) tys
134 pair ((CodegenNames.const thy o CodegenConsts.norm_of_typ thy)
135 (c, tys ---> Type (tyco, map TFree vs)), tys'))) cos
136 |-> (fn (vs, cos) => succeed (CodegenThingol.Datatype (vs, cos)))
139 |> fail ("No such datatype: " ^ quote tyco)
140 val tyco' = CodegenNames.tyco thy tyco;
141 val strict = check_strict strct (CodegenSerializer.tyco_has_serialization thy) tyco';
144 |> tracing (fn _ => "generating type constructor " ^ quote tyco)
145 |> CodegenThingol.ensure_def defgen_datatype strict
146 ("generating type constructor " ^ quote tyco) tyco'
149 and exprgen_tyvar_sort thy (algbr as ((proj_sort, _), _)) funcgr strct (v, sort) trns =
151 |> fold_map (ensure_def_class thy algbr funcgr strct) (proj_sort sort)
152 |-> (fn sort => pair (unprefix "'" v, sort))
153 and exprgen_type thy algbr funcgr strct (TVar _) trns =
154 error "TVar encountered in typ during code generation"
155 | exprgen_type thy algbr funcgr strct (TFree vs) trns =
157 |> exprgen_tyvar_sort thy algbr funcgr strct vs
158 |-> (fn (v, sort) => pair (ITyVar v))
159 | exprgen_type thy algbr funcgr strct (Type ("fun", [t1, t2])) trns =
161 |> exprgen_type thy algbr funcgr strct t1
162 ||>> exprgen_type thy algbr funcgr strct t2
163 |-> (fn (t1', t2') => pair (t1' `-> t2'))
164 | exprgen_type thy algbr funcgr strct (Type (tyco, tys)) trns =
165 case get_abstype thy (tyco, tys)
168 |> exprgen_type thy algbr funcgr strct ty
171 |> ensure_def_tyco thy algbr funcgr strct tyco
172 ||>> fold_map (exprgen_type thy algbr funcgr strct) tys
173 |-> (fn (tyco, tys) => pair (tyco `%% tys));
175 exception CONSTRAIN of (string * typ) * typ;
177 fun exprgen_typinst thy (algbr as ((proj_sort, algebra), consts)) funcgr strct (ty_ctxt, sort_decl) trns =
179 val pp = Sign.pp thy;
181 Inst of (class * string) * inst list list
182 | Contxt of (string * sort) * (class list * int);
183 fun classrel (l as Contxt (v_sort, (classes, n)), _) class =
184 Contxt (v_sort, (class :: classes, n))
185 | classrel (Inst ((_, tyco), lss), _) class =
186 Inst ((class, tyco), lss);
187 fun constructor tyco iss class =
188 Inst ((class, tyco), (map o map) fst iss);
189 fun variable (TFree (v, sort)) =
191 val sort' = proj_sort sort;
192 in map_index (fn (n, class) => (Contxt ((v, sort'), ([], n)), class)) sort' end;
193 val insts = Sorts.of_sort_derivation pp algebra
194 {classrel = classrel, constructor = constructor, variable = variable}
195 (ty_ctxt, proj_sort sort_decl);
196 fun mk_dict (Inst (inst, instss)) trns =
198 |> ensure_def_inst thy algbr funcgr strct inst
199 ||>> (fold_map o fold_map) mk_dict instss
200 |-> (fn (inst, instss) => pair (Instance (inst, instss)))
201 | mk_dict (Contxt ((v, sort), (classes, k))) trns =
203 |> fold_map (ensure_def_class thy algbr funcgr strct) classes
204 |-> (fn classes => pair (Context (classes, (unprefix "'" v,
205 if length sort = 1 then ~1 else k))))
208 |> fold_map mk_dict insts
210 and exprgen_typinst_const thy (algbr as (_, consts)) funcgr strct (c, ty_ctxt) trns =
212 val c' = CodegenConsts.norm_of_typ thy (c, ty_ctxt)
213 val idf = CodegenNames.const thy c';
214 val ty_decl = Consts.declaration consts idf;
215 val insts = (op ~~ o apsnd (map (snd o dest_TVar)) oo pairself)
216 (curry (Consts.typargs consts) idf) (ty_ctxt, ty_decl);
217 val _ = if exists not (map (Sign.of_sort thy) insts)
218 then raise CONSTRAIN ((c, ty_decl), ty_ctxt) else ();
221 |> fold_map (exprgen_typinst thy algbr funcgr strct) insts
223 and ensure_def_inst thy (algbr as ((proj_sort, _), _)) funcgr strct (class, tyco) trns =
225 val (vs, classop_defs) = ((apsnd o map) Const o ClassPackage.the_inst_sign thy)
227 val classops = (map (CodegenConsts.norm_of_typ thy) o snd
228 o ClassPackage.the_consts_sign thy) class;
229 val arity_typ = Type (tyco, (map TFree vs));
230 val superclasses = (proj_sort o Sign.super_classes thy) class
231 fun gen_superarity superclass trns =
233 |> ensure_def_class thy algbr funcgr strct superclass
234 ||>> exprgen_typinst thy algbr funcgr strct (arity_typ, [superclass])
235 |-> (fn (superclass, [Instance (inst, iss)]) => pair (superclass, (inst, iss)));
236 fun gen_classop_def (classop, t) trns =
238 |> ensure_def_const thy algbr funcgr strct classop
239 ||>> exprgen_term thy algbr funcgr strct t;
240 fun defgen_inst trns =
242 |> ensure_def_class thy algbr funcgr strct class
243 ||>> ensure_def_tyco thy algbr funcgr strct tyco
244 ||>> fold_map (exprgen_tyvar_sort thy algbr funcgr strct) vs
245 ||>> fold_map gen_superarity superclasses
246 ||>> fold_map gen_classop_def (classops ~~ classop_defs)
247 |-> (fn ((((class, tyco), arity), superarities), classops) =>
248 succeed (CodegenThingol.Classinst ((class, (tyco, arity)), (superarities, classops))));
249 val inst = CodegenNames.instance thy (class, tyco);
252 |> tracing (fn _ => "generating instance " ^ quote class ^ " / " ^ quote tyco)
253 |> CodegenThingol.ensure_def defgen_inst true
254 ("generating instance " ^ quote class ^ " / " ^ quote tyco) inst
257 and ensure_def_const thy (algbr as (_, consts)) funcgr strct (c, tys) trns =
259 val c' = CodegenNames.const thy (c, tys);
260 fun defgen_datatypecons trns =
262 |> ensure_def_tyco thy algbr funcgr strct
263 ((the o CodegenData.get_datatype_of_constr thy) (c, tys))
264 |-> (fn _ => succeed CodegenThingol.Bot);
265 fun defgen_classop trns =
267 |> ensure_def_class thy algbr funcgr strct ((the o AxClass.class_of_param thy) c)
268 |-> (fn _ => succeed CodegenThingol.Bot);
269 fun defgen_fun trns =
270 case CodegenFuncgr.get_funcs funcgr
271 (perhaps (Consttab.lookup ((snd o snd o CodegenPackageData.get) thy)) (c, tys))
272 of eq_thms as eq_thm :: _ =>
274 val msg = cat_lines ("generating code for theorems " :: map string_of_thm eq_thms);
275 val ty = (Logic.unvarifyT o CodegenData.typ_func thy) eq_thm;
276 val vs = (map dest_TFree o Consts.typargs consts) (c', ty);
278 apfst (snd o strip_comb) o Logic.dest_equals o Logic.unvarify o prop_of;
279 fun exprgen_eq (args, rhs) trns =
281 |> fold_map (exprgen_term thy algbr funcgr strct) args
282 ||>> exprgen_term thy algbr funcgr strct rhs;
285 |> CodegenThingol.message msg (fn trns => trns
286 |> fold_map (exprgen_eq o dest_eqthm) eq_thms
287 ||>> fold_map (exprgen_tyvar_sort thy algbr funcgr strct) vs
288 ||>> exprgen_type thy algbr funcgr strct ty
289 |-> (fn ((eqs, vs), ty) => succeed (CodegenThingol.Fun (eqs, (vs, ty)))))
293 |> fail ("No defining equations found for "
294 ^ (quote o CodegenConsts.string_of_const thy) (c, tys));
296 if CodegenNames.has_nsp CodegenNames.nsp_fun c'
298 else if CodegenNames.has_nsp CodegenNames.nsp_classop c'
300 else if CodegenNames.has_nsp CodegenNames.nsp_dtco c'
301 then defgen_datatypecons
302 else error ("Illegal shallow name space for constant: " ^ quote c');
303 val strict = check_strict strct (CodegenSerializer.const_has_serialization thy) c';
306 |> tracing (fn _ => "generating constant "
307 ^ (quote o CodegenConsts.string_of_const thy) (c, tys))
308 |> CodegenThingol.ensure_def defgen strict ("generating constant "
309 ^ CodegenConsts.string_of_const thy (c, tys)) c'
312 and exprgen_term thy algbr funcgr strct (Const (c, ty)) trns =
314 |> select_appgen thy algbr funcgr strct ((c, ty), [])
315 | exprgen_term thy algbr funcgr strct (Var _) trns =
316 error "Var encountered in term during code generation"
317 | exprgen_term thy algbr funcgr strct (Free (v, ty)) trns =
319 |> exprgen_type thy algbr funcgr strct ty
320 |-> (fn _ => pair (IVar v))
321 | exprgen_term thy algbr funcgr strct (Abs (raw_v, ty, raw_t)) trns =
323 val (v, t) = Syntax.variant_abs (CodegenNames.purify_var raw_v, ty, raw_t);
326 |> exprgen_type thy algbr funcgr strct ty
327 ||>> exprgen_term thy algbr funcgr strct t
328 |-> (fn (ty, t) => pair ((v, ty) `|-> t))
330 | exprgen_term thy algbr funcgr strct (t as _ $ _) trns =
332 of (Const (c, ty), ts) =>
334 |> select_appgen thy algbr funcgr strct ((c, ty), ts)
338 |> exprgen_term thy algbr funcgr strct t'
339 ||>> fold_map (exprgen_term thy algbr funcgr strct) ts
340 |-> (fn (t, ts) => pair (t `$$ ts))
341 and appgen_default thy algbr funcgr strct ((c, ty), ts) trns =
343 |> ensure_def_const thy algbr funcgr strct (CodegenConsts.norm_of_typ thy (c, ty))
344 ||>> exprgen_type thy algbr funcgr strct ty
345 ||>> exprgen_typinst_const thy algbr funcgr strct (c, ty)
346 ||>> fold_map (exprgen_term thy algbr funcgr strct) ts
347 |-> (fn (((c, ty), iss), ts) =>
348 pair (IConst (c, (iss, ty)) `$$ ts))
349 and select_appgen thy algbr funcgr strct ((c, ty), ts) trns =
350 case Symtab.lookup (fst (CodegenPackageData.get thy)) c
351 of SOME (i, (appgen, _)) =>
352 if length ts < i then
354 val tys = Library.take (i - length ts, ((fst o strip_type) ty));
355 val vs = Name.names (Name.declare c Name.context) "a" tys;
358 |> fold_map (exprgen_type thy algbr funcgr strct) tys
359 ||>> appgen thy algbr funcgr strct ((c, ty), ts @ map Free vs)
360 |-> (fn (tys, t) => pair (map2 (fn (v, _) => pair v) vs tys `|--> t))
362 else if length ts > i then
364 |> appgen thy algbr funcgr strct ((c, ty), Library.take (i, ts))
365 ||>> fold_map (exprgen_term thy algbr funcgr strct) (Library.drop (i, ts))
366 |-> (fn (t, ts) => pair (t `$$ ts))
369 |> appgen thy algbr funcgr strct ((c, ty), ts)
372 |> appgen_default thy algbr funcgr strct ((c, ty), ts);
375 (* entrance points into extraction kernel *)
377 fun ensure_def_const' thy algbr funcgr strct c trns =
378 ensure_def_const thy algbr funcgr strct c trns
379 handle CONSTRAIN ((c, ty), ty_decl) => error (
380 "Constant " ^ c ^ " with most general type\n"
381 ^ Sign.string_of_typ thy ty
382 ^ "\noccurs with type\n"
383 ^ Sign.string_of_typ thy ty_decl);
384 fun exprgen_term' thy algbr funcgr strct t trns =
385 exprgen_term thy algbr funcgr strct t trns
386 handle CONSTRAIN ((c, ty), ty_decl) => error ("In term " ^ (quote o Sign.string_of_term thy) t
387 ^ ",\nconstant " ^ c ^ " with most general type\n"
388 ^ Sign.string_of_typ thy ty
389 ^ "\noccurs with type\n"
390 ^ Sign.string_of_typ thy ty_decl);
393 (* parametrized application generators, for instantiation in object logic *)
394 (* (axiomatic extensions of extraction kernel *)
396 fun appgen_numeral int_of_numeral thy algbr funcgr strct (app as (c, ts)) trns =
397 case try (int_of_numeral thy) (list_comb (Const c, ts))
400 |> appgen_default thy algbr funcgr strct app
401 |-> (fn t => pair (CodegenThingol.INum (i, t)))
404 |> appgen_default thy algbr funcgr strct app;
406 fun appgen_char char_to_index thy algbr funcgr strct (app as ((_, ty), _)) trns =
407 case (char_to_index o list_comb o apfst Const) app
410 |> exprgen_type thy algbr funcgr strct ty
411 ||>> appgen_default thy algbr funcgr strct app
412 |-> (fn (_, t0) => pair (IChar (chr i, t0)))
415 |> appgen_default thy algbr funcgr strct app;
417 fun appgen_case dest_case_expr thy algbr funcgr strct (app as (c_ty, ts)) trns =
419 val SOME ([], ((st, sty), ds)) = dest_case_expr thy (list_comb (Const c_ty, ts));
420 fun clausegen (dt, bt) trns =
422 |> exprgen_term thy algbr funcgr strct dt
423 ||>> exprgen_term thy algbr funcgr strct bt;
426 |> exprgen_term thy algbr funcgr strct st
427 ||>> exprgen_type thy algbr funcgr strct sty
428 ||>> fold_map clausegen ds
429 ||>> appgen_default thy algbr funcgr strct app
430 |-> (fn (((se, sty), ds), e0) => pair (ICase (((se, sty), ds), e0)))
433 fun appgen_let thy algbr funcgr strct (app as (_, [st, ct])) trns =
435 |> exprgen_term thy algbr funcgr strct ct
436 ||>> exprgen_term thy algbr funcgr strct st
437 ||>> appgen_default thy algbr funcgr strct app
438 |-> (fn (((v, ty) `|-> be, se), e0) =>
439 pair (ICase (((se, ty), case be
440 of ICase (((IVar w, _), ds), _) => if v = w then ds else [(IVar v, be)]
441 | _ => [(IVar v, be)]
443 | (_, e0) => pair e0);
445 fun add_appconst (c, appgen) thy =
447 val i = (length o fst o strip_type o Sign.the_const_type thy) c;
448 val _ = Code.change thy (K CodegenThingol.empty_code);
450 (CodegenPackageData.map o apfst)
451 (Symtab.update (c, (i, (appgen, stamp ())))) thy
456 (** abstype and constsubst interface **)
458 fun gen_abstyp prep_const prep_typ (raw_abstyp, raw_substtyp) raw_absconsts thy =
460 val abstyp = Type.no_tvars (prep_typ thy raw_abstyp);
461 val substtyp = Type.no_tvars (prep_typ thy raw_substtyp);
462 val absconsts = (map o pairself) (prep_const thy) raw_absconsts;
463 val Type (abstyco, tys) = abstyp handle BIND => error ("bad type: " ^ Sign.string_of_typ thy abstyp);
464 val typarms = map (fst o dest_TFree) tys handle MATCH => error ("bad type: " ^ Sign.string_of_typ thy abstyp);
467 val k = find_index (fn w => v = w) typarms;
469 then error ("free type variable: " ^ quote v)
470 else TFree (string_of_int k, [])
472 val typpat = map_atyps (fn TFree (v, _) => mk_index v) substtyp;
473 fun apply_typpat (Type (tyco, tys)) =
475 val tys' = map apply_typpat tys;
476 in if tyco = abstyco then
477 (map_atyps (fn TFree (n, _) => nth tys' (the (Int.fromString n)))) typpat
481 | apply_typpat ty = ty;
482 val string_of_typ = setmp show_sorts true (Sign.string_of_typ thy);
483 fun add_consts (c1, c2) =
485 val _ = if CodegenNames.has_nsp CodegenNames.nsp_fun (CodegenNames.const thy c2)
487 else error ("not a function: " ^ CodegenConsts.string_of_const thy c2);
488 val funcgr = CodegenFuncgr.mk_funcgr thy [c1, c2] [];
489 val ty_map = CodegenFuncgr.get_func_typs funcgr;
490 val ty1 = (apply_typpat o the o AList.lookup CodegenConsts.eq_const ty_map) c1;
491 val ty2 = (the o AList.lookup CodegenConsts.eq_const ty_map) c2;
492 val _ = if Sign.typ_equiv thy (ty1, ty2) then () else
493 error ("Incompatiable type signatures of " ^ CodegenConsts.string_of_const thy c1
494 ^ " and " ^ CodegenConsts.string_of_const thy c2 ^ ":\n"
495 ^ string_of_typ ty1 ^ "\n" ^ string_of_typ ty2);
496 in Consttab.update (c1, c2) end;
497 val _ = Code.change thy (K CodegenThingol.empty_code);
500 |> (CodegenPackageData.map o apsnd) (fn (abstypes, abscs) =>
502 |> Symtab.update (abstyco, typpat),
504 |> fold add_consts absconsts)
508 fun gen_constsubst prep_const raw_constsubsts thy =
510 val constsubsts = (map o pairself) (prep_const thy) raw_constsubsts;
511 val string_of_typ = setmp show_sorts true (Sign.string_of_typ thy);
512 fun add_consts (c1, c2) =
514 val _ = if CodegenNames.has_nsp CodegenNames.nsp_fun (CodegenNames.const thy c2)
516 else error ("not a function: " ^ CodegenConsts.string_of_const thy c2);
517 val funcgr = CodegenFuncgr.mk_funcgr thy [c1, c2] [];
518 val ty_map = CodegenFuncgr.get_func_typs funcgr;
519 val ty1 = (the o AList.lookup CodegenConsts.eq_const ty_map) c1;
520 val ty2 = (the o AList.lookup CodegenConsts.eq_const ty_map) c2;
521 val _ = if Sign.typ_equiv thy (ty1, ty2) then () else
522 error ("Incompatiable type signatures of " ^ CodegenConsts.string_of_const thy c1
523 ^ " and " ^ CodegenConsts.string_of_const thy c2 ^ ":\n"
524 ^ string_of_typ ty1 ^ "\n" ^ string_of_typ ty2);
525 in Consttab.update (c1, c2) end;
526 val _ = Code.change thy (K CodegenThingol.empty_code);
529 |> (CodegenPackageData.map o apsnd o apsnd) (fold add_consts constsubsts)
532 val abstyp = gen_abstyp CodegenConsts.norm Sign.certify_typ;
533 val abstyp_e = gen_abstyp CodegenConsts.read_const (fn thy => Sign.read_typ (thy, K NONE));
535 val constsubst = gen_constsubst CodegenConsts.norm;
536 val constsubst_e = gen_constsubst CodegenConsts.read_const;
540 (** code generation interfaces **)
542 fun generate thy (cs, rhss) targets init gen it =
544 val raw_funcgr = CodegenFuncgr.mk_funcgr thy cs rhss;
545 val cs' = map_filter (Consttab.lookup ((snd o snd o CodegenPackageData.get) thy))
546 (CodegenFuncgr.Constgraph.keys raw_funcgr);
547 val funcgr = CodegenFuncgr.mk_funcgr thy cs' [];
548 val qnaming = NameSpace.qualified_names NameSpace.default_naming;
549 val algebr = ClassPackage.operational_algebra thy;
550 val consttab = Consts.empty
551 |> fold (fn (c, ty) => Consts.declare qnaming
552 ((CodegenNames.const thy c, ty), true))
553 (CodegenFuncgr.get_func_typs funcgr);
554 val algbr = (algebr, consttab);
556 Code.change_yield thy (CodegenThingol.start_transact init (gen thy algbr funcgr
558 |> (fn (x, modl) => x)
561 fun codegen_term thy t =
563 fun const_typ (c, ty) =
565 val const = CodegenConsts.norm_of_typ thy (c, ty);
566 val funcgr = CodegenFuncgr.mk_funcgr thy [const] [];
567 in case CodegenFuncgr.get_funcs funcgr const
568 of (thm :: _) => CodegenData.typ_func thy thm
569 | [] => Sign.the_const_type thy c
571 val ct = Thm.cterm_of thy t;
572 val (thm, ct') = CodegenData.preprocess_cterm thy
574 val t' = Thm.term_of ct';
575 val cs_rhss = CodegenConsts.consts_of thy t';
577 (thm, generate thy cs_rhss (SOME []) NONE exprgen_term' t')
580 fun const_of_idf thy =
581 CodegenConsts.typ_of_inst thy o the o CodegenNames.const_rev thy;
583 fun get_root_module thy =
586 fun eval_term thy (ref_spec, t) =
588 val _ = Term.fold_atyps (fn _ =>
589 error ("Term" ^ Sign.string_of_term thy t ^ "is polymorhpic"))
591 val (_, t') = codegen_term thy t;
593 CodegenSerializer.eval_term thy (ref_spec, t') (Code.get thy)
598 (** toplevel interface and setup **)
602 structure P = OuterParse
605 fun code raw_cs seris thy =
607 val cs = map (CodegenConsts.read_const thy) raw_cs;
608 val targets = case map fst seris
611 val seris' = map_filter (fn (target, args as _ :: _) =>
612 SOME (CodegenSerializer.get_serializer thy (target, args)) | _ => NONE) seris;
613 fun generate' thy = case cs
616 generate thy (cs, []) targets NONE (fold_map oooo ensure_def_const') cs;
617 fun serialize' [] code seri =
619 | serialize' cs code seri =
621 val cs = generate' thy;
622 val code = Code.get thy;
624 (map (serialize' cs code) seris'; ())
627 val (codeK, code_abstypeK, code_constsubstK) =
628 ("code_gen", "code_abstype", "code_constsubst");
633 OuterSyntax.improper_command codeK "generate and serialize executable code for constants" K.diag (
635 -- Scan.repeat (P.$$$ "(" |--
636 P.name -- P.arguments
638 >> (fn (raw_cs, seris) => Toplevel.keep (code raw_cs seris o Toplevel.theory_of))
642 OuterSyntax.command code_abstypeK "axiomatic abstypes for code generation" K.thy_decl (
643 (P.typ -- P.typ -- Scan.optional (P.$$$ "where" |-- Scan.repeat1
644 (P.term --| (P.$$$ "\\<equiv>" || P.$$$ "==") -- P.term)) [])
645 >> (Toplevel.theory o uncurry abstyp_e)
648 val code_constsubstP =
649 OuterSyntax.command code_constsubstK "axiomatic constant substitutions for code generation" K.thy_decl (
650 Scan.repeat1 (P.term --| (P.$$$ "\\<equiv>" || P.$$$ "==") -- P.term)
651 >> (Toplevel.theory o constsubst_e)
654 val _ = OuterSyntax.add_parsers [codeP, code_abstypeP, code_constsubstP];