src/Tools/Code/code_target.ML
changeset 69624 e02bdf853a4c
parent 69623 ef02c5e051e5
child 69645 e4e5bc6ac214
equal deleted inserted replaced
69623:ef02c5e051e5 69624:e02bdf853a4c
     9   val cert_tyco: Proof.context -> string -> string
     9   val cert_tyco: Proof.context -> string -> string
    10   val read_tyco: Proof.context -> string -> string
    10   val read_tyco: Proof.context -> string -> string
    11 
    11 
    12   datatype pretty_modules = Singleton of string * Pretty.T | Hierarchy of (string list * Pretty.T) list;
    12   datatype pretty_modules = Singleton of string * Pretty.T | Hierarchy of (string list * Pretty.T) list;
    13 
    13 
    14   val export_code_for: Proof.context -> Path.T option -> string -> string -> int option -> Token.T list
    14   val export_code_for: Proof.context -> Path.T option option -> string -> string -> int option -> Token.T list
    15     -> Code_Thingol.program -> bool -> Code_Symbol.T list -> unit
    15     -> Code_Thingol.program -> bool -> Code_Symbol.T list -> unit
    16   val produce_code_for: Proof.context -> string -> string -> int option -> Token.T list
    16   val produce_code_for: Proof.context -> string -> string -> int option -> Token.T list
    17     -> Code_Thingol.program -> bool -> Code_Symbol.T list -> (string list * string) list * string option list
    17     -> Code_Thingol.program -> bool -> Code_Symbol.T list -> (string list * string) list * string option list
    18   val present_code_for: Proof.context -> string -> string -> int option -> Token.T list
    18   val present_code_for: Proof.context -> string -> string -> int option -> Token.T list
    19     -> Code_Thingol.program -> Code_Symbol.T list * Code_Symbol.T list -> string
    19     -> Code_Thingol.program -> Code_Symbol.T list * Code_Symbol.T list -> string
    20   val check_code_for: Proof.context -> string -> bool -> Token.T list
    20   val check_code_for: Proof.context -> string -> bool -> Token.T list
    21     -> Code_Thingol.program -> bool -> Code_Symbol.T list -> unit
    21     -> Code_Thingol.program -> bool -> Code_Symbol.T list -> unit
    22 
    22 
    23   val export_code: Proof.context -> bool -> string list
    23   val export_code: Proof.context -> bool -> string list
    24     -> (((string * string) * Path.T option) * Token.T list) list -> unit
    24     -> (((string * string) * Path.T option option) * Token.T list) list -> unit
    25   val produce_code: Proof.context -> bool -> string list
    25   val produce_code: Proof.context -> bool -> string list
    26     -> string -> string -> int option -> Token.T list -> (string list * string) list * string option list
    26     -> string -> string -> int option -> Token.T list -> (string list * string) list * string option list
    27   val present_code: Proof.context -> string list -> Code_Symbol.T list
    27   val present_code: Proof.context -> string list -> Code_Symbol.T list
    28     -> string -> string -> int option -> Token.T list -> string
    28     -> string -> string -> int option -> Token.T list -> string
    29   val check_code: Proof.context -> bool -> string list
    29   val check_code: Proof.context -> bool -> string list
   160     module_name: string }
   160     module_name: string }
   161   -> Code_Thingol.program
   161   -> Code_Thingol.program
   162   -> Code_Symbol.T list
   162   -> Code_Symbol.T list
   163   -> pretty_modules * (Code_Symbol.T -> string option);
   163   -> pretty_modules * (Code_Symbol.T -> string option);
   164 
   164 
       
   165 val generatedN = "Generated_Code";
       
   166 
   165 fun flat_modules selects width (Singleton (_, p)) =
   167 fun flat_modules selects width (Singleton (_, p)) =
   166       Code_Printer.format selects width p
   168       Code_Printer.format selects width p
   167   | flat_modules selects width (Hierarchy code_modules) =
   169   | flat_modules selects width (Hierarchy code_modules) =
   168       space_implode "\n\n" (map (Code_Printer.format selects width o snd) code_modules);
   170       space_implode "\n\n" (map (Code_Printer.format selects width o snd) code_modules);
   169 
   171 
   172   | export_to_file root width (Hierarchy code_modules) = (
   174   | export_to_file root width (Hierarchy code_modules) = (
   173       Isabelle_System.mkdirs root;
   175       Isabelle_System.mkdirs root;
   174       map (fn (names, p) => File.write (Path.appends (root :: map Path.basic names)) (Code_Printer.format [] width p)) code_modules;
   176       map (fn (names, p) => File.write (Path.appends (root :: map Path.basic names)) (Code_Printer.format [] width p)) code_modules;
   175       ());
   177       ());
   176 
   178 
   177 fun export_result ctxt some_root width (pretty_code, _) =
   179 fun export_to_exports thy width (Singleton (extension, p)) =
   178   case some_root of
   180       Export.export_raw thy (generatedN ^ "." ^ extension) [Code_Printer.format [] width p]
   179     NONE => (writeln (flat_modules [] width pretty_code); ())
   181   | export_to_exports thy width (Hierarchy code_modules) = (
   180   | SOME relative_root =>
   182       map (fn (names, p) => Export.export_raw thy (Path.implode (Path.make names))
       
   183         [Code_Printer.format [] width p]) code_modules;
       
   184       ());
       
   185 
       
   186 fun export_result ctxt some_file width (pretty_code, _) =
       
   187   (case some_file of
       
   188     NONE =>
       
   189       let
       
   190         val thy = Proof_Context.theory_of ctxt
       
   191       in export_to_exports thy width pretty_code end
       
   192   | SOME NONE => writeln (flat_modules [] width pretty_code)
       
   193   | SOME (SOME relative_root) =>
   181       let
   194       let
   182         val root = File.full_path (Resources.master_directory (Proof_Context.theory_of ctxt)) relative_root;
   195         val root = File.full_path (Resources.master_directory (Proof_Context.theory_of ctxt)) relative_root;
   183         val _ = File.check_dir (Path.dir root);
   196         val _ = File.check_dir (Path.dir root);
   184       in export_to_file root width pretty_code end;
   197       in export_to_file root width pretty_code end);
   185 
   198 
   186 fun produce_result syms width (Singleton (_, p), deresolve) =
   199 fun produce_result syms width (Singleton (_, p), deresolve) =
   187       ([([], Code_Printer.format [] width p)], map deresolve syms)
   200       ([([], Code_Printer.format [] width p)], map deresolve syms)
   188   | produce_result syms width (Hierarchy code_modules, deresolve) =
   201   | produce_result syms width (Hierarchy code_modules, deresolve) =
   189       ((map o apsnd) (Code_Printer.format [] width) code_modules, map deresolve syms);
   202       ((map o apsnd) (Code_Printer.format [] width) code_modules, map deresolve syms);
   374 fun assert_module_name "" = error "Empty module name not allowed here"
   387 fun assert_module_name "" = error "Empty module name not allowed here"
   375   | assert_module_name module_name = module_name;
   388   | assert_module_name module_name = module_name;
   376 
   389 
   377 in
   390 in
   378 
   391 
   379 val generatedN = "Generated_Code";
   392 fun export_code_for ctxt some_file target_name module_name some_width args =
   380 
   393   export_result ctxt some_file (the_width ctxt some_width)
   381 fun export_code_for ctxt some_root target_name module_name some_width args =
       
   382   export_result ctxt some_root (the_width ctxt some_width)
       
   383   ooo invoke_serializer ctxt target_name module_name args;
   394   ooo invoke_serializer ctxt target_name module_name args;
   384 
   395 
   385 fun produce_code_for ctxt target_name module_name some_width args =
   396 fun produce_code_for ctxt target_name module_name some_width args =
   386   let
   397   let
   387     val serializer = invoke_serializer ctxt target_name (assert_module_name module_name) args;
   398     val serializer = invoke_serializer ctxt target_name (assert_module_name module_name) args;
   402     val { env_var, make_destination, make_command } =
   413     val { env_var, make_destination, make_command } =
   403       (#check o the_language ctxt) target_name;
   414       (#check o the_language ctxt) target_name;
   404     fun ext_check p =
   415     fun ext_check p =
   405       let
   416       let
   406         val destination = make_destination p;
   417         val destination = make_destination p;
   407         val _ = export_result ctxt (SOME destination) 80
   418         val _ = export_result ctxt (SOME (SOME destination)) 80
   408           (invoke_serializer ctxt target_name generatedN args program all_public syms)
   419           (invoke_serializer ctxt target_name generatedN args program all_public syms)
   409         val cmd = make_command generatedN;
   420         val cmd = make_command generatedN;
   410       in
   421       in
   411         if Isabelle_System.bash ("cd " ^ File.bash_path p ^ " && " ^ cmd ^ " 2>&1") <> 0
   422         if Isabelle_System.bash ("cd " ^ File.bash_path p ^ " && " ^ cmd ^ " 2>&1") <> 0
   412         then error ("Code check failed for " ^ target_name ^ ": " ^ cmd)
   423         then error ("Code check failed for " ^ target_name ^ ": " ^ cmd)
   467     in SOME path end;
   478     in SOME path end;
   468 
   479 
   469 fun export_code ctxt all_public cs seris =
   480 fun export_code ctxt all_public cs seris =
   470   let
   481   let
   471     val program = Code_Thingol.consts_program ctxt cs;
   482     val program = Code_Thingol.consts_program ctxt cs;
   472     val _ = map (fn (((target_name, module_name), some_root), args) =>
   483     val _ = map (fn (((target_name, module_name), some_file), args) =>
   473       export_code_for ctxt some_root target_name module_name NONE args program all_public (map Constant cs)) seris;
   484       export_code_for ctxt some_file target_name module_name NONE args program all_public (map Constant cs)) seris;
   474   in () end;
   485   in () end;
   475 
   486 
   476 fun export_code_cmd all_public raw_cs seris ctxt =
   487 fun export_code_cmd all_public raw_cs seris ctxt =
   477   export_code ctxt all_public
   488   export_code ctxt all_public
   478     (Code_Thingol.read_const_exprs ctxt raw_cs)
   489     (Code_Thingol.read_const_exprs ctxt raw_cs)
   479     ((map o apfst o apsnd) prep_destination seris);
   490     ((map o apfst o apsnd o Option.map) prep_destination seris);
   480 
   491 
   481 fun produce_code ctxt all_public cs target_name some_width some_module_name args =
   492 fun produce_code ctxt all_public cs target_name some_width some_module_name args =
   482   let
   493   let
   483     val program = Code_Thingol.consts_program ctxt cs;
   494     val program = Code_Thingol.consts_program ctxt cs;
   484   in produce_code_for ctxt target_name some_width some_module_name args program all_public (map Constant cs) end;
   495   in produce_code_for ctxt target_name some_width some_module_name args program all_public (map Constant cs) end;
   679 val code_expr_argsP = Scan.optional (\<^keyword>\<open>(\<close> |-- Parse.args --| \<^keyword>\<open>)\<close>) [];
   690 val code_expr_argsP = Scan.optional (\<^keyword>\<open>(\<close> |-- Parse.args --| \<^keyword>\<open>)\<close>) [];
   680 
   691 
   681 fun code_expr_inP all_public raw_cs =
   692 fun code_expr_inP all_public raw_cs =
   682   Scan.repeat (\<^keyword>\<open>in\<close> |-- Parse.!!! (Parse.name
   693   Scan.repeat (\<^keyword>\<open>in\<close> |-- Parse.!!! (Parse.name
   683     -- Scan.optional (\<^keyword>\<open>module_name\<close> |-- Parse.name) ""
   694     -- Scan.optional (\<^keyword>\<open>module_name\<close> |-- Parse.name) ""
   684     -- Scan.optional (\<^keyword>\<open>file\<close> |-- Parse.position Parse.path) ("", Position.none)
   695     -- Scan.option (\<^keyword>\<open>file\<close> |-- Parse.position Parse.path)
   685     -- code_expr_argsP))
   696     -- code_expr_argsP))
   686       >> (fn seri_args => export_code_cmd all_public raw_cs seri_args);
   697       >> (fn seri_args => export_code_cmd all_public raw_cs seri_args);
   687 
   698 
   688 fun code_expr_checkingP all_public raw_cs =
   699 fun code_expr_checkingP all_public raw_cs =
   689   (\<^keyword>\<open>checking\<close> |-- Parse.!!!
   700   (\<^keyword>\<open>checking\<close> |-- Parse.!!!