aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorMustafa Quraish <[email protected]>2022-01-29 17:37:00 -0500
committerMustafa Quraish <[email protected]>2022-01-29 17:37:00 -0500
commita9683512b29abd53814bf834e23f752a8999a679 (patch)
tree033d76dbf7b1249354d2967b9de53fd6af20b7cb /tests
parentAdd i64{max,min} helper functions (diff)
downloadcup-a9683512b29abd53814bf834e23f752a8999a679.tar.xz
cup-a9683512b29abd53814bf834e23f752a8999a679.zip
Implement blocks (lexically scoped) and conditionals
Diffstat (limited to 'tests')
-rw-r--r--tests/common.sh20
-rwxr-xr-xtests/compound.sh161
-rwxr-xr-xtests/conditions.sh65
-rwxr-xr-xtests/variables.sh43
4 files changed, 287 insertions, 2 deletions
diff --git a/tests/common.sh b/tests/common.sh
index dd64ade..80e0bea 100644
--- a/tests/common.sh
+++ b/tests/common.sh
@@ -13,6 +13,7 @@ function assert_exit_status() {
set +e
./a.out
res=$?
+ set -e
if [ $res -ne $2 ]
then
echo ""
@@ -22,11 +23,28 @@ function assert_exit_status() {
echo "$1"
exit 1
fi
- set -e
echo -n "."
}
function assert_exit_status_stdin() {
code=$(</dev/stdin)
assert_exit_status "$code" $1
+}
+
+function assert_compile_failure_stdin() {
+ code=$(</dev/stdin)
+ set +e
+ ./cupcc -c "$code" >/dev/null 2>&1
+ res=$?
+ set -e
+ if [ $res -eq 0 ]
+ then
+ echo ""
+ echo "----------------------------------------------"
+ echo "Test failed: expected compilation, got success"
+ echo "----------------------------------------------"
+ echo "$code"
+ exit 1
+ fi
+ echo -n "."
} \ No newline at end of file
diff --git a/tests/compound.sh b/tests/compound.sh
new file mode 100755
index 0000000..cb49fa0
--- /dev/null
+++ b/tests/compound.sh
@@ -0,0 +1,161 @@
+#!/bin/bash
+
+# Test compound scopes
+
+. tests/common.sh
+
+set -e
+
+echo -n "- Nested Blocks: "
+assert_exit_status_stdin 3 <<EOF
+fn main() {
+ let x: int = 1;
+ {
+ let y: int = 3;
+ x = y;
+ }
+ return x;
+}
+EOF
+
+assert_exit_status_stdin 15 <<EOF
+fn main(): int {
+ let x: int;
+ {
+ let y: int = 10;
+ {
+ let z: int = 5;
+ x = y + z;
+ }
+ }
+ return x;
+}
+EOF
+
+assert_exit_status_stdin 8 <<EOF
+fn main(): int {
+ let x: int = 0;
+ {
+ let y: int = 3;
+ x = x + y;
+ }
+ {
+ let y: int = 5;
+ x = x + y;
+ }
+ return x;
+}
+EOF
+
+assert_compile_failure_stdin <<EOF
+fn main(): int {
+ let x: int;
+ {
+ let y: int = 10;
+ {
+ let z: int = 5;
+ x = y + z;
+ }
+ y = z;
+ }
+ return x;
+}
+EOF
+
+assert_compile_failure_stdin <<EOF
+fn main(): int {
+ let x: int;
+ {
+ let y: int = 10;
+ {
+ let z: int = 5;
+ x = y + z;
+ }
+ }
+ x = z;
+ return x;
+}
+EOF
+
+assert_compile_failure_stdin <<EOF
+fn main(): int {
+ let x: int;
+ {
+ let y: int = 10;
+ {
+ let z: int = 5;
+ x = y + z;
+ }
+ }
+ x = y;
+ return x;
+}
+EOF
+
+# We do not allow shadowing variables on purpose
+assert_compile_failure_stdin <<EOF
+fn main(): int {
+ let x: int;
+ {
+ let y: int = 10;
+ {
+ let z: int = 5;
+ x = y + z;
+ let x: int = 10;
+ }
+ }
+ return x;
+}
+EOF
+echo " OK"
+
+echo -n "- Conditionals w/ blocks: "
+assert_exit_status_stdin 3 <<EOF
+fn main() {
+ let x: int = 1;
+ if (x == 1) {
+ let y: int = 3;
+ x = y;
+ }
+ return x;
+}
+EOF
+
+assert_exit_status_stdin 1 <<EOF
+fn main() {
+ let x: int = 1;
+ if (x != 1) {
+ let y: int = 3;
+ x = y;
+ }
+ return x;
+}
+EOF
+
+assert_exit_status_stdin 5 <<EOF
+fn main() {
+ let x: int = 1;
+ if (x != 1) {
+ let y: int = 3;
+ x = y;
+ } else {
+ let y: int = 5;
+ x = y;
+ }
+ return x;
+}
+EOF
+
+assert_compile_failure_stdin <<EOF
+fn main() {
+ let x: int = 1;
+ if (x != 1) {
+ let y: int = 3;
+ x = y;
+ }
+ x = y; // Invalid
+ return x;
+}
+EOF
+
+echo " OK" \ No newline at end of file
diff --git a/tests/conditions.sh b/tests/conditions.sh
new file mode 100755
index 0000000..be80d96
--- /dev/null
+++ b/tests/conditions.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+
+. tests/common.sh
+
+set -e
+
+echo -n "- Conditionals: "
+assert_exit_status 'fn main() { return 1 ? 5 : 10; }' 5
+assert_exit_status 'fn main() { return 0 ? 5 : 10; }' 10
+assert_exit_status 'fn main() { return 1 < 2 ? 10 : 20; }' 10
+
+assert_exit_status_stdin 5 <<EOF
+fn main() {
+ let flag: int = 1;
+ let a: int;
+ flag ? a = 5 : a = 10;
+ return a;
+}
+EOF
+
+assert_exit_status_stdin 10 <<EOF
+fn main() {
+ let flag: int = 0;
+ let a: int;
+ flag ? a = 5 : a = 10;
+ return a;
+}
+EOF
+echo " OK"
+
+echo -n "- If statement: "
+assert_exit_status_stdin 10 <<EOF
+fn main() {
+ if (5 < 20) return 10;
+ return 3;
+}
+EOF
+
+assert_exit_status_stdin 3 <<EOF
+fn main() {
+ if (5 > 20) return 10;
+ return 3;
+}
+EOF
+
+assert_exit_status_stdin 20 <<EOF
+fn main() {
+ let x: int;
+ if (0)
+ x = 3;
+ else
+ x = 20;
+ return x;
+}
+EOF
+
+assert_exit_status_stdin 3 <<EOF
+fn main() {
+ let x: int;
+ if (1)
+ x = 3;
+ return x;
+}
+EOF
+echo " OK" \ No newline at end of file
diff --git a/tests/variables.sh b/tests/variables.sh
index 0c88784..7b44fe7 100755
--- a/tests/variables.sh
+++ b/tests/variables.sh
@@ -29,7 +29,6 @@ EOF
echo " OK"
echo -n "- Multiple variable: "
-
assert_exit_status_stdin 2 <<EOF
fn main() {
let x: int = 1;
@@ -59,4 +58,46 @@ fn main() {
}
EOF
+assert_exit_status_stdin 18 <<EOF
+fn main() {
+ let x: int = 5;
+ let y: int;
+ let z: int = (y = x + 3) + 2;
+ return z + y;
+}
+EOF
+echo " OK"
+
+echo -n "- Short-circuiting assignments: "
+assert_exit_status_stdin 5 <<EOF
+fn main() {
+ let x: int = 5;
+ let y: int = (1 || (x = 10));
+ return x;
+}
+EOF
+
+assert_exit_status_stdin 10 <<EOF
+fn main() {
+ let x: int = 5;
+ let y: int = (0 || (x = 10));
+ return x;
+}
+EOF
+
+assert_exit_status_stdin 5 <<EOF
+fn main() {
+ let x: int = 5;
+ let y: int = (0 && (x = 10));
+ return x;
+}
+EOF
+
+assert_exit_status_stdin 10 <<EOF
+fn main() {
+ let x: int = 5;
+ let y: int = (1 && (x = 10));
+ return x;
+}
+EOF
echo " OK"