[Header] open K__ open K let test_run pgm_str = let pgm = Parser.program Lexer.start (Lexing.from_string pgm_str) in K.run (K.emptyMemory, K.emptyEnv, pgm) let test_error_str pgm_str = let pgm = Parser.program Lexer.start (Lexing.from_string pgm_str) in try (try let _ = K.run (K.emptyMemory, K.emptyEnv, pgm) in "" with K.Error s -> String.sub s 0 7) with Invalid_argument _ -> "" [Test] (* 1. let, assignment, arithmetic *) test_run " let x := 5 in let y := 0 in ((x := 6) - 3) * 4 + (y := x * 2) / 5 + y " [Value] K.Num 14 [Test] (* 2. branch, sequence, write *) test_run " if (3 < 5) then ( write 1; if (not false) then ( write 11; if (20 < 10) then write 111 else write 222 ) else write 22 ) else false " [Output] 1 11 222 [Test] (* 3. type error in arithmetic *) test_error_str " true + 2 " [Value] "TypeErr" [Test] (* 4. while + let *) test_run "let x := 1 in let sum := 0 in while (x < 11) do ( sum := sum + x; x := x + 1 ); sum" [Value] K.Num 55 [Test] (* 5. equal + unbound in false branch *) test_run " if 3 < 2 then x else ( if (false = 3) then y else 25 ) " [Value] K.Num 25 [Test] (* 6. result of assign *) test_run " let x := 3 in write x * (x := x + 1); write (x := x + 1) * x; if (x := 0) < x then write x; while (x := x + 1) < 3 do write x else false " [Output] 16 20 0 1 2 [Test] (* 7. scope *) test_run " let x := 0 in let z := (let x := (x := 3; x + 1) in x := x + 1; (x := x + 1) * (let x := 2 in x := x + 1)) in z " [Value] K.Num 18 [Test] (* 8. unbound variable *) test_error_str " let y:= let x := 5 in x in x + y " [Value] "Unbound" [Test] (* 9. Factorial but convoluted *) test_run "let n := 10 in let prod := 1 in let cond := true in while (cond := (0 < n)) do ( prod := prod * n; n := n - 1 ); if (false = 0) then cond := true else prod" [Value] K.Num 3628800 [Test] (* 10. GCD *) test_run "let n := 9168 in let m := 1337 in while (not (n = 0)) do ( let r := m - (m / n) * n in m := n; n := r ); m" [Value] K.Num 191