158 lines
5.8 KiB
OCaml
158 lines
5.8 KiB
OCaml
|
|
open Util.Assert
|
||
|
|
open X86
|
||
|
|
open Ll
|
||
|
|
|
||
|
|
module Driver = Oat.Driver
|
||
|
|
module Backend = Oat.Backend
|
||
|
|
module Typechecker = Oat.Typechecker
|
||
|
|
module Frontend = Oat.Frontend
|
||
|
|
module Tctxt = Oat.Tctxt
|
||
|
|
open Backend
|
||
|
|
open Driver
|
||
|
|
|
||
|
|
(* Do NOT modify this file -- we will overwrite it with our *)
|
||
|
|
(* own version when we test your project. *)
|
||
|
|
|
||
|
|
|
||
|
|
let fdecl_of_path path =
|
||
|
|
Platform.verb @@ Printf.sprintf "* processing file: %s\n" path;
|
||
|
|
let ll_ast = parse_ll_file path in
|
||
|
|
match ll_ast.Ll.fdecls with
|
||
|
|
| [_, fdecl] -> fdecl
|
||
|
|
| _ -> failwith "test expected one fdecl"
|
||
|
|
|
||
|
|
|
||
|
|
let exec_e2e_ast ll_ast args extra_files =
|
||
|
|
let output_path = !Platform.output_path in
|
||
|
|
let dot_s_file = Platform.gen_name output_path "test" ".s" in
|
||
|
|
let exec_file = Platform.gen_name output_path "exec" "" in
|
||
|
|
let asm_ast = Backend.compile_prog ll_ast in
|
||
|
|
let asm_str = X86.string_of_prog asm_ast in
|
||
|
|
let _ = Driver.write_file dot_s_file asm_str in
|
||
|
|
let _ = Platform.link (dot_s_file::extra_files) exec_file in
|
||
|
|
let result = Driver.run_executable args exec_file in
|
||
|
|
let _ = Platform.sh (Printf.sprintf "rm -f %s %s" dot_s_file exec_file) Platform.ignore_error in
|
||
|
|
let _ = Platform.verb @@ Printf.sprintf "** Executable exited with: %d\n" result in
|
||
|
|
Int64.of_int result
|
||
|
|
|
||
|
|
|
||
|
|
let exec_e2e_file path args =
|
||
|
|
let ast = Driver.parse_ll_file path in
|
||
|
|
exec_e2e_ast ast args []
|
||
|
|
|
||
|
|
let io_test path args =
|
||
|
|
let ll_ast = Driver.parse_ll_file path in
|
||
|
|
let output_path = !Platform.output_path in
|
||
|
|
let dot_s_file = Platform.gen_name output_path "test" ".s" in
|
||
|
|
let exec_file = Platform.gen_name output_path "exec" "" in
|
||
|
|
let tmp_file = Platform.gen_name output_path "tmp" ".txt" in
|
||
|
|
let asm_ast = Backend.compile_prog ll_ast in
|
||
|
|
let asm_str = X86.string_of_prog asm_ast in
|
||
|
|
let _ = Driver.write_file dot_s_file asm_str in
|
||
|
|
let _ = Platform.link (dot_s_file::["cinterop.c"]) exec_file in
|
||
|
|
let args = String.concat " " args in
|
||
|
|
let result = Driver.run_program args exec_file tmp_file in
|
||
|
|
let _ = Platform.sh (Printf.sprintf "rm -f %s %s %s" dot_s_file exec_file tmp_file) Platform.ignore_error in
|
||
|
|
let _ = Platform.verb @@ Printf.sprintf "** Executable output:\n%s\n" result in
|
||
|
|
result
|
||
|
|
|
||
|
|
let c_link_test c_files path args =
|
||
|
|
let ll_ast = Driver.parse_ll_file path in
|
||
|
|
let output_path = !Platform.output_path in
|
||
|
|
let dot_s_file = Platform.gen_name output_path "test" ".s" in
|
||
|
|
let exec_file = Platform.gen_name output_path "exec" "" in
|
||
|
|
let asm_ast = Backend.compile_prog ll_ast in
|
||
|
|
let asm_str = X86.string_of_prog asm_ast in
|
||
|
|
let _ = Driver.write_file dot_s_file asm_str in
|
||
|
|
let _ = Platform.link (dot_s_file::c_files) exec_file in
|
||
|
|
let args = String.concat " " args in
|
||
|
|
let result = Driver.run_executable args exec_file in
|
||
|
|
let _ = Platform.sh (Printf.sprintf "rm -f %s %s" dot_s_file exec_file) Platform.ignore_error in
|
||
|
|
Int64.of_int result
|
||
|
|
|
||
|
|
let oat_file_test path args =
|
||
|
|
let () = Platform.verb @@ Printf.sprintf "** Processing: %s\n" path in
|
||
|
|
|
||
|
|
let output_path = !Platform.output_path in
|
||
|
|
let dot_ll_file = Platform.gen_name output_path "test" ".ll" in
|
||
|
|
let exec_file = Platform.gen_name output_path "exec" "" in
|
||
|
|
let tmp_file = Platform.gen_name output_path "tmp" ".txt" in
|
||
|
|
|
||
|
|
let oat_ast = parse_oat_file path in
|
||
|
|
Typechecker.typecheck_program oat_ast;
|
||
|
|
let ll_ast = Frontend.cmp_prog oat_ast in
|
||
|
|
let ll_str = Driver.string_of_ll_ast path ll_ast in
|
||
|
|
let () = write_file dot_ll_file ll_str in
|
||
|
|
let () = Platform.link (dot_ll_file::["bin/runtime.c"]) exec_file in
|
||
|
|
|
||
|
|
let result = Driver.run_program args exec_file tmp_file in
|
||
|
|
let () = Platform.sh (Printf.sprintf "rm -f %s %s %s" dot_ll_file exec_file tmp_file) Platform.ignore_error in
|
||
|
|
let () = Platform.verb @@ Printf.sprintf "** Executable output:\n%s\n" result in
|
||
|
|
result
|
||
|
|
|
||
|
|
let oat_tc_ok_file_test path =
|
||
|
|
let _ = Platform.verb @@ Printf.sprintf "** OAT Typechecker OK Processing: %s\n" path in
|
||
|
|
let oat_ast = parse_oat_file path in
|
||
|
|
let _= Typechecker.typecheck_program oat_ast in
|
||
|
|
()
|
||
|
|
|
||
|
|
let oat_tc_err_file_test path err =
|
||
|
|
let _ = Platform.verb @@ Printf.sprintf "** OAT Typechecker Error Processing: %s\n" path in
|
||
|
|
let oat_ast = parse_oat_file path in
|
||
|
|
try
|
||
|
|
let _ = Typechecker.typecheck_program oat_ast in
|
||
|
|
failwith @@ Printf.sprintf "Expected type error: %s" err
|
||
|
|
with
|
||
|
|
| Typechecker.TypeError s ->
|
||
|
|
if s = err then () else
|
||
|
|
failwith @@ Printf.sprintf "Expected type error: %s but got %s" err s
|
||
|
|
|
||
|
|
let executed tests =
|
||
|
|
List.map (fun (fn, ans) ->
|
||
|
|
fn, assert_eqf (fun () -> exec_e2e_file fn "") ans)
|
||
|
|
tests
|
||
|
|
|
||
|
|
let executed_oat_file tests =
|
||
|
|
List.map (fun (path, args, ans) ->
|
||
|
|
(path ^ " args: " ^ args), assert_eqfs (fun () -> oat_file_test path args) ans)
|
||
|
|
tests
|
||
|
|
|
||
|
|
let executed_tc_ok_file tests =
|
||
|
|
List.map (fun path ->
|
||
|
|
("typechecking: " ^ path, fun () -> oat_tc_ok_file_test path)) tests
|
||
|
|
|
||
|
|
let executed_tc_err_file tests =
|
||
|
|
List.map (fun (path, err) ->
|
||
|
|
("typechecking: " ^ path, fun () -> oat_tc_err_file_test path err)) tests
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
let executed_io tests =
|
||
|
|
List.map (fun (fn, args, ans) ->
|
||
|
|
(fn ^ ":" ^ (String.concat " " args)), assert_eqfs (fun () -> io_test fn args) ans)
|
||
|
|
tests
|
||
|
|
|
||
|
|
let executed_c_link tests =
|
||
|
|
List.map (fun (c_file, fn, args, ans) ->
|
||
|
|
(fn ^ ":" ^ (String.concat " " args)), assert_eqf (fun () -> c_link_test c_file fn args) ans)
|
||
|
|
tests
|
||
|
|
|
||
|
|
let typecheck path () =
|
||
|
|
let () = Platform.verb @@ Printf.sprintf "** Processing: %s\n" path in
|
||
|
|
let oat_ast = parse_oat_file path in
|
||
|
|
Typechecker.typecheck_program oat_ast
|
||
|
|
|
||
|
|
let typecheck_error (a : assertion) () =
|
||
|
|
try a (); failwith "Should have a type error" with Typechecker.TypeError s -> ()
|
||
|
|
|
||
|
|
let typecheck_correct (a : assertion) () =
|
||
|
|
try a () with Typechecker.TypeError s -> failwith "Should not have had a type error"
|
||
|
|
|
||
|
|
|
||
|
|
let typecheck_file_error tests =
|
||
|
|
List.map (fun p -> p, typecheck_error (typecheck p)) tests
|
||
|
|
|
||
|
|
let typecheck_file_correct tests =
|
||
|
|
List.map (fun p -> p, typecheck_correct (typecheck p)) tests
|
||
|
|
|