src/HOL/Library/code_test.ML
author haftmann
Fri, 09 Jan 2015 08:36:59 +0100
changeset 59323 468bd3aedfa1
parent 58832 ec9550bd5fd7
child 59720 f893472fff31
permissions -rw-r--r--
modernized and more uniform style
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
58039
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
     1
(*  Title:      Code_Test.ML
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
     2
    Author:     Andreas Lochbihler, ETH Zurich
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
     3
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
     4
Test infrastructure for the code generator
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
     5
*)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
     6
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
     7
signature CODE_TEST = sig
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
     8
  val add_driver : string * ((Proof.context -> (string * string) list * string -> Path.T -> string) * string) -> theory -> theory
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
     9
  val get_driver : theory -> string -> ((Proof.context -> (string * string) list * string -> Path.T -> string) * string) option
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    10
  val overlord : bool Config.T
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    11
  val successN : string
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    12
  val failureN : string
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    13
  val start_markerN : string
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    14
  val end_markerN : string
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    15
  val test_terms : Proof.context -> term list -> string -> unit
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    16
  val test_targets : Proof.context -> term list -> string list -> unit list
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    17
  val test_code_cmd : string list -> string list -> Toplevel.state -> unit
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    18
58348
2d47c7d10b62 add target language evaluators for the value command;
Andreas Lochbihler
parents: 58039
diff changeset
    19
  val eval_term : string -> Proof.context -> term -> term
58039
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    20
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    21
  val gen_driver :
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    22
   (theory -> Path.T -> string list -> string ->
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    23
    {files : (Path.T * string) list,
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    24
     compile_cmd : string option, run_cmd : string, mk_code_file : string -> Path.T})
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    25
   -> string -> string -> string
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    26
   -> theory -> (string * string) list * string -> Path.T -> string
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    27
58415
8392d221bd91 clarified ISABELLE_POLYML;
wenzelm
parents: 58348
diff changeset
    28
  val ISABELLE_POLYML : string
58039
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    29
  val polymlN : string
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    30
  val evaluate_in_polyml : Proof.context -> (string * string) list * string -> Path.T -> string
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    31
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    32
  val mltonN : string
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    33
  val ISABELLE_MLTON : string
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    34
  val evaluate_in_mlton : Proof.context -> (string * string) list * string -> Path.T -> string
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    35
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    36
  val smlnjN : string
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    37
  val ISABELLE_SMLNJ : string
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    38
  val evaluate_in_smlnj : Proof.context -> (string * string) list * string -> Path.T -> string
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    39
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    40
  val ocamlN : string
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    41
  val ISABELLE_OCAMLC : string
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    42
  val evaluate_in_ocaml : Proof.context -> (string * string) list * string -> Path.T -> string
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    43
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    44
  val ghcN : string
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    45
  val ISABELLE_GHC : string
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    46
  val ghc_options : string Config.T
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    47
  val evaluate_in_ghc : Proof.context -> (string * string) list * string -> Path.T -> string
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    48
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    49
  val scalaN : string
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    50
  val ISABELLE_SCALA : string
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    51
  val evaluate_in_scala : Proof.context -> (string * string) list * string -> Path.T -> string
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    52
end
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    53
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    54
structure Code_Test : CODE_TEST = struct
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    55
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    56
(* convert a list of terms into nested tuples and back *)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    57
fun mk_tuples [] = @{term "()"}
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    58
  | mk_tuples [t] = t
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    59
  | mk_tuples (t :: ts) = HOLogic.mk_prod (t, mk_tuples ts)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    60
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    61
fun dest_tuples (Const (@{const_name Pair}, _) $ l $ r) = l :: dest_tuples r
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    62
  | dest_tuples t = [t]
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    63
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    64
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    65
fun map_option _ NONE = NONE
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    66
  | map_option f (SOME x) = SOME (f x)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    67
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    68
fun last_field sep str =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    69
  let
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    70
    val n = size sep;
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    71
    val len = size str;
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    72
    fun find i =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    73
      if i < 0 then NONE
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    74
      else if String.substring (str, i, n) = sep then SOME i
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    75
      else find (i - 1);
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    76
  in
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    77
    (case find (len - n) of
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    78
      NONE => NONE
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    79
    | SOME i => SOME (String.substring (str, 0, i), String.extract (str, i + n, NONE)))
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    80
  end;
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    81
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    82
fun split_first_last start stop s =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    83
  case first_field start s
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    84
   of NONE => NONE
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    85
    | SOME (initial, rest) =>
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    86
      case last_field stop rest
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    87
       of NONE => NONE
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    88
        | SOME (middle, tail) => SOME (initial, middle, tail);
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    89
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    90
(* Data slot for drivers *)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    91
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    92
structure Drivers = Theory_Data
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    93
(
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    94
  type T = (string * ((Proof.context -> (string * string) list * string -> Path.T -> string) * string)) list;
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    95
  val empty = [];
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    96
  val extend = I;
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    97
  fun merge data : T = AList.merge (op =) (K true) data;
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    98
)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
    99
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   100
val add_driver = Drivers.map o AList.update (op =);
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   101
val get_driver = AList.lookup (op =) o Drivers.get;
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   102
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   103
(*
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   104
  Test drivers must produce output of the following format:
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   105
  
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   106
  The start of the relevant data is marked with start_markerN,
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   107
  its end with end_markerN.
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   108
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   109
  Between these two markers, every line corresponds to one test.
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   110
  Lines of successful tests start with successN, failures start with failureN.
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   111
  The failure failureN may continue with the YXML encoding of the evaluated term.
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   112
  There must not be any additional whitespace in between.
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   113
*)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   114
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   115
(* Parsing of results *)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   116
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   117
val successN = "True"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   118
val failureN = "False"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   119
val start_markerN = "*@*Isabelle/Code_Test-start*@*"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   120
val end_markerN = "*@*Isabelle/Code_Test-end*@*"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   121
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   122
fun parse_line line =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   123
  if String.isPrefix successN line then (true, NONE)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   124
  else if String.isPrefix failureN line then (false, 
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   125
    if size line > size failureN then
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   126
      String.extract (line, size failureN, NONE)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   127
      |> YXML.parse_body
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   128
      |> Term_XML.Decode.term
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   129
      |> dest_tuples
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   130
      |> SOME
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   131
    else NONE)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   132
  else raise Fail ("Cannot parse result of evaluation:\n" ^ line)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   133
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   134
fun parse_result target out =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   135
  case split_first_last start_markerN end_markerN out
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   136
    of NONE => error ("Evaluation failed for " ^ target ^ "!\nBash output:\n" ^ out)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   137
     | SOME (_, middle, _) => middle |> trim_line |> split_lines |> map parse_line
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   138
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   139
(* Pretty printing of test results *)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   140
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   141
fun pretty_eval _ NONE _ = []
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   142
  | pretty_eval ctxt (SOME evals) ts = 
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   143
    [Pretty.fbrk,
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   144
     Pretty.big_list "Evaluated terms"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   145
       (map (fn (t, eval) => Pretty.block 
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   146
         [Syntax.pretty_term ctxt t, Pretty.brk 1, Pretty.str "=", Pretty.brk 1,
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   147
          Syntax.pretty_term ctxt eval])
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   148
       (ts ~~ evals))]
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   149
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   150
fun pretty_failure ctxt target (((_, evals), query), eval_ts) =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   151
  Pretty.block (Pretty.text ("Test in " ^ target ^ " failed for") @ [Pretty.brk 1, Pretty.quote (Syntax.pretty_term ctxt query)]
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   152
    @ pretty_eval ctxt evals eval_ts)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   153
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   154
fun pretty_failures ctxt target failures =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   155
  Pretty.blk (0, Pretty.fbreaks (map (pretty_failure ctxt target) failures))
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   156
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   157
(* Driver invocation *)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   158
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   159
val overlord = Attrib.setup_config_bool @{binding "code_test_overlord"} (K false);
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   160
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   161
fun with_overlord_dir name f =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   162
  let
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   163
    val path = Path.append (Path.explode "$ISABELLE_HOME_USER") (Path.basic (name ^ serial_string ()))
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   164
    val _ = Isabelle_System.mkdirs path;
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   165
  in
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   166
    Exn.release (Exn.capture f path)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   167
  end;
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   168
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   169
fun dynamic_value_strict ctxt t compiler =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   170
  let
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   171
    val thy = Proof_Context.theory_of ctxt
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   172
    val (driver, target) = case get_driver thy compiler
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   173
     of NONE => error ("No driver for target " ^ compiler)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   174
      | SOME f => f;
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   175
    val debug = Config.get (Proof_Context.init_global thy) overlord
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   176
    val with_dir = if debug then with_overlord_dir else Isabelle_System.with_tmp_dir
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   177
    fun evaluate f = with_dir "Code_Test" (driver ctxt f) |> parse_result compiler
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   178
    fun evaluator program _ vs_ty deps =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   179
      Exn.interruptible_capture evaluate (Code_Target.evaluator ctxt target program deps true vs_ty);
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   180
    fun postproc f = map (apsnd (map_option (map f)))
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   181
  in
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   182
    Exn.release (Code_Thingol.dynamic_value ctxt (Exn.map_result o postproc) evaluator t)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   183
  end;
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   184
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   185
(* Term preprocessing *)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   186
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   187
fun add_eval (Const (@{const_name Trueprop}, _) $ t) = add_eval t
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   188
  | add_eval (Const (@{const_name "HOL.eq"}, _) $ lhs $ rhs) = (fn acc =>
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   189
    acc
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   190
    |> add_eval rhs
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   191
    |> add_eval lhs
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   192
    |> cons rhs
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   193
    |> cons lhs)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   194
  | add_eval (Const (@{const_name "Not"}, _) $ t) = add_eval t
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   195
  | add_eval (Const (@{const_name "Orderings.ord_class.less_eq"}, _) $ lhs $ rhs) = (fn acc =>
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   196
    lhs :: rhs :: acc)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   197
  | add_eval (Const (@{const_name "Orderings.ord_class.less"}, _) $ lhs $ rhs) = (fn acc =>
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   198
    lhs :: rhs :: acc)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   199
  | add_eval _ = I
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   200
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   201
fun mk_term_of [] = @{term "None :: (unit \<Rightarrow> yxml_of_term) option"}
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   202
  | mk_term_of ts =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   203
  let
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   204
    val tuple = mk_tuples ts
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   205
    val T = fastype_of tuple
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   206
  in
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   207
    @{term "Some :: (unit \<Rightarrow> yxml_of_term) \<Rightarrow> (unit \<Rightarrow> yxml_of_term) option"} $
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   208
      (absdummy @{typ unit} (@{const yxml_string_of_term} $
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   209
        (Const (@{const_name Code_Evaluation.term_of}, T --> @{typ term}) $ tuple)))
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   210
  end
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   211
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   212
fun test_terms ctxt ts target =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   213
  let
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   214
    val thy = Proof_Context.theory_of ctxt
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   215
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   216
    fun term_of t = Sign.of_sort thy (fastype_of t, @{sort term_of})
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   217
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   218
    fun ensure_bool t = case fastype_of t of @{typ bool} => ()
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   219
      | _ => error ("Test case not of type bool: " ^ Pretty.string_of (Syntax.pretty_term ctxt t))
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   220
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   221
    val _ = map ensure_bool ts
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   222
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   223
    val evals = map (fn t => filter term_of (add_eval t [])) ts
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   224
    val eval = map mk_term_of evals
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   225
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   226
    val T = HOLogic.mk_prodT (@{typ bool}, Type (@{type_name option}, [@{typ unit} --> @{typ yxml_of_term}]))
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   227
    val t = HOLogic.mk_list T (map HOLogic.mk_prod (ts ~~ eval))
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   228
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   229
    val result = dynamic_value_strict ctxt t target;
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   230
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   231
    val failed =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   232
      filter_out (fst o fst o fst) (result ~~ ts ~~ evals)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   233
      handle ListPair.UnequalLengths => 
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   234
        error ("Evaluation failed!\nWrong number of test results: " ^ Int.toString (length result))
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   235
    val _ = case failed of [] => () 
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   236
      | _ => error (Pretty.string_of (pretty_failures ctxt target failed))
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   237
  in
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   238
    ()
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   239
  end
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   240
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   241
fun test_targets ctxt = map o test_terms ctxt
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   242
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   243
fun test_code_cmd raw_ts targets state =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   244
  let
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   245
    val ctxt = Toplevel.context_of state;
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   246
    val ts = Syntax.read_terms ctxt raw_ts;
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   247
    val frees = fold Term.add_free_names ts []
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   248
    val _ = if frees = [] then () else
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   249
      error ("Terms contain free variables: " ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   250
      Pretty.string_of (Pretty.block (Pretty.commas (map Pretty.str frees))))
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   251
  in
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   252
    test_targets ctxt ts targets; ()
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   253
  end
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   254
58348
2d47c7d10b62 add target language evaluators for the value command;
Andreas Lochbihler
parents: 58039
diff changeset
   255
fun eval_term target ctxt t =
2d47c7d10b62 add target language evaluators for the value command;
Andreas Lochbihler
parents: 58039
diff changeset
   256
  let
2d47c7d10b62 add target language evaluators for the value command;
Andreas Lochbihler
parents: 58039
diff changeset
   257
    val frees = Term.add_free_names t []
2d47c7d10b62 add target language evaluators for the value command;
Andreas Lochbihler
parents: 58039
diff changeset
   258
    val _ = if frees = [] then () else
2d47c7d10b62 add target language evaluators for the value command;
Andreas Lochbihler
parents: 58039
diff changeset
   259
      error ("Term contains free variables: " ^
2d47c7d10b62 add target language evaluators for the value command;
Andreas Lochbihler
parents: 58039
diff changeset
   260
      Pretty.string_of (Pretty.block (Pretty.commas (map Pretty.str frees))))
58039
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   261
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   262
    val thy = Proof_Context.theory_of ctxt
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   263
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   264
    val T_t = fastype_of t
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   265
    val _ = if Sign.of_sort thy (T_t, @{sort term_of}) then () else error 
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   266
      ("Type " ^ Pretty.string_of (Syntax.pretty_typ ctxt T_t) ^ 
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   267
       " of term not of sort " ^ Pretty.string_of (Syntax.pretty_sort ctxt @{sort term_of}))
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   268
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   269
    val T = HOLogic.mk_prodT (@{typ bool}, Type (@{type_name option}, [@{typ unit} --> @{typ yxml_of_term}]))
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   270
    val t' = HOLogic.mk_list T [HOLogic.mk_prod (@{term "False"}, mk_term_of [t])]
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   271
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   272
    val result = dynamic_value_strict ctxt t' target;
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   273
  in
58348
2d47c7d10b62 add target language evaluators for the value command;
Andreas Lochbihler
parents: 58039
diff changeset
   274
    case result of [(_, SOME [t])] => t | _ => error "Evaluation failed"
58039
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   275
  end
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   276
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   277
(* Generic driver *)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   278
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   279
fun gen_driver mk_driver env_var env_var_dest compilerN ctxt (code_files, value_name) =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   280
  let
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   281
    val compiler = getenv env_var
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   282
    val _ = if compiler <> "" then () else error (Pretty.string_of (Pretty.para 
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   283
         ("Environment variable " ^ env_var ^ " is not set. To test code generation with " ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   284
         compilerN ^ ", set this variable to your " ^ env_var_dest ^ " in the settings file.")))
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   285
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   286
    fun compile NONE = ()
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   287
      | compile (SOME cmd) =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   288
        let
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   289
          val (out, ret) = Isabelle_System.bash_output cmd
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   290
        in
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   291
          if ret = 0 then () else error
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   292
            ("Compilation with " ^ compilerN ^ " failed:\n" ^ cmd ^ "\n" ^ out)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   293
        end
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   294
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   295
    fun run (path : Path.T)= 
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   296
      let
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   297
        val modules = map fst code_files
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   298
        val {files, compile_cmd, run_cmd, mk_code_file}
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   299
          =  mk_driver ctxt path modules value_name
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   300
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   301
        val _ = map (fn (name, code) => File.write (mk_code_file name) code) code_files
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   302
        val _ = map (fn (name, content) => File.write name content) files
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   303
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   304
        val _ = compile compile_cmd
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   305
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   306
        val (out, res) = Isabelle_System.bash_output run_cmd
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   307
        val _ = if res = 0 then () else error
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   308
          ("Evaluation for " ^ compilerN ^ " terminated with error code " ^ Int.toString res ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   309
           "\nBash output:\n" ^ out)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   310
      in
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   311
        out
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   312
      end
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   313
  in
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   314
    run
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   315
  end
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   316
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   317
(* Driver for PolyML *)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   318
58415
8392d221bd91 clarified ISABELLE_POLYML;
wenzelm
parents: 58348
diff changeset
   319
val ISABELLE_POLYML = "ISABELLE_POLYML"
58039
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   320
val polymlN = "PolyML";
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   321
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   322
fun mk_driver_polyml _ path _ value_name =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   323
  let
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   324
    val generatedN = "generated.sml"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   325
    val driverN = "driver.sml"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   326
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   327
    val code_path = Path.append path (Path.basic generatedN)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   328
    val driver_path = Path.append path (Path.basic driverN)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   329
    val driver = 
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   330
      "fun main prog_name = \n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   331
      "  let\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   332
      "    fun format_term NONE = \"\"\n" ^ 
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   333
      "      | format_term (SOME t) = t ();\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   334
      "    fun format (true, _) = \"" ^ successN ^ "\\n\"\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   335
      "      | format (false, to) = \"" ^ failureN ^ "\" ^ format_term to ^ \"\\n\";\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   336
      "    val result = " ^ value_name ^ " ();\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   337
      "    val _ = print \"" ^ start_markerN ^ "\";\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   338
      "    val _ = map (print o format) result;\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   339
      "    val _ = print \"" ^ end_markerN ^ "\";\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   340
      "  in\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   341
      "    ()\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   342
      "  end;\n"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   343
    val cmd =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   344
      "echo \"use \\\"" ^ Path.implode code_path ^ "\\\"; use \\\"" ^ 
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   345
      Path.implode driver_path ^ "\\\"; main ();\" | " ^ 
58415
8392d221bd91 clarified ISABELLE_POLYML;
wenzelm
parents: 58348
diff changeset
   346
      Path.implode (Path.variable ISABELLE_POLYML)
58039
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   347
  in
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   348
    {files = [(driver_path, driver)], compile_cmd = NONE, run_cmd = cmd, mk_code_file = K code_path}
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   349
  end
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   350
58832
ec9550bd5fd7 make SML/NJ more happy;
wenzelm
parents: 58626
diff changeset
   351
fun evaluate_in_polyml ctxt =
ec9550bd5fd7 make SML/NJ more happy;
wenzelm
parents: 58626
diff changeset
   352
  gen_driver mk_driver_polyml ISABELLE_POLYML "PolyML executable" polymlN ctxt
58039
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   353
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   354
(* Driver for mlton *)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   355
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   356
val mltonN = "MLton"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   357
val ISABELLE_MLTON = "ISABELLE_MLTON"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   358
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   359
fun mk_driver_mlton _ path _ value_name =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   360
  let
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   361
    val generatedN = "generated.sml"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   362
    val driverN = "driver.sml"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   363
    val projectN = "test"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   364
    val ml_basisN = projectN ^ ".mlb"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   365
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   366
    val code_path = Path.append path (Path.basic generatedN)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   367
    val driver_path = Path.append path (Path.basic driverN)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   368
    val ml_basis_path = Path.append path (Path.basic ml_basisN)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   369
    val driver = 
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   370
      "fun format_term NONE = \"\"\n" ^ 
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   371
      "  | format_term (SOME t) = t ();\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   372
      "fun format (true, _) = \"" ^ successN ^ "\\n\"\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   373
      "  | format (false, to) = \"" ^ failureN ^ "\" ^ format_term to ^ \"\\n\";\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   374
      "val result = " ^ value_name ^ " ();\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   375
      "val _ = print \"" ^ start_markerN ^ "\";\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   376
      "val _ = map (print o format) result;\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   377
      "val _ = print \"" ^ end_markerN ^ "\";\n"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   378
    val ml_basis =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   379
      "$(SML_LIB)/basis/basis.mlb\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   380
      generatedN ^ "\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   381
      driverN
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   382
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   383
    val compile_cmd =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   384
      File.shell_path (Path.variable ISABELLE_MLTON) ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   385
      " -default-type intinf " ^ File.shell_path ml_basis_path
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   386
    val run_cmd = File.shell_path (Path.append path (Path.basic projectN))
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   387
  in
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   388
    {files = [(driver_path, driver), (ml_basis_path, ml_basis)],
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   389
     compile_cmd = SOME compile_cmd, run_cmd = run_cmd, mk_code_file = K code_path}
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   390
  end
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   391
58832
ec9550bd5fd7 make SML/NJ more happy;
wenzelm
parents: 58626
diff changeset
   392
fun evaluate_in_mlton ctxt =
ec9550bd5fd7 make SML/NJ more happy;
wenzelm
parents: 58626
diff changeset
   393
  gen_driver mk_driver_mlton ISABELLE_MLTON "MLton executable" mltonN ctxt
58039
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   394
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   395
(* Driver for SML/NJ *)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   396
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   397
val smlnjN = "SMLNJ"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   398
val ISABELLE_SMLNJ = "ISABELLE_SMLNJ"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   399
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   400
fun mk_driver_smlnj _ path _ value_name =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   401
  let
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   402
    val generatedN = "generated.sml"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   403
    val driverN = "driver.sml"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   404
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   405
    val code_path = Path.append path (Path.basic generatedN)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   406
    val driver_path = Path.append path (Path.basic driverN)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   407
    val driver = 
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   408
      "structure Test = struct\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   409
      "fun main prog_name =\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   410
      "  let\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   411
      "    fun format_term NONE = \"\"\n" ^ 
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   412
      "      | format_term (SOME t) = t ();\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   413
      "    fun format (true, _) = \"" ^ successN ^ "\\n\"\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   414
      "      | format (false, to) = \"" ^ failureN ^ "\" ^ format_term to ^ \"\\n\";\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   415
      "    val result = " ^ value_name ^ " ();\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   416
      "    val _ = print \"" ^ start_markerN ^ "\";\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   417
      "    val _ = map (print o format) result;\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   418
      "    val _ = print \"" ^ end_markerN ^ "\";\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   419
      "  in\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   420
      "    0\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   421
      "  end;\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   422
      "end;"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   423
    val cmd =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   424
      "echo \"Control.MC.matchRedundantError := false; Control.MC.matchRedundantWarn := false;" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   425
      "use \\\"" ^ Path.implode code_path ^ "\\\"; use \\\"" ^ Path.implode driver_path ^ "\\\";" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   426
      "Test.main ();\" | " ^ Path.implode (Path.variable ISABELLE_SMLNJ)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   427
  in
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   428
    {files = [(driver_path, driver)], compile_cmd = NONE, run_cmd = cmd, mk_code_file = K code_path}
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   429
  end
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   430
58832
ec9550bd5fd7 make SML/NJ more happy;
wenzelm
parents: 58626
diff changeset
   431
fun evaluate_in_smlnj ctxt =
ec9550bd5fd7 make SML/NJ more happy;
wenzelm
parents: 58626
diff changeset
   432
  gen_driver mk_driver_smlnj ISABELLE_SMLNJ "SMLNJ executable" smlnjN ctxt
58039
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   433
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   434
(* Driver for OCaml *)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   435
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   436
val ocamlN = "OCaml"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   437
val ISABELLE_OCAMLC = "ISABELLE_OCAMLC"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   438
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   439
fun mk_driver_ocaml _ path _ value_name =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   440
  let
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   441
    val generatedN = "generated.ml"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   442
    val driverN = "driver.ml"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   443
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   444
    val code_path = Path.append path (Path.basic generatedN)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   445
    val driver_path = Path.append path (Path.basic driverN)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   446
    val driver = 
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   447
      "let format_term = function\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   448
      "  | None -> \"\"\n" ^ 
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   449
      "  | Some t -> t ();;\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   450
      "let format = function\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   451
      "  | (true, _) -> \"" ^ successN ^ "\\n\"\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   452
      "  | (false, x) -> \"" ^ failureN ^ "\" ^ format_term x ^ \"\\n\";;\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   453
      "let result = " ^ ("Generated." ^ value_name) ^ " ();;\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   454
      "let main x =\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   455
      "  let _ = print_string \"" ^ start_markerN ^ "\" in\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   456
      "  let _ = List.map (fun x -> print_string (format x)) result in\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   457
      "  print_string \"" ^ end_markerN ^ "\";;\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   458
      "main ();;"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   459
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   460
    val compiled_path = Path.append path (Path.basic "test")
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   461
    val compile_cmd =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   462
      Path.implode (Path.variable ISABELLE_OCAMLC) ^ " -w pu -o " ^ Path.implode compiled_path ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   463
      " -I " ^ Path.implode path ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   464
      " nums.cma " ^ Path.implode code_path ^ " " ^ Path.implode driver_path
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   465
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   466
    val run_cmd = File.shell_path compiled_path
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   467
  in
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   468
    {files = [(driver_path, driver)],
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   469
     compile_cmd = SOME compile_cmd, run_cmd = run_cmd, mk_code_file = K code_path}
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   470
  end
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   471
58832
ec9550bd5fd7 make SML/NJ more happy;
wenzelm
parents: 58626
diff changeset
   472
fun evaluate_in_ocaml ctxt =
ec9550bd5fd7 make SML/NJ more happy;
wenzelm
parents: 58626
diff changeset
   473
  gen_driver mk_driver_ocaml ISABELLE_OCAMLC "ocamlc executable" ocamlN ctxt
58039
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   474
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   475
(* Driver for GHC *)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   476
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   477
val ghcN = "GHC"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   478
val ISABELLE_GHC = "ISABELLE_GHC"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   479
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   480
val ghc_options = Attrib.setup_config_string @{binding code_test_ghc} (K "")
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   481
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   482
fun mk_driver_ghc ctxt path modules value_name =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   483
  let
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   484
    val driverN = "Main.hs"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   485
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   486
    fun mk_code_file name = Path.append path (Path.basic (name ^ ".hs"))
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   487
    val driver_path = Path.append path (Path.basic driverN)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   488
    val driver = 
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   489
      "module Main where {\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   490
      String.concat (map (fn module => "import qualified " ^ module ^ ";\n") modules) ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   491
      "main = do {\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   492
      "    let {\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   493
      "      format_term Nothing = \"\";\n" ^ 
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   494
      "      format_term (Just t) = t ();\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   495
      "      format (True, _) = \"" ^ successN ^ "\\n\";\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   496
      "      format (False, to) = \"" ^ failureN ^ "\" ++ format_term to ++ \"\\n\";\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   497
      "      result = " ^ value_name ^ " ();\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   498
      "    };\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   499
      "    Prelude.putStr \"" ^ start_markerN ^ "\";\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   500
      "    Prelude.mapM_ (putStr . format) result;\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   501
      "    Prelude.putStr \"" ^ end_markerN ^ "\";\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   502
      "  }\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   503
      "}\n"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   504
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   505
    val compiled_path = Path.append path (Path.basic "test")
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   506
    val compile_cmd =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   507
      Path.implode (Path.variable ISABELLE_GHC) ^ " " ^ Code_Haskell.language_params ^ " " ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   508
      Config.get ctxt ghc_options ^ " -o " ^ Path.implode compiled_path ^ " " ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   509
      Path.implode driver_path ^ " -i" ^ Path.implode path
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   510
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   511
    val run_cmd = File.shell_path compiled_path
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   512
  in
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   513
    {files = [(driver_path, driver)],
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   514
     compile_cmd = SOME compile_cmd, run_cmd = run_cmd, mk_code_file = mk_code_file}
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   515
  end
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   516
58832
ec9550bd5fd7 make SML/NJ more happy;
wenzelm
parents: 58626
diff changeset
   517
fun evaluate_in_ghc ctxt =
ec9550bd5fd7 make SML/NJ more happy;
wenzelm
parents: 58626
diff changeset
   518
  gen_driver mk_driver_ghc ISABELLE_GHC "GHC executable" ghcN ctxt
58039
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   519
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   520
(* Driver for Scala *)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   521
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   522
val scalaN = "Scala"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   523
val ISABELLE_SCALA = "ISABELLE_SCALA"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   524
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   525
fun mk_driver_scala _ path _ value_name =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   526
  let
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   527
    val generatedN = "Generated_Code"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   528
    val driverN = "Driver.scala"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   529
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   530
    val code_path = Path.append path (Path.basic (generatedN ^ ".scala"))
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   531
    val driver_path = Path.append path (Path.basic driverN)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   532
    val driver = 
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   533
      "import " ^ generatedN ^ "._\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   534
      "object Test {\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   535
      "  def format_term(x : Option[Unit => String]) : String = x match {\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   536
      "    case None => \"\"\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   537
      "    case Some(x) => x(())\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   538
      "  }\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   539
      "  def format(term : (Boolean, Option[Unit => String])) : String = term match {\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   540
      "      case (true, _) => \"True\\n\"\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   541
      "      case (false, x) => \"False\" + format_term(x) + \"\\n\"\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   542
      "  }\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   543
      "  def main(args:Array[String]) = {\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   544
      "    val result = " ^ value_name ^ "(());\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   545
      "    print(\"" ^ start_markerN ^ "\");\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   546
      "    result.map{test:(Boolean, Option[Unit => String]) => print(format(test))};\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   547
      "    print(\"" ^ end_markerN ^ "\");\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   548
      "  }\n" ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   549
      "}\n"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   550
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   551
    val compile_cmd =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   552
      Path.implode (Path.append (Path.variable ISABELLE_SCALA) (Path.basic "scalac")) ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   553
      " -d " ^ File.shell_path path ^ " -classpath " ^ File.shell_path path ^ " " ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   554
      File.shell_path code_path ^ " " ^ File.shell_path driver_path
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   555
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   556
    val run_cmd =
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   557
      Path.implode (Path.append (Path.variable ISABELLE_SCALA) (Path.basic "scala")) ^
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   558
      " -cp " ^ File.shell_path path ^ " Test"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   559
  in
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   560
    {files = [(driver_path, driver)],
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   561
     compile_cmd = SOME compile_cmd, run_cmd = run_cmd, mk_code_file = K code_path}
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   562
  end
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   563
58832
ec9550bd5fd7 make SML/NJ more happy;
wenzelm
parents: 58626
diff changeset
   564
fun evaluate_in_scala ctxt =
ec9550bd5fd7 make SML/NJ more happy;
wenzelm
parents: 58626
diff changeset
   565
  gen_driver mk_driver_scala ISABELLE_SCALA "Scala directory" scalaN ctxt
58039
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   566
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   567
val test_codeP = Scan.repeat1 Parse.prop -- (@{keyword "in"} |-- Scan.repeat1 Parse.name)
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   568
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   569
val _ = 
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   570
  Outer_Syntax.command @{command_spec "test_code"}
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   571
    "compile test cases to target languages, execute them and report results"
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   572
      (test_codeP >> (fn (raw_ts, targets) => Toplevel.keep (test_code_cmd raw_ts targets)))
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   573
59323
468bd3aedfa1 modernized and more uniform style
haftmann
parents: 58832
diff changeset
   574
val _ = Theory.setup (fold add_driver
468bd3aedfa1 modernized and more uniform style
haftmann
parents: 58832
diff changeset
   575
  [(polymlN, (evaluate_in_polyml, Code_ML.target_SML)),
468bd3aedfa1 modernized and more uniform style
haftmann
parents: 58832
diff changeset
   576
   (mltonN, (evaluate_in_mlton, Code_ML.target_SML)),
468bd3aedfa1 modernized and more uniform style
haftmann
parents: 58832
diff changeset
   577
   (smlnjN, (evaluate_in_smlnj, Code_ML.target_SML)),
468bd3aedfa1 modernized and more uniform style
haftmann
parents: 58832
diff changeset
   578
   (ocamlN, (evaluate_in_ocaml, Code_ML.target_OCaml)),
468bd3aedfa1 modernized and more uniform style
haftmann
parents: 58832
diff changeset
   579
   (ghcN, (evaluate_in_ghc, Code_Haskell.target)),
468bd3aedfa1 modernized and more uniform style
haftmann
parents: 58832
diff changeset
   580
   (scalaN, (evaluate_in_scala, Code_Scala.target))]
468bd3aedfa1 modernized and more uniform style
haftmann
parents: 58832
diff changeset
   581
  #> fold (fn target => Value.add_evaluator (target, eval_term target))
468bd3aedfa1 modernized and more uniform style
haftmann
parents: 58832
diff changeset
   582
    [polymlN, mltonN, smlnjN, ocamlN, ghcN, scalaN]);
468bd3aedfa1 modernized and more uniform style
haftmann
parents: 58832
diff changeset
   583
58039
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   584
end
469a375212c1 add testing framework for generated code
Andreas Lochbihler
parents:
diff changeset
   585