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 |