src/HOL/Codegenerator_Test/code_test.ML
changeset 58348 2d47c7d10b62
parent 58039 469a375212c1
child 58415 8392d221bd91
equal deleted inserted replaced
58347:272ad6a47d6d 58348:2d47c7d10b62
    14   val end_markerN : string
    14   val end_markerN : string
    15   val test_terms : Proof.context -> term list -> string -> unit
    15   val test_terms : Proof.context -> term list -> string -> unit
    16   val test_targets : Proof.context -> term list -> string list -> unit list
    16   val test_targets : Proof.context -> term list -> string list -> unit list
    17   val test_code_cmd : string list -> string list -> Toplevel.state -> unit
    17   val test_code_cmd : string list -> string list -> Toplevel.state -> unit
    18 
    18 
    19   val eval_term : Proof.context -> term -> string -> unit
    19   val eval_term : string -> Proof.context -> term -> term
    20 
    20 
    21   val gen_driver :
    21   val gen_driver :
    22    (theory -> Path.T -> string list -> string ->
    22    (theory -> Path.T -> string list -> string ->
    23     {files : (Path.T * string) list,
    23     {files : (Path.T * string) list,
    24      compile_cmd : string option, run_cmd : string, mk_code_file : string -> Path.T})
    24      compile_cmd : string option, run_cmd : string, mk_code_file : string -> Path.T})
   250       Pretty.string_of (Pretty.block (Pretty.commas (map Pretty.str frees))))
   250       Pretty.string_of (Pretty.block (Pretty.commas (map Pretty.str frees))))
   251   in
   251   in
   252     test_targets ctxt ts targets; ()
   252     test_targets ctxt ts targets; ()
   253   end
   253   end
   254 
   254 
   255 
   255 fun eval_term target ctxt t =
   256 fun eval_term ctxt t target =
   256   let
   257   let
   257     val frees = Term.add_free_names t []
       
   258     val _ = if frees = [] then () else
       
   259       error ("Term contains free variables: " ^
       
   260       Pretty.string_of (Pretty.block (Pretty.commas (map Pretty.str frees))))
       
   261 
   258     val thy = Proof_Context.theory_of ctxt
   262     val thy = Proof_Context.theory_of ctxt
   259 
   263 
   260     val T_t = fastype_of t
   264     val T_t = fastype_of t
   261     val _ = if Sign.of_sort thy (T_t, @{sort term_of}) then () else error 
   265     val _ = if Sign.of_sort thy (T_t, @{sort term_of}) then () else error 
   262       ("Type " ^ Pretty.string_of (Syntax.pretty_typ ctxt T_t) ^ 
   266       ("Type " ^ Pretty.string_of (Syntax.pretty_typ ctxt T_t) ^ 
   264 
   268 
   265     val T = HOLogic.mk_prodT (@{typ bool}, Type (@{type_name option}, [@{typ unit} --> @{typ yxml_of_term}]))
   269     val T = HOLogic.mk_prodT (@{typ bool}, Type (@{type_name option}, [@{typ unit} --> @{typ yxml_of_term}]))
   266     val t' = HOLogic.mk_list T [HOLogic.mk_prod (@{term "False"}, mk_term_of [t])]
   270     val t' = HOLogic.mk_list T [HOLogic.mk_prod (@{term "False"}, mk_term_of [t])]
   267 
   271 
   268     val result = dynamic_value_strict ctxt t' target;
   272     val result = dynamic_value_strict ctxt t' target;
   269     val t_eval = case result of [(_, SOME [t])] => t | _ => error "Evaluation failed"
   273   in
   270   in
   274     case result of [(_, SOME [t])] => t | _ => error "Evaluation failed"
   271     Pretty.writeln (Syntax.pretty_term ctxt t_eval)
   275   end
   272   end
       
   273 
       
   274 fun eval_term_cmd raw_t target state =
       
   275   let
       
   276     val ctxt = Toplevel.context_of state;
       
   277     val t = Syntax.read_term ctxt raw_t;
       
   278     val frees = Term.add_free_names t []
       
   279     val _ = if frees = [] then () else
       
   280       error ("Term contains free variables: " ^
       
   281       Pretty.string_of (Pretty.block (Pretty.commas (map Pretty.str frees))))
       
   282   in
       
   283     eval_term ctxt t target
       
   284   end
       
   285 
       
   286 
   276 
   287 (* Generic driver *)
   277 (* Generic driver *)
   288 
   278 
   289 fun gen_driver mk_driver env_var env_var_dest compilerN ctxt (code_files, value_name) =
   279 fun gen_driver mk_driver env_var env_var_dest compilerN ctxt (code_files, value_name) =
   290   let
   280   let
   573 val _ = 
   563 val _ = 
   574   Outer_Syntax.command @{command_spec "test_code"}
   564   Outer_Syntax.command @{command_spec "test_code"}
   575     "compile test cases to target languages, execute them and report results"
   565     "compile test cases to target languages, execute them and report results"
   576       (test_codeP >> (fn (raw_ts, targets) => Toplevel.keep (test_code_cmd raw_ts targets)))
   566       (test_codeP >> (fn (raw_ts, targets) => Toplevel.keep (test_code_cmd raw_ts targets)))
   577 
   567 
   578 val eval_termP = Parse.term -- (@{keyword "in"} |-- Parse.name)
       
   579 
       
   580 val _ = 
       
   581   Outer_Syntax.command @{command_spec "eval_term"}
       
   582     "evaluate term in target language"
       
   583       (eval_termP >> (fn (raw_t, target) => Toplevel.keep (eval_term_cmd raw_t target)))
       
   584 
       
   585 val _ = Context.>> (Context.map_theory (
   568 val _ = Context.>> (Context.map_theory (
   586   fold add_driver
   569   fold add_driver
   587     [(polymlN, (evaluate_in_polyml, Code_ML.target_SML)),
   570     [(polymlN, (evaluate_in_polyml, Code_ML.target_SML)),
   588      (mltonN, (evaluate_in_mlton, Code_ML.target_SML)),
   571      (mltonN, (evaluate_in_mlton, Code_ML.target_SML)),
   589      (smlnjN, (evaluate_in_smlnj, Code_ML.target_SML)),
   572      (smlnjN, (evaluate_in_smlnj, Code_ML.target_SML)),
   590      (ocamlN, (evaluate_in_ocaml, Code_ML.target_OCaml)),
   573      (ocamlN, (evaluate_in_ocaml, Code_ML.target_OCaml)),
   591      (ghcN, (evaluate_in_ghc, Code_Haskell.target)),
   574      (ghcN, (evaluate_in_ghc, Code_Haskell.target)),
   592      (scalaN, (evaluate_in_scala, Code_Scala.target))]))
   575      (scalaN, (evaluate_in_scala, Code_Scala.target))]
       
   576     #> fold (fn target => Value.add_evaluator (target, eval_term target))
       
   577       [polymlN, mltonN, smlnjN, ocamlN, ghcN, scalaN]
       
   578     ))
   593 end
   579 end
   594 
   580