src/Tools/Code/code_target.ML
changeset 70002 0addec5ab4ad
parent 70001 6430327079c2
child 70009 435fb018e8ee
equal deleted inserted replaced
70001:6430327079c2 70002:0addec5ab4ad
    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: Path.T option option -> string -> string -> int option -> Token.T list
    14   val export_code_for: Path.T option option -> string -> string -> int option -> Token.T list
    15     -> Code_Thingol.program -> bool -> Code_Symbol.T list -> theory -> theory
    15     -> Code_Thingol.program -> bool -> Code_Symbol.T list -> local_theory -> local_theory
    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: string -> bool -> Token.T list
    20   val check_code_for: string -> bool -> Token.T list
    21     -> Code_Thingol.program -> bool -> Code_Symbol.T list -> theory -> theory
    21     -> Code_Thingol.program -> bool -> Code_Symbol.T list -> local_theory -> local_theory
    22 
    22 
    23   val export_code: bool -> string list
    23   val export_code: bool -> string list
    24     -> (((string * string) * Path.T option option) * Token.T list) list -> theory -> theory
    24     -> (((string * string) * Path.T option option) * Token.T list) list
       
    25     -> local_theory -> local_theory
    25   val export_code_cmd: bool -> string list
    26   val export_code_cmd: bool -> string list
    26     -> (((string * string) * (string * Position.T) option) * Token.T list) list -> theory -> theory
    27     -> (((string * string) * (string * Position.T) option) * Token.T list) list
       
    28     -> local_theory -> local_theory
    27   val produce_code: Proof.context -> bool -> string list
    29   val produce_code: Proof.context -> bool -> string list
    28     -> string -> string -> int option -> Token.T list -> (string list * string) list * string option list
    30     -> string -> string -> int option -> Token.T list -> (string list * string) list * string option list
    29   val present_code: Proof.context -> string list -> Code_Symbol.T list
    31   val present_code: Proof.context -> string list -> Code_Symbol.T list
    30     -> string -> string -> int option -> Token.T list -> string
    32     -> string -> string -> int option -> Token.T list -> string
    31   val check_code: bool -> string list -> ((string * bool) * Token.T list) list -> theory -> theory
    33   val check_code: bool -> string list -> ((string * bool) * Token.T list) list
       
    34     -> local_theory -> local_theory
    32 
    35 
    33   val generatedN: string
    36   val generatedN: string
    34   val compilation_text: Proof.context -> string -> Code_Thingol.program
    37   val compilation_text: Proof.context -> string -> Code_Thingol.program
    35     -> Code_Symbol.T list -> bool -> ((string * class list) list * Code_Thingol.itype) * Code_Thingol.iterm
    38     -> Code_Symbol.T list -> bool -> ((string * class list) list * Code_Thingol.itype) * Code_Thingol.iterm
    36     -> (string list * string) list * string
    39     -> (string list * string) list * string
   399 fun assert_module_name "" = error "Empty module name not allowed here"
   402 fun assert_module_name "" = error "Empty module name not allowed here"
   400   | assert_module_name module_name = module_name;
   403   | assert_module_name module_name = module_name;
   401 
   404 
   402 in
   405 in
   403 
   406 
   404 fun export_code_for some_file target_name module_name some_width args program all_public cs thy =
   407 fun export_code_for some_file target_name module_name some_width args program all_public cs lthy =
   405   let
   408   let
   406     val thy_ctxt = Proof_Context.init_global thy;
   409     val format = Code_Printer.format [] (the_width lthy some_width);
   407     val format = Code_Printer.format [] (the_width thy_ctxt some_width);
   410     val res = invoke_serializer lthy target_name module_name args program all_public cs;
   408     val res = invoke_serializer thy_ctxt target_name module_name args program all_public cs;
   411   in Local_Theory.background_theory (export_result some_file format res) lthy end;
   409   in export_result some_file format res thy end;
       
   410 
   412 
   411 fun produce_code_for ctxt target_name module_name some_width args =
   413 fun produce_code_for ctxt target_name module_name some_width args =
   412   let
   414   let
   413     val serializer = invoke_serializer ctxt target_name (assert_module_name module_name) args;
   415     val serializer = invoke_serializer ctxt target_name (assert_module_name module_name) args;
   414   in fn program => fn all_public => fn syms =>
   416   in fn program => fn all_public => fn syms =>
   421     val serializer = invoke_serializer ctxt target_name (assert_module_name module_name) args;
   423     val serializer = invoke_serializer ctxt target_name (assert_module_name module_name) args;
   422   in fn program => fn (syms, selects) =>
   424   in fn program => fn (syms, selects) =>
   423     present_result selects (the_width ctxt some_width) (serializer program false syms)
   425     present_result selects (the_width ctxt some_width) (serializer program false syms)
   424   end;
   426   end;
   425 
   427 
   426 fun check_code_for target_name strict args program all_public syms thy =
   428 fun check_code_for target_name strict args program all_public syms lthy =
   427   let
   429   let
   428     val thy_ctxt = Proof_Context.init_global thy;
   430     val { env_var, make_destination, make_command } = #check (the_language lthy target_name);
   429     val { env_var, make_destination, make_command } = #check (the_language thy_ctxt target_name);
       
   430     val format = Code_Printer.format [] 80;
   431     val format = Code_Printer.format [] 80;
   431     fun ext_check p =
   432     fun ext_check p =
   432       let
   433       let
   433         val destination = make_destination p;
   434         val destination = make_destination p;
   434         val thy' =
   435         val lthy' = lthy
   435           export_result (SOME (SOME destination)) format
   436           |> Local_Theory.background_theory
   436             (invoke_serializer thy_ctxt target_name generatedN args program all_public syms) thy;
   437             (export_result (SOME (SOME destination)) format
       
   438               (invoke_serializer lthy target_name generatedN args program all_public syms));
   437         val cmd = make_command generatedN;
   439         val cmd = make_command generatedN;
   438         val context_cmd = "cd " ^ File.bash_path p ^ " && " ^ cmd ^ " 2>&1";
   440         val context_cmd = "cd " ^ File.bash_path p ^ " && " ^ cmd ^ " 2>&1";
   439       in
   441       in
   440         if Isabelle_System.bash context_cmd <> 0
   442         if Isabelle_System.bash context_cmd <> 0
   441         then error ("Code check failed for " ^ target_name ^ ": " ^ cmd)
   443         then error ("Code check failed for " ^ target_name ^ ": " ^ cmd)
   442         else thy'
   444         else lthy'
   443       end;
   445       end;
   444   in
   446   in
   445     if not (env_var = "") andalso getenv env_var = "" then
   447     if not (env_var = "") andalso getenv env_var = "" then
   446       if strict
   448       if strict
   447       then error (env_var ^ " not set; cannot check code for " ^ target_name)
   449       then error (env_var ^ " not set; cannot check code for " ^ target_name)
   448       else (warning (env_var ^ " not set; skipped checking code for " ^ target_name); thy)
   450       else (warning (env_var ^ " not set; skipped checking code for " ^ target_name); lthy)
   449     else Isabelle_System.with_tmp_dir "Code_Test" ext_check
   451     else Isabelle_System.with_tmp_dir "Code_Test" ext_check
   450   end;
   452   end;
   451 
   453 
   452 fun dynamic_compilation_text prepared_serializer width prepared_program syms all_public ((vs, ty), t) =
   454 fun dynamic_compilation_text prepared_serializer width prepared_program syms all_public ((vs, ty), t) =
   453   let
   455   let
   493       val _ = Position.report pos Markup.language_path;
   495       val _ = Position.report pos Markup.language_path;
   494       val path = Path.explode s;
   496       val path = Path.explode s;
   495       val _ = Position.report pos (Markup.path (Path.smart_implode path));
   497       val _ = Position.report pos (Markup.path (Path.smart_implode path));
   496     in SOME path end;
   498     in SOME path end;
   497 
   499 
   498 fun export_code all_public cs seris thy =
   500 fun export_code all_public cs seris lthy =
   499   let
   501   let
   500     val thy_ctxt = Proof_Context.init_global thy;
   502     val program = Code_Thingol.consts_program lthy cs;
   501     val program = Code_Thingol.consts_program thy_ctxt cs;
   503   in
   502   in
   504     (seris, lthy) |-> fold (fn (((target_name, module_name), some_file), args) =>
   503     (seris, thy) |-> fold (fn (((target_name, module_name), some_file), args) =>
       
   504       export_code_for some_file target_name module_name NONE args
   505       export_code_for some_file target_name module_name NONE args
   505         program all_public (map Constant cs))
   506         program all_public (map Constant cs))
   506   end;
   507   end;
   507 
   508 
   508 fun export_code_cmd all_public raw_cs seris thy =
   509 fun export_code_cmd all_public raw_cs seris lthy =
   509   let
   510   let
   510     val thy_ctxt = Proof_Context.init_global thy;
   511     val cs = Code_Thingol.read_const_exprs lthy raw_cs;
   511     val cs = Code_Thingol.read_const_exprs thy_ctxt raw_cs;
   512   in export_code all_public cs ((map o apfst o apsnd o Option.map) prep_destination seris) lthy end;
   512   in export_code all_public cs ((map o apfst o apsnd o Option.map) prep_destination seris) thy end;
       
   513 
   513 
   514 fun produce_code ctxt all_public cs target_name some_width some_module_name args =
   514 fun produce_code ctxt all_public cs target_name some_width some_module_name args =
   515   let
   515   let
   516     val program = Code_Thingol.consts_program ctxt cs;
   516     val program = Code_Thingol.consts_program ctxt cs;
   517   in produce_code_for ctxt target_name some_width some_module_name args program all_public (map Constant cs) end;
   517   in produce_code_for ctxt target_name some_width some_module_name args program all_public (map Constant cs) end;
   519 fun present_code ctxt cs syms target_name some_width some_module_name args =
   519 fun present_code ctxt cs syms target_name some_width some_module_name args =
   520   let
   520   let
   521     val program = Code_Thingol.consts_program ctxt cs;
   521     val program = Code_Thingol.consts_program ctxt cs;
   522   in present_code_for ctxt target_name some_width some_module_name args program (map Constant cs, syms) end;
   522   in present_code_for ctxt target_name some_width some_module_name args program (map Constant cs, syms) end;
   523 
   523 
   524 fun check_code all_public cs seris thy =
   524 fun check_code all_public cs seris lthy =
   525   let
   525   let
   526     val thy_ctxt = Proof_Context.init_global thy;
   526     val program = Code_Thingol.consts_program lthy cs;
   527     val program = Code_Thingol.consts_program thy_ctxt cs;
   527   in
   528   in
   528     (seris, lthy) |-> fold (fn ((target_name, strict), args) =>
   529     (seris, thy) |-> fold (fn ((target_name, strict), args) =>
       
   530       check_code_for target_name strict args program all_public (map Constant cs))
   529       check_code_for target_name strict args program all_public (map Constant cs))
   531   end;
   530   end;
   532 
   531 
   533 fun check_code_cmd all_public raw_cs seris thy =
   532 fun check_code_cmd all_public raw_cs seris lthy =
   534   let val thy_ctxt = Proof_Context.init_global thy
   533   check_code all_public (Code_Thingol.read_const_exprs lthy raw_cs) seris lthy;
   535   in check_code all_public (Code_Thingol.read_const_exprs thy_ctxt raw_cs) seris thy end;
       
   536 
   534 
   537 
   535 
   538 (** serializer configuration **)
   536 (** serializer configuration **)
   539 
   537 
   540 (* reserved symbol names *)
   538 (* reserved symbol names *)
   701       Parse.string (Parse.minus >> K ()) (Parse.minus >> K ())
   699       Parse.string (Parse.minus >> K ()) (Parse.minus >> K ())
   702       (Parse.text -- Scan.optional (\<^keyword>\<open>for\<close> |-- parse_simple_symbols) [])
   700       (Parse.text -- Scan.optional (\<^keyword>\<open>for\<close> |-- parse_simple_symbols) [])
   703       >> (Toplevel.theory o fold set_printings_cmd));
   701       >> (Toplevel.theory o fold set_printings_cmd));
   704 
   702 
   705 val _ =
   703 val _ =
   706   Outer_Syntax.command \<^command_keyword>\<open>export_code\<close> "generate executable code for constants"
   704   Outer_Syntax.local_theory \<^command_keyword>\<open>export_code\<close> "generate executable code for constants"
   707     (Scan.optional (\<^keyword>\<open>open\<close> >> K true) false -- Scan.repeat1 Parse.term
   705     (Scan.optional (\<^keyword>\<open>open\<close> >> K true) false -- Scan.repeat1 Parse.term
   708       :|-- (fn args => (code_expr_checkingP args || code_expr_inP args)) >> Toplevel.theory);
   706       :|-- (fn args => (code_expr_checkingP args || code_expr_inP args)));
   709 
   707 
   710 end;
   708 end;
   711 
   709 
   712 local
   710 local
   713 
   711