src/Tools/code/code_target.ML
changeset 24621 97d403d9ab54
parent 24591 6509626eb2c9
child 24630 351a308ab58d
equal deleted inserted replaced
24620:40811901b998 24621:97d403d9ab54
    30   val add_pretty_imperative_monad_bind: string -> string -> theory -> theory;
    30   val add_pretty_imperative_monad_bind: string -> string -> theory -> theory;
    31 
    31 
    32   type serializer;
    32   type serializer;
    33   val add_serializer: string * serializer -> theory -> theory;
    33   val add_serializer: string * serializer -> theory -> theory;
    34   val get_serializer: theory -> string -> bool -> string option -> string option -> Args.T list
    34   val get_serializer: theory -> string -> bool -> string option -> string option -> Args.T list
    35     -> (theory -> string -> string) -> string list option -> CodeThingol.code -> unit;
    35     -> (theory -> string -> string) -> (string -> bool) -> string list option
       
    36     -> CodeThingol.code -> unit;
    36   val assert_serializer: theory -> string -> string;
    37   val assert_serializer: theory -> string -> string;
    37 
    38 
    38   val eval_verbose: bool ref;
    39   val eval_verbose: bool ref;
    39   val eval_term: theory -> (string * (unit -> 'a) option ref) -> CodeThingol.code
    40   val eval_invoke: theory -> (theory -> string -> string) -> (string -> bool)
    40     ->  CodeThingol.iterm * CodeThingol.itype -> string list -> 'a;
    41     -> (string * (unit -> 'a) option ref) -> CodeThingol.code
       
    42     -> CodeThingol.iterm * CodeThingol.itype -> string list -> 'a;
    41   val code_width: int ref;
    43   val code_width: int ref;
    42 
    44 
    43   val setup: theory -> theory;
    45   val setup: theory -> theory;
    44 end;
    46 end;
    45 
    47 
   298   | MLClass of string * ((class * string) list * (vname * (string * itype) list))
   300   | MLClass of string * ((class * string) list * (vname * (string * itype) list))
   299   | MLClassinst of string * ((class * (string * (vname * sort) list))
   301   | MLClassinst of string * ((class * (string * (vname * sort) list))
   300         * ((class * (string * (string * dict list list))) list
   302         * ((class * (string * (string * dict list list))) list
   301       * (string * const) list));
   303       * (string * const) list));
   302 
   304 
   303 fun pr_sml tyco_syntax const_syntax labelled_name init_syms deresolv is_cons ml_def =
   305 fun pr_sml allows_exception tyco_syntax const_syntax labelled_name init_syms deresolv is_cons ml_def =
   304   let
   306   let
   305     val pr_label_classrel = translate_string (fn "." => "__" | c => c) o NameSpace.qualifier;
   307     val pr_label_classrel = translate_string (fn "." => "__" | c => c) o NameSpace.qualifier;
   306     val pr_label_classop = NameSpace.base o NameSpace.qualifier;
   308     val pr_label_classop = NameSpace.base o NameSpace.qualifier;
   307     fun pr_dicts fxy ds =
   309     fun pr_dicts fxy ds =
   308       let
   310       let
   567   ] @ content @ [
   569   ] @ content @ [
   568     str "",
   570     str "",
   569     str ("end; (*struct " ^ name ^ "*)")
   571     str ("end; (*struct " ^ name ^ "*)")
   570   ]);
   572   ]);
   571 
   573 
   572 fun pr_ocaml tyco_syntax const_syntax labelled_name init_syms deresolv is_cons ml_def =
   574 fun pr_ocaml allows_exception tyco_syntax const_syntax labelled_name
       
   575     init_syms deresolv is_cons ml_def =
   573   let
   576   let
   574     fun pr_dicts fxy ds =
   577     fun pr_dicts fxy ds =
   575       let
   578       let
   576         fun pr_dictvar (v, (_, 1)) = "_" ^ first_upper v
   579         fun pr_dictvar (v, (_, 1)) = "_" ^ first_upper v
   577           | pr_dictvar (v, (i, _)) = "_" ^ first_upper v ^ string_of_int (i+1);
   580           | pr_dictvar (v, (i, _)) = "_" ^ first_upper v ^ string_of_int (i+1);
   856 
   859 
   857 val code_width = ref 80;
   860 val code_width = ref 80;
   858 fun code_output p = Pretty.setmp_margin (!code_width) Pretty.output p ^ "\n";
   861 fun code_output p = Pretty.setmp_margin (!code_width) Pretty.output p ^ "\n";
   859 
   862 
   860 fun seri_ml pr_def pr_modl module output labelled_name reserved_syms raw_module_alias module_prolog
   863 fun seri_ml pr_def pr_modl module output labelled_name reserved_syms raw_module_alias module_prolog
   861   (_ : string -> class_syntax option) tyco_syntax const_syntax code =
   864   allows_exception (_ : string -> class_syntax option) tyco_syntax const_syntax code =
   862   let
   865   let
   863     val module_alias = if is_some module then K module else raw_module_alias;
   866     val module_alias = if is_some module then K module else raw_module_alias;
   864     val is_cons = CodeThingol.is_cons code;
   867     val is_cons = CodeThingol.is_cons code;
   865     datatype node =
   868     datatype node =
   866         Def of string * ml_def option
   869         Def of string * ml_def option
  1012      of NONE => []
  1015      of NONE => []
  1013       | SOME p => [p, str ""];
  1016       | SOME p => [p, str ""];
  1014     fun pr_node prefix (Def (_, NONE)) =
  1017     fun pr_node prefix (Def (_, NONE)) =
  1015           NONE
  1018           NONE
  1016       | pr_node prefix (Def (_, SOME def)) =
  1019       | pr_node prefix (Def (_, SOME def)) =
  1017           SOME (pr_def tyco_syntax const_syntax labelled_name init_syms
  1020           SOME (pr_def allows_exception tyco_syntax const_syntax labelled_name init_syms
  1018             (deresolver prefix) is_cons def)
  1021             (deresolver prefix) is_cons def)
  1019       | pr_node prefix (Module (dmodlname, (_, nodes))) =
  1022       | pr_node prefix (Module (dmodlname, (_, nodes))) =
  1020           SOME (pr_modl dmodlname (the_prolog (NameSpace.implode (prefix @ [dmodlname]))
  1023           SOME (pr_modl dmodlname (the_prolog (NameSpace.implode (prefix @ [dmodlname]))
  1021             @ separate (str "") ((map_filter (pr_node (prefix @ [dmodlname]) o Graph.get_node nodes)
  1024             @ separate (str "") ((map_filter (pr_node (prefix @ [dmodlname]) o Graph.get_node nodes)
  1022                 o rev o flat o Graph.strong_conn) nodes)));
  1025                 o rev o flat o Graph.strong_conn) nodes)));
  1062 
  1065 
  1063 val pr_bind_haskell = gen_pr_bind pr_bind';
  1066 val pr_bind_haskell = gen_pr_bind pr_bind';
  1064 
  1067 
  1065 in
  1068 in
  1066 
  1069 
  1067 fun pr_haskell class_syntax tyco_syntax const_syntax labelled_name init_syms
  1070 fun pr_haskell allows_exception class_syntax tyco_syntax const_syntax labelled_name
  1068     deresolv_here deresolv is_cons deriving_show def =
  1071     init_syms deresolv_here deresolv is_cons deriving_show def =
  1069   let
  1072   let
  1070     fun class_name class = case class_syntax class
  1073     fun class_name class = case class_syntax class
  1071      of NONE => deresolv class
  1074      of NONE => deresolv class
  1072       | SOME (class, _) => class;
  1075       | SOME (class, _) => class;
  1073     fun classop_name class classop = case class_syntax class
  1076     fun classop_name class classop = case class_syntax class
  1292   in (1, pretty) end;
  1295   in (1, pretty) end;
  1293 
  1296 
  1294 end; (*local*)
  1297 end; (*local*)
  1295 
  1298 
  1296 fun seri_haskell module_prefix module destination string_classes labelled_name
  1299 fun seri_haskell module_prefix module destination string_classes labelled_name
  1297     reserved_syms raw_module_alias module_prolog class_syntax tyco_syntax const_syntax code =
  1300     reserved_syms raw_module_alias module_prolog
       
  1301     allows_exception class_syntax tyco_syntax const_syntax code =
  1298   let
  1302   let
  1299     val _ = Option.map File.check destination;
  1303     val _ = Option.map File.check destination;
  1300     val is_cons = CodeThingol.is_cons code;
  1304     val is_cons = CodeThingol.is_cons code;
  1301     val module_alias = if is_some module then K module else raw_module_alias;
  1305     val module_alias = if is_some module then K module else raw_module_alias;
  1302     val init_names = Name.make_context reserved_syms;
  1306     val init_names = Name.make_context reserved_syms;
  1363                     (maps snd cs)
  1367                     (maps snd cs)
  1364         and deriv' tycos (tyco `%% tys) = deriv tycos tyco
  1368         and deriv' tycos (tyco `%% tys) = deriv tycos tyco
  1365               andalso forall (deriv' tycos) tys
  1369               andalso forall (deriv' tycos) tys
  1366           | deriv' _ (ITyVar _) = true
  1370           | deriv' _ (ITyVar _) = true
  1367       in deriv [] tyco end;
  1371       in deriv [] tyco end;
  1368     fun seri_def qualified = pr_haskell class_syntax tyco_syntax const_syntax labelled_name init_syms
  1372     fun seri_def qualified = pr_haskell allows_exception class_syntax tyco_syntax
       
  1373       const_syntax labelled_name init_syms
  1369       deresolv_here (if qualified then deresolv else deresolv_here) is_cons
  1374       deresolv_here (if qualified then deresolv else deresolv_here) is_cons
  1370       (if string_classes then deriving_show else K false);
  1375       (if string_classes then deriving_show else K false);
  1371     fun write_module (SOME destination) modlname =
  1376     fun write_module (SOME destination) modlname =
  1372           let
  1377           let
  1373             val filename = case modlname
  1378             val filename = case modlname
  1426   end;
  1431   end;
  1427 
  1432 
  1428 
  1433 
  1429 (** diagnosis serializer **)
  1434 (** diagnosis serializer **)
  1430 
  1435 
  1431 fun seri_diagnosis labelled_name _ _ _ _ _ _ code =
  1436 fun seri_diagnosis labelled_name _ _ _ _ _ _ _ code =
  1432   let
  1437   let
  1433     val init_names = CodeName.make_vars [];
  1438     val init_names = CodeName.make_vars [];
  1434     fun pr_fun "fun" = SOME (2, fn pr_typ => fn fxy => fn [ty1, ty2] =>
  1439     fun pr_fun "fun" = SOME (2, fn pr_typ => fn fxy => fn [ty1, ty2] =>
  1435           brackify_infix (1, R) fxy [
  1440           brackify_infix (1, R) fxy [
  1436             pr_typ (INFX (1, X)) ty1,
  1441             pr_typ (INFX (1, X)) ty1,
  1437             str "->",
  1442             str "->",
  1438             pr_typ (INFX (1, R)) ty2
  1443             pr_typ (INFX (1, R)) ty2
  1439           ])
  1444           ])
  1440       | pr_fun _ = NONE
  1445       | pr_fun _ = NONE
  1441     val pr = pr_haskell (K NONE) pr_fun (K NONE) labelled_name init_names I I (K false) (K false);
  1446     val pr = pr_haskell (K true) (K NONE) pr_fun (K NONE) labelled_name init_names I I (K false) (K false);
  1442   in
  1447   in
  1443     []
  1448     []
  1444     |> Graph.fold (fn (name, (def, _)) => case try pr (name, def) of SOME p => cons p | NONE => I) code
  1449     |> Graph.fold (fn (name, (def, _)) => case try pr (name, def) of SOME p => cons p | NONE => I) code
  1445     |> Pretty.chunks2
  1450     |> Pretty.chunks2
  1446     |> code_output
  1451     |> code_output
  1493   -> Args.T list
  1498   -> Args.T list
  1494   -> (string -> string)
  1499   -> (string -> string)
  1495   -> string list
  1500   -> string list
  1496   -> (string -> string option)
  1501   -> (string -> string option)
  1497   -> (string -> Pretty.T option)
  1502   -> (string -> Pretty.T option)
       
  1503   -> (string -> bool)
  1498   -> (string -> class_syntax option)
  1504   -> (string -> class_syntax option)
  1499   -> (string -> typ_syntax option)
  1505   -> (string -> typ_syntax option)
  1500   -> (string -> term_syntax option)
  1506   -> (string -> term_syntax option)
  1501   -> CodeThingol.code -> unit;
  1507   -> CodeThingol.code -> unit;
  1502 
  1508 
  1568 val target_SML = "SML";
  1574 val target_SML = "SML";
  1569 val target_OCaml = "OCaml";
  1575 val target_OCaml = "OCaml";
  1570 val target_Haskell = "Haskell";
  1576 val target_Haskell = "Haskell";
  1571 val target_diag = "diag";
  1577 val target_diag = "diag";
  1572 
  1578 
  1573 fun get_serializer thy target permissive module file args labelled_name = fn cs =>
  1579 fun get_serializer thy target permissive module file args
       
  1580     labelled_name allows_exception = fn cs =>
  1574   let
  1581   let
  1575     val data = case Symtab.lookup (CodeTargetData.get thy) target
  1582     val data = case Symtab.lookup (CodeTargetData.get thy) target
  1576      of SOME data => data
  1583      of SOME data => data
  1577       | NONE => error ("Unknown code target language: " ^ quote target);
  1584       | NONE => error ("Unknown code target language: " ^ quote target);
  1578     val seri = the_serializer data;
  1585     val seri = the_serializer data;
  1587       | names => error ("No defining equations for " ^ commas (map (labelled_name thy) names));
  1594       | names => error ("No defining equations for " ^ commas (map (labelled_name thy) names));
  1588   in
  1595   in
  1589     project
  1596     project
  1590     #> check_empty_funs
  1597     #> check_empty_funs
  1591     #> seri module file args (labelled_name thy) reserved (Symtab.lookup alias) (Symtab.lookup prolog)
  1598     #> seri module file args (labelled_name thy) reserved (Symtab.lookup alias) (Symtab.lookup prolog)
  1592       (Symtab.lookup class) (Symtab.lookup tyco) (Symtab.lookup const)
  1599       allows_exception (Symtab.lookup class) (Symtab.lookup tyco) (Symtab.lookup const)
  1593   end;
  1600   end;
  1594 
  1601 
  1595 fun eval_term thy (ref_name, reff) code (t, ty) args =
  1602 fun eval_invoke thy labelled_name allows_exception (ref_name, reff) code (t, ty) args =
  1596   let
  1603   let
  1597     val val_name = "Isabelle_Eval.EVAL.EVAL";
  1604     val val_name = "Isabelle_Eval.EVAL.EVAL";
  1598     val val_name' = "Isabelle_Eval.EVAL";
  1605     val val_name' = "Isabelle_Eval.EVAL";
  1599     val val_name'_args = space_implode " " (val_name' :: map (enclose "(" ")") args);
  1606     val val_name'_args = space_implode " " (val_name' :: map (enclose "(" ")") args);
  1600     val seri = get_serializer thy "SML" false (SOME "Isabelle_Eval") NONE [] CodeName.labelled_name;
  1607     val seri = get_serializer thy "SML" false (SOME "Isabelle_Eval") NONE []
       
  1608       labelled_name allows_exception;
  1601     fun eval code = (
  1609     fun eval code = (
  1602       reff := NONE;
  1610       reff := NONE;
  1603       seri (SOME [val_name]) code;
  1611       seri (SOME [val_name]) code;
  1604       use_text "generated code for evaluation" Output.ml_output (!eval_verbose)
  1612       use_text "generated code for evaluation" Output.ml_output (!eval_verbose)
  1605         ("val _ = (" ^ ref_name ^ " := SOME (fn () => " ^ val_name'_args ^ "))");
  1613         ("val _ = (" ^ ref_name ^ " := SOME (fn () => " ^ val_name'_args ^ "))");