src/HOL/Library/code_test.ML
changeset 72275 f7189b7f5567
parent 72274 a1098a183f4a
child 72276 dfe150a246e6
equal deleted inserted replaced
72274:a1098a183f4a 72275:f7189b7f5567
   148 
   148 
   149 val overlord = Attrib.setup_config_bool \<^binding>\<open>code_test_overlord\<close> (K false)
   149 val overlord = Attrib.setup_config_bool \<^binding>\<open>code_test_overlord\<close> (K false)
   150 
   150 
   151 fun with_overlord_dir name f =
   151 fun with_overlord_dir name f =
   152   let
   152   let
   153     val path =
   153     val dir =
   154       Path.append (Path.explode "$ISABELLE_HOME_USER") (Path.basic (name ^ serial_string ()))
   154       Path.append (Path.explode "$ISABELLE_HOME_USER") (Path.basic (name ^ serial_string ()))
   155     val _ = Isabelle_System.mkdirs path
   155     val _ = Isabelle_System.mkdirs dir
   156   in Exn.release (Exn.capture f path) end
   156   in Exn.release (Exn.capture f dir) end
   157 
   157 
   158 fun dynamic_value_strict ctxt t compiler =
   158 fun dynamic_value_strict ctxt t compiler =
   159   let
   159   let
   160     val thy = Proof_Context.theory_of ctxt
   160     val thy = Proof_Context.theory_of ctxt
   161     val (driver, target) =
   161     val (driver, target) =
   298           in
   298           in
   299             if ret = 0 then ()
   299             if ret = 0 then ()
   300             else error ("Compilation with " ^ compilerN ^ " failed:\n" ^ cmd ^ "\n" ^ out)
   300             else error ("Compilation with " ^ compilerN ^ " failed:\n" ^ cmd ^ "\n" ^ out)
   301           end
   301           end
   302 
   302 
   303     fun run path =
   303     fun run dir =
   304       let
   304       let
   305         val modules = map fst code_files
   305         val modules = map fst code_files
   306         val {files, compile_cmd, run_cmd, mk_code_file} = mk_driver ctxt path modules value_name
   306         val {files, compile_cmd, run_cmd, mk_code_file} = mk_driver ctxt dir modules value_name
   307 
   307 
   308         val _ = List.app (fn (name, code) => File.write (mk_code_file name) code) code_files
   308         val _ = List.app (fn (name, code) => File.write (mk_code_file name) code) code_files
   309         val _ = List.app (fn (name, content) => File.write name content) files
   309         val _ = List.app (fn (name, content) => File.write name content) files
   310 
   310 
   311         val _ = compile compile_cmd
   311         val _ = compile compile_cmd
   323 
   323 
   324 val polymlN = "PolyML"
   324 val polymlN = "PolyML"
   325 
   325 
   326 val evaluate_in_polyml =
   326 val evaluate_in_polyml =
   327   evaluate NONE polymlN
   327   evaluate NONE polymlN
   328     (fn _ => fn path => fn _ => fn value_name =>
   328     (fn _ => fn dir => fn _ => fn value_name =>
   329       let
   329       let
   330         val generatedN = "generated.sml"
   330         val generatedN = "generated.sml"
   331         val driverN = "driver.sml"
   331         val driverN = "driver.sml"
   332 
   332 
   333         val code_path = Path.append path (Path.basic generatedN)
   333         val code_path = Path.append dir (Path.basic generatedN)
   334         val driver_path = Path.append path (Path.basic driverN)
   334         val driver_path = Path.append dir (Path.basic driverN)
   335         val driver =
   335         val driver =
   336           "fun main prog_name = \n" ^
   336           "fun main prog_name = \n" ^
   337           "  let\n" ^
   337           "  let\n" ^
   338           "    fun format_term NONE = \"\"\n" ^
   338           "    fun format_term NONE = \"\"\n" ^
   339           "      | format_term (SOME t) = t ();\n" ^
   339           "      | format_term (SOME t) = t ();\n" ^
   362 val mltonN = "MLton"
   362 val mltonN = "MLton"
   363 val ISABELLE_MLTON = "ISABELLE_MLTON"
   363 val ISABELLE_MLTON = "ISABELLE_MLTON"
   364 
   364 
   365 val evaluate_in_mlton =
   365 val evaluate_in_mlton =
   366   evaluate (SOME (ISABELLE_MLTON, "MLton executable")) mltonN
   366   evaluate (SOME (ISABELLE_MLTON, "MLton executable")) mltonN
   367     (fn _ => fn path => fn _ => fn value_name =>
   367     (fn _ => fn dir => fn _ => fn value_name =>
   368       let
   368       let
   369         val generatedN = "generated.sml"
   369         val generatedN = "generated.sml"
   370         val driverN = "driver.sml"
   370         val driverN = "driver.sml"
   371         val projectN = "test"
   371         val projectN = "test"
   372         val ml_basisN = projectN ^ ".mlb"
   372         val ml_basisN = projectN ^ ".mlb"
   373 
   373 
   374         val code_path = Path.append path (Path.basic generatedN)
   374         val code_path = Path.append dir (Path.basic generatedN)
   375         val driver_path = Path.append path (Path.basic driverN)
   375         val driver_path = Path.append dir (Path.basic driverN)
   376         val ml_basis_path = Path.append path (Path.basic ml_basisN)
   376         val ml_basis_path = Path.append dir (Path.basic ml_basisN)
   377         val driver =
   377         val driver =
   378           "fun format_term NONE = \"\"\n" ^
   378           "fun format_term NONE = \"\"\n" ^
   379           "  | format_term (SOME t) = t ();\n" ^
   379           "  | format_term (SOME t) = t ();\n" ^
   380           "fun format (true, _) = \"" ^ successN ^ "\\n\"\n" ^
   380           "fun format (true, _) = \"" ^ successN ^ "\\n\"\n" ^
   381           "  | format (false, to) = \"" ^ failureN ^ "\" ^ format_term to ^ \"\\n\";\n" ^
   381           "  | format (false, to) = \"" ^ failureN ^ "\" ^ format_term to ^ \"\\n\";\n" ^
   387       in
   387       in
   388        {files = [(driver_path, driver), (ml_basis_path, ml_basis)],
   388        {files = [(driver_path, driver), (ml_basis_path, ml_basis)],
   389         compile_cmd =
   389         compile_cmd =
   390           File.bash_path (Path.variable ISABELLE_MLTON) ^
   390           File.bash_path (Path.variable ISABELLE_MLTON) ^
   391             " -default-type intinf " ^ File.bash_path ml_basis_path,
   391             " -default-type intinf " ^ File.bash_path ml_basis_path,
   392         run_cmd = File.bash_path (Path.append path (Path.basic projectN)),
   392         run_cmd = File.bash_path (Path.append dir (Path.basic projectN)),
   393         mk_code_file = K code_path}
   393         mk_code_file = K code_path}
   394       end)
   394       end)
   395 
   395 
   396 
   396 
   397 (* driver for SML/NJ *)
   397 (* driver for SML/NJ *)
   399 val smlnjN = "SMLNJ"
   399 val smlnjN = "SMLNJ"
   400 val ISABELLE_SMLNJ = "ISABELLE_SMLNJ"
   400 val ISABELLE_SMLNJ = "ISABELLE_SMLNJ"
   401 
   401 
   402 val evaluate_in_smlnj =
   402 val evaluate_in_smlnj =
   403   evaluate (SOME (ISABELLE_SMLNJ, "SMLNJ executable")) smlnjN
   403   evaluate (SOME (ISABELLE_SMLNJ, "SMLNJ executable")) smlnjN
   404     (fn _ => fn path => fn _ => fn value_name =>
   404     (fn _ => fn dir => fn _ => fn value_name =>
   405       let
   405       let
   406         val generatedN = "generated.sml"
   406         val generatedN = "generated.sml"
   407         val driverN = "driver.sml"
   407         val driverN = "driver.sml"
   408 
   408 
   409         val code_path = Path.append path (Path.basic generatedN)
   409         val code_path = Path.append dir (Path.basic generatedN)
   410         val driver_path = Path.append path (Path.basic driverN)
   410         val driver_path = Path.append dir (Path.basic driverN)
   411         val driver =
   411         val driver =
   412           "structure Test = struct\n" ^
   412           "structure Test = struct\n" ^
   413           "fun main prog_name =\n" ^
   413           "fun main prog_name =\n" ^
   414           "  let\n" ^
   414           "  let\n" ^
   415           "    fun format_term NONE = \"\"\n" ^
   415           "    fun format_term NONE = \"\"\n" ^
   443 val ocamlN = "OCaml"
   443 val ocamlN = "OCaml"
   444 val ISABELLE_OCAMLFIND = "ISABELLE_OCAMLFIND"
   444 val ISABELLE_OCAMLFIND = "ISABELLE_OCAMLFIND"
   445 
   445 
   446 val evaluate_in_ocaml =
   446 val evaluate_in_ocaml =
   447   evaluate (SOME (ISABELLE_OCAMLFIND, "ocamlfind executable")) ocamlN
   447   evaluate (SOME (ISABELLE_OCAMLFIND, "ocamlfind executable")) ocamlN
   448     (fn _ => fn path => fn _ => fn value_name =>
   448     (fn _ => fn dir => fn _ => fn value_name =>
   449       let
   449       let
   450         val generatedN = "generated.ml"
   450         val generatedN = "generated.ml"
   451         val driverN = "driver.ml"
   451         val driverN = "driver.ml"
   452 
   452 
   453         val code_path = Path.append path (Path.basic generatedN)
   453         val code_path = Path.append dir (Path.basic generatedN)
   454         val driver_path = Path.append path (Path.basic driverN)
   454         val driver_path = Path.append dir (Path.basic driverN)
   455         val driver =
   455         val driver =
   456           "let format_term = function\n" ^
   456           "let format_term = function\n" ^
   457           "  | None -> \"\"\n" ^
   457           "  | None -> \"\"\n" ^
   458           "  | Some t -> t ();;\n" ^
   458           "  | Some t -> t ();;\n" ^
   459           "let format = function\n" ^
   459           "let format = function\n" ^
   464           "  let _ = print_string \"" ^ start_markerN ^ "\" in\n" ^
   464           "  let _ = print_string \"" ^ start_markerN ^ "\" in\n" ^
   465           "  let _ = List.map (fun x -> print_string (format x)) result in\n" ^
   465           "  let _ = List.map (fun x -> print_string (format x)) result in\n" ^
   466           "  print_string \"" ^ end_markerN ^ "\";;\n" ^
   466           "  print_string \"" ^ end_markerN ^ "\";;\n" ^
   467           "main ();;"
   467           "main ();;"
   468 
   468 
   469         val compiled_path = Path.append path (Path.basic "test")
   469         val compiled_path = Path.append dir (Path.basic "test")
   470       in
   470       in
   471        {files = [(driver_path, driver)],
   471        {files = [(driver_path, driver)],
   472         compile_cmd =
   472         compile_cmd =
   473           "\"$ISABELLE_OCAMLFIND\" ocamlopt -w pu -package zarith -linkpkg" ^
   473           "\"$ISABELLE_OCAMLFIND\" ocamlopt -w pu -package zarith -linkpkg" ^
   474           " -o " ^ File.bash_path compiled_path ^ " -I " ^ File.bash_path path ^ " " ^
   474           " -o " ^ File.bash_path compiled_path ^ " -I " ^ File.bash_path dir ^ " " ^
   475           File.bash_path code_path ^ " " ^ File.bash_path driver_path ^ " </dev/null",
   475           File.bash_path code_path ^ " " ^ File.bash_path driver_path ^ " </dev/null",
   476         run_cmd = File.bash_path compiled_path,
   476         run_cmd = File.bash_path compiled_path,
   477         mk_code_file = K code_path}
   477         mk_code_file = K code_path}
   478       end)
   478       end)
   479 
   479 
   485 
   485 
   486 val ghc_options = Attrib.setup_config_string \<^binding>\<open>code_test_ghc\<close> (K "")
   486 val ghc_options = Attrib.setup_config_string \<^binding>\<open>code_test_ghc\<close> (K "")
   487 
   487 
   488 val evaluate_in_ghc =
   488 val evaluate_in_ghc =
   489   evaluate (SOME (ISABELLE_GHC, "GHC executable")) ghcN
   489   evaluate (SOME (ISABELLE_GHC, "GHC executable")) ghcN
   490     (fn ctxt => fn path => fn modules => fn value_name =>
   490     (fn ctxt => fn dir => fn modules => fn value_name =>
   491       let
   491       let
   492         val driverN = "Main.hs"
   492         val driverN = "Main.hs"
   493 
   493 
   494         fun mk_code_file name = Path.append path (Path.basic name)
   494         fun mk_code_file name = Path.append dir (Path.basic name)
   495         val driver_path = Path.append path (Path.basic driverN)
   495         val driver_path = Path.append dir (Path.basic driverN)
   496         val driver =
   496         val driver =
   497           "module Main where {\n" ^
   497           "module Main where {\n" ^
   498           implode (map (fn module => "import qualified " ^ unsuffix ".hs" module ^ ";\n") modules) ^
   498           implode (map (fn module => "import qualified " ^ unsuffix ".hs" module ^ ";\n") modules) ^
   499           "main = do {\n" ^
   499           "main = do {\n" ^
   500           "    let {\n" ^
   500           "    let {\n" ^
   508           "    Prelude.mapM_ (putStr . format) result;\n" ^
   508           "    Prelude.mapM_ (putStr . format) result;\n" ^
   509           "    Prelude.putStr \"" ^ end_markerN ^ "\";\n" ^
   509           "    Prelude.putStr \"" ^ end_markerN ^ "\";\n" ^
   510           "  }\n" ^
   510           "  }\n" ^
   511           "}\n"
   511           "}\n"
   512 
   512 
   513         val compiled_path = Path.append path (Path.basic "test")
   513         val compiled_path = Path.append dir (Path.basic "test")
   514       in
   514       in
   515        {files = [(driver_path, driver)],
   515        {files = [(driver_path, driver)],
   516         compile_cmd =
   516         compile_cmd =
   517           "\"$ISABELLE_GHC\" " ^ Code_Haskell.language_params ^ " " ^
   517           "\"$ISABELLE_GHC\" " ^ Code_Haskell.language_params ^ " " ^
   518           Config.get ctxt ghc_options ^ " -o " ^
   518           Config.get ctxt ghc_options ^ " -o " ^
   519           Bash.string (File.platform_path compiled_path) ^ " " ^
   519           Bash.string (File.platform_path compiled_path) ^ " " ^
   520           Bash.string (File.platform_path driver_path) ^ " -i" ^
   520           Bash.string (File.platform_path driver_path) ^ " -i" ^
   521           Bash.string (File.platform_path path),
   521           Bash.string (File.platform_path dir),
   522         run_cmd = File.bash_path compiled_path,
   522         run_cmd = File.bash_path compiled_path,
   523         mk_code_file = mk_code_file}
   523         mk_code_file = mk_code_file}
   524       end)
   524       end)
   525 
   525 
   526 
   526 
   527 (* driver for Scala *)
   527 (* driver for Scala *)
   528 
   528 
   529 val scalaN = "Scala"
   529 val scalaN = "Scala"
   530 
   530 
   531 val evaluate_in_scala = evaluate NONE scalaN
   531 val evaluate_in_scala = evaluate NONE scalaN
   532   (fn _ => fn path => fn _ => fn value_name =>
   532   (fn _ => fn dir => fn _ => fn value_name =>
   533     let
   533     let
   534       val generatedN = "Generated_Code"
   534       val generatedN = "Generated_Code"
   535       val driverN = "Driver.scala"
   535       val driverN = "Driver.scala"
   536 
   536 
   537       val code_path = Path.append path (Path.basic (generatedN ^ ".scala"))
   537       val code_path = Path.append dir (Path.basic (generatedN ^ ".scala"))
   538       val driver_path = Path.append path (Path.basic driverN)
   538       val driver_path = Path.append dir (Path.basic driverN)
   539       val driver =
   539       val driver =
   540         "import " ^ generatedN ^ "._\n" ^
   540         "import " ^ generatedN ^ "._\n" ^
   541         "object Test {\n" ^
   541         "object Test {\n" ^
   542         "  def format_term(x : Option[Unit => String]) : String = x match {\n" ^
   542         "  def format_term(x : Option[Unit => String]) : String = x match {\n" ^
   543         "    case None => \"\"\n" ^
   543         "    case None => \"\"\n" ^
   555         "  }\n" ^
   555         "  }\n" ^
   556         "}\n"
   556         "}\n"
   557     in
   557     in
   558      {files = [(driver_path, driver)],
   558      {files = [(driver_path, driver)],
   559       compile_cmd =
   559       compile_cmd =
   560         "isabelle_scala scalac $ISABELLE_SCALAC_OPTIONS -d " ^ Bash.string (File.platform_path path) ^
   560         "isabelle_scala scalac $ISABELLE_SCALAC_OPTIONS -d " ^ Bash.string (File.platform_path dir) ^
   561         " -classpath " ^ Bash.string (File.platform_path path) ^ " " ^
   561         " -classpath " ^ Bash.string (File.platform_path dir) ^ " " ^
   562         Bash.string (File.platform_path code_path) ^ " " ^
   562         Bash.string (File.platform_path code_path) ^ " " ^
   563         Bash.string (File.platform_path driver_path),
   563         Bash.string (File.platform_path driver_path),
   564       run_cmd = "isabelle_scala scala -cp " ^ Bash.string (File.platform_path path) ^ " Test",
   564       run_cmd = "isabelle_scala scala -cp " ^ Bash.string (File.platform_path dir) ^ " Test",
   565       mk_code_file = K code_path}
   565       mk_code_file = K code_path}
   566     end)
   566     end)
   567 
   567 
   568 
   568 
   569 (* command setup *)
   569 (* command setup *)