src/Tools/code/code_ml.ML
changeset 30947 dd551284a300
parent 30941 705bb15b2365
child 30962 f5fd07c558f9
equal deleted inserted replaced
30946:585c3f2622ea 30947:dd551284a300
     4 Serializer for SML and OCaml.
     4 Serializer for SML and OCaml.
     5 *)
     5 *)
     6 
     6 
     7 signature CODE_ML =
     7 signature CODE_ML =
     8 sig
     8 sig
     9   val eval_term: string * (unit -> 'a) option ref
     9   val eval_term: string option -> string * (unit -> term) option ref
       
    10     -> theory -> term -> string list -> term
       
    11   val eval: string option -> string * (unit -> 'a) option ref
    10     -> theory -> term -> string list -> 'a
    12     -> theory -> term -> string list -> 'a
       
    13   val target_Eval: string
    11   val setup: theory -> theory
    14   val setup: theory -> theory
    12 end;
    15 end;
    13 
    16 
    14 structure Code_ML : CODE_ML =
    17 structure Code_ML : CODE_ML =
    15 struct
    18 struct
    20 infixr 5 @@;
    23 infixr 5 @@;
    21 infixr 5 @|;
    24 infixr 5 @|;
    22 
    25 
    23 val target_SML = "SML";
    26 val target_SML = "SML";
    24 val target_OCaml = "OCaml";
    27 val target_OCaml = "OCaml";
       
    28 val target_Eval = "Eval";
    25 
    29 
    26 datatype ml_stmt =
    30 datatype ml_stmt =
    27     MLExc of string * int
    31     MLExc of string * int
    28   | MLVal of string * ((typscheme * iterm) * (thm * bool))
    32   | MLVal of string * ((typscheme * iterm) * (thm * bool))
    29   | MLFuns of (string * (typscheme * ((iterm list * iterm) * (thm * bool)) list)) list * string list
    33   | MLFuns of (string * (typscheme * ((iterm list * iterm) * (thm * bool)) list)) list * string list
   942 end; (*local*)
   946 end; (*local*)
   943 
   947 
   944 
   948 
   945 (** ML (system language) code for evaluation and instrumentalization **)
   949 (** ML (system language) code for evaluation and instrumentalization **)
   946 
   950 
   947 fun ml_code_of thy = Code_Target.serialize_custom thy (target_SML,
   951 fun eval_code_of some_target thy = Code_Target.serialize_custom thy (the_default target_Eval some_target,
   948     (fn _ => fn [] => serialize_ml target_SML (SOME (K ())) (K Pretty.chunks) pr_sml_stmt (SOME ""),
   952     (fn _ => fn [] => serialize_ml target_SML (SOME (K ())) (K Pretty.chunks) pr_sml_stmt (SOME ""),
   949   literals_sml));
   953   literals_sml));
   950 
   954 
   951 
   955 
   952 (* evaluation *)
   956 (* evaluation *)
   953 
   957 
   954 fun eval_term reff thy t args =
   958 fun gen_eval eval some_target reff thy t args =
   955   let
   959   let
   956     val ctxt = ProofContext.init thy;
   960     val ctxt = ProofContext.init thy;
   957     val _ = if null (Term.add_frees t []) then () else error ("Term "
   961     val _ = if null (Term.add_frees t []) then () else error ("Term "
   958       ^ quote (Syntax.string_of_term_global thy t)
   962       ^ quote (Syntax.string_of_term_global thy t)
   959       ^ " to be evaluated contains free variables");
   963       ^ " to be evaluated contains free variables");
   960     fun evaluator _ naming program ((_, ty), t) deps =
   964     fun evaluator naming program (((_, (_, ty)), _), t) deps =
   961       let
   965       let
   962         val _ = if Code_Thingol.contains_dictvar t then
   966         val _ = if Code_Thingol.contains_dictvar t then
   963           error "Term to be evaluated contains free dictionaries" else ();
   967           error "Term to be evaluated contains free dictionaries" else ();
   964         val value_name = "Value.VALUE.value"
   968         val value_name = "Value.VALUE.value"
   965         val program' = program
   969         val program' = program
   966           |> Graph.new_node (value_name,
   970           |> Graph.new_node (value_name,
   967               Code_Thingol.Fun (Term.dummy_patternN, (([], ty), [(([], t), (Drule.dummy_thm, true))])))
   971               Code_Thingol.Fun (Term.dummy_patternN, (([], ty), [(([], t), (Drule.dummy_thm, true))])))
   968           |> fold (curry Graph.add_edge value_name) deps;
   972           |> fold (curry Graph.add_edge value_name) deps;
   969         val (value_code, [SOME value_name']) = ml_code_of thy naming program' [value_name];
   973         val (value_code, [SOME value_name']) = eval_code_of some_target thy naming program' [value_name];
   970         val sml_code = "let\n" ^ value_code ^ "\nin " ^ value_name'
   974         val sml_code = "let\n" ^ value_code ^ "\nin " ^ value_name'
   971           ^ space_implode " " (map (enclose "(" ")") args) ^ " end";
   975           ^ space_implode " " (map (enclose "(" ")") args) ^ " end";
   972       in ML_Context.evaluate ctxt false reff sml_code end;
   976       in ML_Context.evaluate ctxt false reff sml_code end;
   973   in Code_Thingol.eval_term thy I evaluator t end;
   977   in eval thy I evaluator t end;
       
   978 
       
   979 fun eval_term thy = gen_eval Code_Thingol.eval_term thy;
       
   980 fun eval thy = gen_eval Code_Thingol.eval thy;
   974 
   981 
   975 
   982 
   976 (* instrumentalization by antiquotation *)
   983 (* instrumentalization by antiquotation *)
   977 
   984 
   978 local
   985 local
   986 val is_first_occ = fst o snd o CodeAntiqData.get;
   993 val is_first_occ = fst o snd o CodeAntiqData.get;
   987 
   994 
   988 fun delayed_code thy consts () =
   995 fun delayed_code thy consts () =
   989   let
   996   let
   990     val (consts', (naming, program)) = Code_Thingol.consts_program thy consts;
   997     val (consts', (naming, program)) = Code_Thingol.consts_program thy consts;
   991     val (ml_code, consts'') = ml_code_of thy naming program consts';
   998     val (ml_code, consts'') = eval_code_of NONE thy naming program consts';
   992     val const_tab = map2 (fn const => fn NONE =>
   999     val const_tab = map2 (fn const => fn NONE =>
   993       error ("Constant " ^ (quote o Code_Unit.string_of_const thy) const
  1000       error ("Constant " ^ (quote o Code_Unit.string_of_const thy) const
   994         ^ "\nhas a user-defined serialization")
  1001         ^ "\nhas a user-defined serialization")
   995       | SOME const' => (const, const')) consts consts''
  1002       | SOME const' => (const, const')) consts consts''
   996   in (ml_code, const_tab) end;
  1003   in (ml_code, const_tab) end;
  1044       pr_ocaml_module pr_ocaml_stmt module_name);
  1051       pr_ocaml_module pr_ocaml_stmt module_name);
  1045 
  1052 
  1046 val setup =
  1053 val setup =
  1047   Code_Target.add_target (target_SML, (isar_seri_sml, literals_sml))
  1054   Code_Target.add_target (target_SML, (isar_seri_sml, literals_sml))
  1048   #> Code_Target.add_target (target_OCaml, (isar_seri_ocaml, literals_ocaml))
  1055   #> Code_Target.add_target (target_OCaml, (isar_seri_ocaml, literals_ocaml))
       
  1056   #> Code_Target.extend_target (target_Eval, (target_SML, K I))
  1049   #> Code_Target.add_syntax_tyco target_SML "fun" (SOME (2, fn pr_typ => fn fxy => fn [ty1, ty2] =>
  1057   #> Code_Target.add_syntax_tyco target_SML "fun" (SOME (2, fn pr_typ => fn fxy => fn [ty1, ty2] =>
  1050       brackify_infix (1, R) fxy [
  1058       brackify_infix (1, R) fxy [
  1051         pr_typ (INFX (1, X)) ty1,
  1059         pr_typ (INFX (1, X)) ty1,
  1052         str "->",
  1060         str "->",
  1053         pr_typ (INFX (1, R)) ty2
  1061         pr_typ (INFX (1, R)) ty2