diff options
| author | Mustafa Quraish <[email protected]> | 2022-02-02 07:20:53 -0500 |
|---|---|---|
| committer | Mustafa Quraish <[email protected]> | 2022-02-02 07:37:39 -0500 |
| commit | 1a8f96c65f94227faa9747ef876a60f3c313c6f1 (patch) | |
| tree | d80a396958ff2fc752b620cc5314e27e40b58ecb /tests | |
| parent | Use `type*` instead of `type&` to denote a pointer type (for now) (diff) | |
| download | cup-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-x | tests/conditions.sh | 18 | ||||
| -rwxr-xr-x | tests/core.sh | 116 | ||||
| -rwxr-xr-x | tests/functions.sh | 44 | ||||
| -rwxr-xr-x | tests/loops.sh | 20 | ||||
| -rwxr-xr-x | tests/variables.sh | 36 |
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; |