aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorMustafa Quraish <[email protected]>2022-02-02 07:20:53 -0500
committerMustafa Quraish <[email protected]>2022-02-02 07:37:39 -0500
commit1a8f96c65f94227faa9747ef876a60f3c313c6f1 (patch)
treed80a396958ff2fc752b620cc5314e27e40b58ecb /tests
parentUse `type*` instead of `type&` to denote a pointer type (for now) (diff)
downloadcup-1a8f96c65f94227faa9747ef876a60f3c313c6f1.tar.xz
cup-1a8f96c65f94227faa9747ef876a60f3c313c6f1.zip
Type checking of expressions / functions!
This is a bit of a chonky commit, but it adds in the basics of checking the types of expressions / function calls / return types. There's still a lot of work to be done, including: (1) Adding new core types, and casting between allowed types automatically (2) Picking the corrent output type based on input types (for instance float+int == float) (3) We need much better error reporting, the error messages are really vague and unhelpful as-is (4) We also need to work to ensure that a function with a return type actually returns (5) Possible re-factoring to make stuff less hacky when we have more types / structs / arrays / etc.
Diffstat (limited to 'tests')
-rwxr-xr-xtests/conditions.sh18
-rwxr-xr-xtests/core.sh116
-rwxr-xr-xtests/functions.sh44
-rwxr-xr-xtests/loops.sh20
-rwxr-xr-xtests/variables.sh36
5 files changed, 117 insertions, 117 deletions
diff --git a/tests/conditions.sh b/tests/conditions.sh
index be80d96..b10948e 100755
--- a/tests/conditions.sh
+++ b/tests/conditions.sh
@@ -5,12 +5,12 @@
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 'fn main(): int { return 1 ? 5 : 10; }' 5
+assert_exit_status 'fn main(): int { return 0 ? 5 : 10; }' 10
+assert_exit_status 'fn main(): int { return 1 < 2 ? 10 : 20; }' 10
assert_exit_status_stdin 5 <<EOF
-fn main() {
+fn main(): int {
let flag: int = 1;
let a: int;
flag ? a = 5 : a = 10;
@@ -19,7 +19,7 @@ fn main() {
EOF
assert_exit_status_stdin 10 <<EOF
-fn main() {
+fn main(): int {
let flag: int = 0;
let a: int;
flag ? a = 5 : a = 10;
@@ -30,21 +30,21 @@ echo " OK"
echo -n "- If statement: "
assert_exit_status_stdin 10 <<EOF
-fn main() {
+fn main(): int {
if (5 < 20) return 10;
return 3;
}
EOF
assert_exit_status_stdin 3 <<EOF
-fn main() {
+fn main(): int {
if (5 > 20) return 10;
return 3;
}
EOF
assert_exit_status_stdin 20 <<EOF
-fn main() {
+fn main(): int {
let x: int;
if (0)
x = 3;
@@ -55,7 +55,7 @@ fn main() {
EOF
assert_exit_status_stdin 3 <<EOF
-fn main() {
+fn main(): int {
let x: int;
if (1)
x = 3;
diff --git a/tests/core.sh b/tests/core.sh
index 71c539d..7b62208 100755
--- a/tests/core.sh
+++ b/tests/core.sh
@@ -5,75 +5,75 @@
set -e
echo -n "- Basic return: "
-assert_exit_status 'fn main() { return 0; }' 0
-assert_exit_status 'fn main() { return 1; }' 1
-assert_exit_status 'fn main() { return 100; }' 100
+assert_exit_status 'fn main(): int { return 0; }' 0
+assert_exit_status 'fn main(): int { return 1; }' 1
+assert_exit_status 'fn main(): int { return 100; }' 100
echo " OK"
echo -n "- Unary ops: "
-assert_exit_status 'fn main() { return -1; }' 255
-assert_exit_status 'fn main() { return -100; }' 156
-assert_exit_status 'fn main() { return !0; }' 1
-assert_exit_status 'fn main() { return !1; }' 0
-assert_exit_status 'fn main() { return !34; }' 0
-assert_exit_status 'fn main() { return !-1; }' 0
-assert_exit_status 'fn main() { return ~34; }' 221
+assert_exit_status 'fn main(): int { return -1; }' 255
+assert_exit_status 'fn main(): int { return -100; }' 156
+assert_exit_status 'fn main(): int { return !0; }' 1
+assert_exit_status 'fn main(): int { return !1; }' 0
+assert_exit_status 'fn main(): int { return !34; }' 0
+assert_exit_status 'fn main(): int { return !-1; }' 0
+assert_exit_status 'fn main(): int { return ~34; }' 221
echo " OK"
echo -n "- Arith Binary ops: "
-assert_exit_status 'fn main() { return 1 + 1; }' 2
-assert_exit_status 'fn main() { return 1 + 100; }' 101
-assert_exit_status 'fn main() { return 100 + 1; }' 101
-assert_exit_status 'fn main() { return 1 - 1; }' 0
-assert_exit_status 'fn main() { return 1 - 100; }' 157
-assert_exit_status 'fn main() { return 100 - 1; }' 99
-assert_exit_status 'fn main() { return 1 * 1; }' 1
-assert_exit_status 'fn main() { return 1 * 100; }' 100
-assert_exit_status 'fn main() { return 100 * 1; }' 100
-assert_exit_status 'fn main() { return 7 * 3; }' 21
-assert_exit_status 'fn main() { return 1 / 1; }' 1
-assert_exit_status 'fn main() { return 100 / 1; }' 100
-assert_exit_status 'fn main() { return 100 / 7; }' 14
-assert_exit_status 'fn main() { return 100 / 100; }' 1
-assert_exit_status 'fn main() { return 100 / -1; }' 156
+assert_exit_status 'fn main(): int { return 1 + 1; }' 2
+assert_exit_status 'fn main(): int { return 1 + 100; }' 101
+assert_exit_status 'fn main(): int { return 100 + 1; }' 101
+assert_exit_status 'fn main(): int { return 1 - 1; }' 0
+assert_exit_status 'fn main(): int { return 1 - 100; }' 157
+assert_exit_status 'fn main(): int { return 100 - 1; }' 99
+assert_exit_status 'fn main(): int { return 1 * 1; }' 1
+assert_exit_status 'fn main(): int { return 1 * 100; }' 100
+assert_exit_status 'fn main(): int { return 100 * 1; }' 100
+assert_exit_status 'fn main(): int { return 7 * 3; }' 21
+assert_exit_status 'fn main(): int { return 1 / 1; }' 1
+assert_exit_status 'fn main(): int { return 100 / 1; }' 100
+assert_exit_status 'fn main(): int { return 100 / 7; }' 14
+assert_exit_status 'fn main(): int { return 100 / 100; }' 1
+assert_exit_status 'fn main(): int { return 100 / -1; }' 156
echo " OK"
echo -n "- Relational ops: "
-assert_exit_status 'fn main() { return 1 == 1; }' 1
-assert_exit_status 'fn main() { return 1 == 2; }' 0
-assert_exit_status 'fn main() { return 1 != 1; }' 0
-assert_exit_status 'fn main() { return 1 != 2; }' 1
+assert_exit_status 'fn main(): int { return 1 == 1; }' 1
+assert_exit_status 'fn main(): int { return 1 == 2; }' 0
+assert_exit_status 'fn main(): int { return 1 != 1; }' 0
+assert_exit_status 'fn main(): int { return 1 != 2; }' 1
-assert_exit_status 'fn main() { return 1 < 2; }' 1
-assert_exit_status 'fn main() { return 2 < 2; }' 0
+assert_exit_status 'fn main(): int { return 1 < 2; }' 1
+assert_exit_status 'fn main(): int { return 2 < 2; }' 0
-assert_exit_status 'fn main() { return 1 <= 2; }' 1
-assert_exit_status 'fn main() { return 2 <= 2; }' 1
-assert_exit_status 'fn main() { return 3 <= 2; }' 0
+assert_exit_status 'fn main(): int { return 1 <= 2; }' 1
+assert_exit_status 'fn main(): int { return 2 <= 2; }' 1
+assert_exit_status 'fn main(): int { return 3 <= 2; }' 0
-assert_exit_status 'fn main() { return 2 > 2; }' 0
-assert_exit_status 'fn main() { return 3 > 2; }' 1
+assert_exit_status 'fn main(): int { return 2 > 2; }' 0
+assert_exit_status 'fn main(): int { return 3 > 2; }' 1
-assert_exit_status 'fn main() { return 1 >= 2; }' 0
-assert_exit_status 'fn main() { return 2 >= 2; }' 1
-assert_exit_status 'fn main() { return 3 >= 2; }' 1
+assert_exit_status 'fn main(): int { return 1 >= 2; }' 0
+assert_exit_status 'fn main(): int { return 2 >= 2; }' 1
+assert_exit_status 'fn main(): int { return 3 >= 2; }' 1
echo " OK"
echo -n "- Simple logical ops: "
-assert_exit_status 'fn main() { return 0 && 0; }' 0
-assert_exit_status 'fn main() { return 0 && 5; }' 0
-assert_exit_status 'fn main() { return 5 && 0; }' 0
-assert_exit_status 'fn main() { return 5 && 1; }' 1
-
-assert_exit_status 'fn main() { return 0 || 0; }' 0
-assert_exit_status 'fn main() { return 5 || 0; }' 1
-assert_exit_status 'fn main() { return 0 || 3; }' 1
-assert_exit_status 'fn main() { return 2 || 1; }' 1
+assert_exit_status 'fn main(): int { return 0 && 0; }' 0
+assert_exit_status 'fn main(): int { return 0 && 5; }' 0
+assert_exit_status 'fn main(): int { return 5 && 0; }' 0
+assert_exit_status 'fn main(): int { return 5 && 1; }' 1
+
+assert_exit_status 'fn main(): int { return 0 || 0; }' 0
+assert_exit_status 'fn main(): int { return 5 || 0; }' 1
+assert_exit_status 'fn main(): int { return 0 || 3; }' 1
+assert_exit_status 'fn main(): int { return 2 || 1; }' 1
echo " OK"
echo -n "- Short-circuiting: "
assert_exit_status_stdin 5 <<EOF
-fn main() {
+fn main(): int {
let x: int = 5;
let y: int = (1 || (x = 10));
return x;
@@ -81,7 +81,7 @@ fn main() {
EOF
assert_exit_status_stdin 10 <<EOF
-fn main() {
+fn main(): int {
let x: int = 5;
let y: int = (0 || (x = 10));
return x;
@@ -89,7 +89,7 @@ fn main() {
EOF
assert_exit_status_stdin 5 <<EOF
-fn main() {
+fn main(): int {
let x: int = 5;
let y: int = (0 && (x = 10));
return x;
@@ -97,7 +97,7 @@ fn main() {
EOF
assert_exit_status_stdin 10 <<EOF
-fn main() {
+fn main(): int {
let x: int = 5;
let y: int = (1 && (x = 10));
return x;
@@ -109,7 +109,7 @@ echo -n "- Importing file: "
assert_exit_status_stdin 10 <<EOF
import "std/math.cup"
-fn main() {
+fn main(): int {
let x: int = abs(-5);
let y: int = factorial(3);
return x + y - 1;
@@ -117,7 +117,7 @@ fn main() {
EOF
assert_compile_failure_stdin <<EOF
-fn main() {
+fn main(): int {
let x: int = abs(-5);
let y: int = factorial(3);
return x + y - 1;
@@ -127,7 +127,7 @@ echo " OK"
echo -n "- Defer: "
assert_stdout_text \
-"fn main() {
+"fn main(): int {
defer print(5);
print(4);
}" \
@@ -135,7 +135,7 @@ assert_stdout_text \
5"
assert_stdout_text \
-"fn main() {
+"fn main(): int {
defer print(1);
{
defer print(2);
@@ -162,7 +162,7 @@ assert_stdout_text \
}
print(3);
}
-fn main() {
+fn main(): int {
defer print(4);
defer test();
print(10);
@@ -180,7 +180,7 @@ fn test(): int {
defer g = 10;
return g;
}
-fn main() {
+fn main(): int {
print(test());
print(g);
}" \
diff --git a/tests/functions.sh b/tests/functions.sh
index e8c79f2..c188bd1 100755
--- a/tests/functions.sh
+++ b/tests/functions.sh
@@ -8,61 +8,61 @@ set -e
echo -n "- Different argument counts: "
assert_exit_status_stdin 5 <<EOF
-fn test() { return 5; }
-fn main() { return test(); }
+fn test(): int { return 5; }
+fn main(): int { return test(); }
EOF
assert_exit_status_stdin 5 <<EOF
-fn test(a: int) { return a; }
-fn main() { return test(5); }
+fn test(a: int): int { return a; }
+fn main(): int { return test(5); }
EOF
assert_exit_status_stdin 5 <<EOF
-fn test(a: int, b: int) { return a+b; }
-fn main() { return test(2, 3); }
+fn test(a: int, b: int): int { return a+b; }
+fn main(): int { return test(2, 3); }
EOF
assert_exit_status_stdin 5 <<EOF
-fn test(a: int, b: int) { let n: int = a + b; return n; }
-fn main() { return test(2, 3); }
+fn test(a: int, b: int): int { let n: int = a + b; return n; }
+fn main(): int { return test(2, 3); }
EOF
assert_exit_status_stdin 5 <<EOF
-fn test(a: int, b: int, c: int, d: int, e: int) { return a+b+c+d+e; }
-fn main() { return test(1,1,1,1,1); }
+fn test(a: int, b: int, c: int, d: int, e: int): int { return a+b+c+d+e; }
+fn main(): int { return test(1,1,1,1,1); }
EOF
assert_compile_failure_stdin <<EOF
-fn test() { return 5; }
-fn main() { return test(5); }
+fn test(): int { return 5; }
+fn main(): int { return test(5); }
EOF
assert_compile_failure_stdin <<EOF
-fn test(a: int, b: int, c: int) { return 5; }
-fn main() { return test(5); }
+fn test(a: int, b: int, c: int): int { return 5; }
+fn main(): int { return test(5); }
EOF
assert_compile_failure_stdin <<EOF
-fn test(a: int, b: int, c: int) { return 5; }
-fn main() { return test(5, 6, 5, 8); }
+fn test(a: int, b: int, c: int): int { return 5; }
+fn main(): int { return test(5, 6, 5, 8); }
EOF
echo " OK"
echo -n "- Recursion: "
assert_exit_status_stdin 3 <<EOF
-fn test(n: int) { return n == 0 ? 0 : 1 + test(n-1); }
-fn main() { return test(3); }
+fn test(n: int): int { return n == 0 ? 0 : 1 + test(n-1); }
+fn main(): int { return test(3); }
EOF
assert_exit_status_stdin 55 <<EOF
-fn test(n: int) { return n == 0 ? 0 : n + test(n-1); }
-fn main() { return test(10); }
+fn test(n: int): int { return n == 0 ? 0 : n + test(n-1); }
+fn main(): int { return test(10); }
EOF
assert_exit_status_stdin 55 <<EOF
-fn test(n: int, accum: int) { return n == 0 ? accum : test(n-1, n+accum); }
-fn main() { return test(10,0); }
+fn test(n: int, accum: int): int { return n == 0 ? accum : test(n-1, n+accum); }
+fn main(): int { return test(10,0); }
EOF
echo " OK" \ No newline at end of file
diff --git a/tests/loops.sh b/tests/loops.sh
index 3fea60f..ab0a949 100755
--- a/tests/loops.sh
+++ b/tests/loops.sh
@@ -6,7 +6,7 @@ set -e
echo -n "- While loops: "
assert_exit_status_stdin 5 <<EOF
-fn main() {
+fn main(): int {
while (1) {
return 5;
}
@@ -15,7 +15,7 @@ fn main() {
EOF
assert_exit_status_stdin 3 <<EOF
-fn main() {
+fn main(): int {
while (0) {
return 5;
}
@@ -24,7 +24,7 @@ fn main() {
EOF
assert_exit_status_stdin 10 <<EOF
-fn main() {
+fn main(): int {
let sum: int = 0;
while (sum < 10) {
sum = sum + 1;
@@ -34,7 +34,7 @@ fn main() {
EOF
assert_exit_status_stdin 55 <<EOF
-fn main() {
+fn main(): int {
let sum: int = 0;
let N: int = 10;
let i: int = 0;
@@ -49,7 +49,7 @@ echo " OK"
echo -n "- For loops: "
assert_exit_status_stdin 5 <<EOF
-fn main() {
+fn main(): int {
for (;;) {
return 5;
}
@@ -58,7 +58,7 @@ fn main() {
EOF
assert_exit_status_stdin 3 <<EOF
-fn main() {
+fn main(): int {
for (;0;) {
return 5;
}
@@ -67,7 +67,7 @@ fn main() {
EOF
assert_exit_status_stdin 55 <<EOF
-fn main() {
+fn main(): int {
let sum: int = 0;
let i: int;
for (i = 0; i <= 10; i = i + 1) {
@@ -78,7 +78,7 @@ fn main() {
EOF
assert_exit_status_stdin 55 <<EOF
-fn main() {
+fn main(): int {
let sum: int = 0;
let i: int = 0;
for (; i <= 10; i = i + 1) {
@@ -89,7 +89,7 @@ fn main() {
EOF
assert_exit_status_stdin 45 <<EOF
-fn main() {
+fn main(): int {
let sum: int = 0;
let i: int = 0;
for (;i < 10;) {
@@ -101,7 +101,7 @@ fn main() {
EOF
assert_exit_status_stdin 55 <<EOF
-fn main() {
+fn main(): int {
let sum: int = 0;
let i: int = 0;
for (;;) {
diff --git a/tests/variables.sh b/tests/variables.sh
index ffa66c3..93e9bd8 100755
--- a/tests/variables.sh
+++ b/tests/variables.sh
@@ -5,12 +5,12 @@
set -e
echo -n "- One variable: "
-assert_exit_status 'fn main() { let x: int; x = 45; return x; }' 45
-assert_exit_status 'fn main() { let x: int = 45; return x; }' 45
-assert_exit_status 'fn main() { let x: int = 45; return x+x; }' 90
+assert_exit_status 'fn main(): int { let x: int; x = 45; return x; }' 45
+assert_exit_status 'fn main(): int { let x: int = 45; return x; }' 45
+assert_exit_status 'fn main(): int { let x: int = 45; return x+x; }' 90
assert_exit_status_stdin 5 <<EOF
-fn main() {
+fn main(): int {
let x: int;
x = 3;
x = 5;
@@ -19,7 +19,7 @@ fn main() {
EOF
assert_exit_status_stdin 5 <<EOF
-fn main() {
+fn main(): int {
let x: int = 3;
x = x + x - 1;
return x;
@@ -30,7 +30,7 @@ echo " OK"
echo -n "- Multiple variable: "
assert_exit_status_stdin 2 <<EOF
-fn main() {
+fn main(): int {
let x: int = 1;
let y: int = x + x;
return y;
@@ -38,7 +38,7 @@ fn main() {
EOF
assert_exit_status_stdin 23 <<EOF
-fn main() {
+fn main(): int {
let x: int = 1;
let y: int = x + x;
let z: int = y + y;
@@ -49,7 +49,7 @@ fn main() {
EOF
assert_exit_status_stdin 2 <<EOF
-fn main() {
+fn main(): int {
let x: int = 1;
let y: int = x + x;
y = y + x;
@@ -59,7 +59,7 @@ fn main() {
EOF
assert_exit_status_stdin 18 <<EOF
-fn main() {
+fn main(): int {
let x: int = 5;
let y: int;
let z: int = (y = x + 3) + 2;
@@ -71,7 +71,7 @@ echo " OK"
echo -n "- Global variables: "
assert_exit_status_stdin 18 <<EOF
let g: int;
-fn main() {
+fn main(): int {
g = 18;
return g;
}
@@ -80,7 +80,7 @@ EOF
assert_exit_status_stdin 18 <<EOF
let g: int;
let h: int;
-fn main() {
+fn main(): int {
g = 18;
h = g + g;
return h - g;
@@ -96,7 +96,7 @@ fn test() {
h = g + g;
}
-fn main() {
+fn main(): int {
test();
return h - g;
}
@@ -105,7 +105,7 @@ EOF
assert_compile_failure_stdin <<EOF
let g: int = 0;
-fn main() {
+fn main(): int {
return g;
}
EOF
@@ -113,7 +113,7 @@ echo " OK"
echo -n "- Nested Blocks: "
assert_exit_status_stdin 3 <<EOF
-fn main() {
+fn main(): int {
let x: int = 1;
{
let y: int = 3;
@@ -216,7 +216,7 @@ echo " OK"
echo -n "- Conditionals w/ blocks: "
assert_exit_status_stdin 3 <<EOF
-fn main() {
+fn main(): int {
let x: int = 1;
if (x == 1) {
let y: int = 3;
@@ -227,7 +227,7 @@ fn main() {
EOF
assert_exit_status_stdin 1 <<EOF
-fn main() {
+fn main(): int {
let x: int = 1;
if (x != 1) {
let y: int = 3;
@@ -238,7 +238,7 @@ fn main() {
EOF
assert_exit_status_stdin 5 <<EOF
-fn main() {
+fn main(): int {
let x: int = 1;
if (x != 1) {
let y: int = 3;
@@ -252,7 +252,7 @@ fn main() {
EOF
assert_compile_failure_stdin <<EOF
-fn main() {
+fn main(): int {
let x: int = 1;
if (x != 1) {
let y: int = 3;