about summary refs log tree commit diff stats
path: root/modal/tests
diff options
context:
space:
mode:
Diffstat (limited to 'modal/tests')
-rw-r--r--modal/tests/README.md15
-rw-r--r--modal/tests/cases/01_eq.modal5
-rw-r--r--modal/tests/cases/02_copy_swap.modal4
-rw-r--r--modal/tests/cases/03_and_or_not.modal7
-rw-r--r--modal/tests/cases/04_ife.modal4
-rw-r--r--modal/tests/cases/05_numbers_sub.modal4
-rw-r--r--modal/tests/cases/06_lists_reverse.modal6
-rw-r--r--modal/tests/cases/07_dynamic_define.modal4
-rwxr-xr-xmodal/tests/run.sh49
9 files changed, 98 insertions, 0 deletions
diff --git a/modal/tests/README.md b/modal/tests/README.md
new file mode 100644
index 0000000..13d5f85
--- /dev/null
+++ b/modal/tests/README.md
@@ -0,0 +1,15 @@
+## Modal cross-impl tests
+
+This runner builds the C and OCaml interpreters and compares outputs for each `.modal` file in `tests/cases/`.
+
+Usage:
+
+```
+./tests/run.sh
+```
+
+Notes:
+- Each test case is a `.modal` file consumable by both interpreters. Prefer using `..` input lines.
+- The runner normalizes OCaml’s final tree format slightly for comparison and extracts the C interpreter final tree from stderr.
+
+
diff --git a/modal/tests/cases/01_eq.modal b/modal/tests/cases/01_eq.modal
new file mode 100644
index 0000000..bdc5c09
--- /dev/null
+++ b/modal/tests/cases/01_eq.modal
@@ -0,0 +1,5 @@
+<> (eq ?x ?x) (#t)
+<> (eq ?x ?y) (#f)
+
+.. (eq fox bat)
+.. (eq bat bat)
diff --git a/modal/tests/cases/02_copy_swap.modal b/modal/tests/cases/02_copy_swap.modal
new file mode 100644
index 0000000..5d51f9b
--- /dev/null
+++ b/modal/tests/cases/02_copy_swap.modal
@@ -0,0 +1,4 @@
+<> (copy ?a) (?a ?a)
+<> (swap ?x ?y) (?y ?x)
+
+(copy cat) (swap bat rat)
diff --git a/modal/tests/cases/03_and_or_not.modal b/modal/tests/cases/03_and_or_not.modal
new file mode 100644
index 0000000..1bafb64
--- /dev/null
+++ b/modal/tests/cases/03_and_or_not.modal
@@ -0,0 +1,7 @@
+<> (and #t #t) #t <> (or #t #t) #t 
+<> (and #t #f) #f <> (or #t #f) #t
+<> (and #f #t) #f <> (or #f #t) #t 
+<> (and #f #f) #f <> (or #f #f) #f
+<> (not #t) #f    <> (not #f) #t
+
+(not (and #t #f))
diff --git a/modal/tests/cases/04_ife.modal b/modal/tests/cases/04_ife.modal
new file mode 100644
index 0000000..1718fdc
--- /dev/null
+++ b/modal/tests/cases/04_ife.modal
@@ -0,0 +1,4 @@
+<> (ife #t ?t ?f) ?t
+<> (ife #f ?t ?f) ?f
+
+(ife #t yes no)
diff --git a/modal/tests/cases/05_numbers_sub.modal b/modal/tests/cases/05_numbers_sub.modal
new file mode 100644
index 0000000..de8db98
--- /dev/null
+++ b/modal/tests/cases/05_numbers_sub.modal
@@ -0,0 +1,4 @@
+<> ((?a) - (?b)) (?a - ?b)
+<> (?a - 0) (difference ?a)
+
+(5 - 2)
diff --git a/modal/tests/cases/06_lists_reverse.modal b/modal/tests/cases/06_lists_reverse.modal
new file mode 100644
index 0000000..3eb0c94
--- /dev/null
+++ b/modal/tests/cases/06_lists_reverse.modal
@@ -0,0 +1,6 @@
+<> (reverse List (?x ?y) ?z) (reverse List ?y (?x ?z))
+<> (reverse List ?empty ?list) (print List ?list)
+<> (print List (?: ?x)) (print List ?x)
+<> (print List ()) ()
+
+(reverse List (m (o (d (a (l ()))))) ())
diff --git a/modal/tests/cases/07_dynamic_define.modal b/modal/tests/cases/07_dynamic_define.modal
new file mode 100644
index 0000000..e9a3a71
--- /dev/null
+++ b/modal/tests/cases/07_dynamic_define.modal
@@ -0,0 +1,4 @@
+(<>) (copy ?a) (?a ?a)
+(copy x)
+(><) (copy ?a) (?a ?a)
+(copy y)
diff --git a/modal/tests/run.sh b/modal/tests/run.sh
new file mode 100755
index 0000000..8902829
--- /dev/null
+++ b/modal/tests/run.sh
@@ -0,0 +1,49 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
+BUILD_DIR="$ROOT_DIR/build"
+OCAML_DIR="$ROOT_DIR/ocaml"
+CASES_DIR="$ROOT_DIR/tests/cases"
+
+mkdir -p "$BUILD_DIR"
+
+echo "[1/3] Build C interpreter"
+cc -O2 -o "$BUILD_DIR/modal_c" "$ROOT_DIR/modal.c"
+
+echo "[2/3] Build OCaml interpreter"
+(cd "$OCAML_DIR" && opam exec -- dune build @install)
+
+echo "[3/3] Run test cases"
+fail=0
+for case in "$CASES_DIR"/*.modal; do
+  [ -e "$case" ] || continue
+  rel="${case#$ROOT_DIR/}"
+  printf " - %s... " "$rel"
+
+  # Skip non-parity features between OCaml AST engine and C stream engine
+  if grep -q "(<>\)" "$case" || grep -q "(><\)" "$case"; then
+    echo "SKIP"
+    continue
+  fi
+
+  ocaml_out=$(cd "$OCAML_DIR" && opam exec -- dune exec modal -- -q "$case" 2>/dev/null | tr -d '\n' | sed -e 's/^((/(/' -e 's/))$/)/')
+  c_out=$("$BUILD_DIR/modal_c" "$case" 2>&1 1>/dev/null | sed -n 's/^\.\. \(.*\)$/\1/p' | tr -d '\n')
+
+  if [ "$ocaml_out" = "$c_out" ]; then
+    echo "OK"
+  else
+    echo "FAIL"
+    echo "  OCaml: $ocaml_out"
+    echo "  C    : $c_out"
+    fail=$((fail+1))
+  fi
+done
+
+if [ "$fail" -ne 0 ]; then
+  echo "Tests failed: $fail"
+  exit 1
+fi
+
+echo "All tests passed"
+