Skip to content

Instantly share code, notes, and snippets.

@DarinM223
Last active August 29, 2015 14:08
Show Gist options
  • Save DarinM223/e2611c00cbe1a00c2cc7 to your computer and use it in GitHub Desktop.
Save DarinM223/e2611c00cbe1a00c2cc7 to your computer and use it in GitHub Desktop.
mocaml interpreter tests
(* A simple test harness for the MOCaml interpreter. *)
(* put your tests here:
each test is a pair of a MOCaml declaration and the expected
result, both expressed as strings.
use the string "dynamic type error" if a DynamicTypeError is expected to be raised.
use the string "match failure" if a MatchFailure is expected to be raised.
use the string "implement me" if an ImplementMe exception is expected to be raised
call the function runtests() to run these tests
*)
let tests = [
(* simple tests *)
("3", "3");
("false", "false");
("[]", "[]");
("let x = 34", "val x = 34");
("y", "dynamic type error");
("x + 4", "38");
("x - 4", "30");
("x * 4", "136");
("x = 34", "true");
("x = 0", "false");
("x > 33", "true");
("35 > x", "true");
("x > 35", "false");
("2::3::[]", "[2; 3]");
("5::[2; 3]", "[5; 2; 3]");
("5::3", "dynamic type error");
("-x", "-34");
("33 > -x", "true");
("-[]", "dynamic type error");
("if x > 33 then 50 else 100", "50");
("(if x = 34 then 2 else 3)::[2; 3]", "[2; 2; 3]");
("if 1 then 2 else 3", "dynamic type error");
("if [2; 3] then 5 else 10", "dynamic type error");
("if 2 > 5 then 20 else 3", "3");
(* non-recursive function testing *)
("let newfunc = function x -> x * x", "val newfunc = <fun>");
("newfunc 2", "4");
("newfunc(2)", "4");
("let timesThreeNums = function a -> function b -> function c -> a * b * c", "val timesThreeNums = <fun>");
("timesThreeNums 2 3 4", "24");
("let multSix = timesThreeNums 2 3", "val multSix = <fun>");
("multSix 2", "12");
("let a = function true -> false", "val a = <fun>");
("a 1", "match failure"); (* not sure about this one *)
("let b = function _ -> true", "val b = <fun>");
("b 1", "true");
("b [1; 2; 3]", "true");
("let decapitate = function head::tail -> tail", "val decapitate = <fun>");
("decapitate [1; 2; 3]", "[2; 3]");
("decapitate [1]", "[]");
("decapitate []", "match failure");
("(function _ -> x) 42", "34");
(* pattern matching *)
("let l = [1; 2; 3]", "val l = [1; 2; 3]");
("match l with 1::2::[] -> true | _ -> false", "false");
("match l with 1::2::rest -> rest", "[3]");
("match 5 with s -> s", "5");
("match 10 with _ -> x", "34");
("(function s -> match s with head::tail -> head = x) [34; 2]", "true");
("match 20 with x -> x", "20");
(* recursive function testing *)
("let rec recTest num = match num with 0 -> 0 | s -> 1 + (if s > 0 then recTest(s-1) else recTest(s+1))", "val recTest = <fun>");
("recTest 10", "10");
("recTest (-10)", "10");
("let rec recTest2 _ = recTest2", "val recTest2 = <fun>");
("recTest2", "<fun>");
("recTest2 1 2 3 4 5 6 7 8 9 10 11 12", "<fun>");
]
(* The Test Harness
You don't need to understand the code below.
*)
let testOne test env =
let decl = main token (Lexing.from_string (test^";;")) in
let res = evalDecl decl env in
let str = print_result res in
match res with
(None,v) -> (str,env)
| (Some x,v) -> (str, Env.add_binding x v env)
let test tests =
let (results, finalEnv) =
List.fold_left
(fun (resultStrings, env) (test,expected) ->
let (res,newenv) =
try testOne test env with
Parsing.Parse_error -> ("parse error",env)
| DynamicTypeError -> ("dynamic type error",env)
| MatchFailure -> ("match failure",env)
| ImplementMe s -> ("implement me",env) in
(resultStrings@[res], newenv)
)
([], Env.empty_env()) tests
in
List.iter2
(fun (t,er) r ->
let out = if er=r then "ok" else "expected " ^ er ^ " but got " ^ r in
print_endline
(t ^ "....................." ^ out))
tests results
(* CALL THIS FUNCTION TO RUN THE TESTS *)
let runtests() = test tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment