aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-02-15 00:04:23 +0900
committernsfisis <nsfisis@gmail.com>2026-02-15 00:04:23 +0900
commit2009a26e17ad9dbefee3a5ca4339d754e51ef078 (patch)
tree5c311a1a17f40786f53f4a89c5bbbb72402a6b2d
parentef0cb4dbdc1c036f70f94a905cbacae9be5abf5e (diff)
downloadducc-2009a26e17ad9dbefee3a5ca4339d754e51ef078.tar.gz
ducc-2009a26e17ad9dbefee3a5ca4339d754e51ef078.tar.zst
ducc-2009a26e17ad9dbefee3a5ca4339d754e51ef078.zip
refactor: write more tests in C
-rw-r--r--tests/all.sh4
-rw-r--r--tests/empty_statements.c1
-rw-r--r--tests/empty_statements.sh6
-rw-r--r--tests/expressions.c107
-rw-r--r--tests/expressions.sh241
-rw-r--r--tests/for_loops.c86
-rw-r--r--tests/for_loops.sh158
-rw-r--r--tests/functions.c14
-rw-r--r--tests/functions.sh20
-rw-r--r--tests/pointers.c134
-rw-r--r--tests/pointers.sh317
-rw-r--r--tests/run.sh38
-rw-r--r--tests/structs.c241
-rw-r--r--tests/structs.sh389
-rw-r--r--tests/switch.c148
-rw-r--r--tests/switch.sh215
-rw-r--r--tests/types.c156
-rw-r--r--tests/types.sh245
-rw-r--r--tests/unions.c14
-rw-r--r--tests/unions.sh22
20 files changed, 942 insertions, 1614 deletions
diff --git a/tests/all.sh b/tests/all.sh
index 39d5ca6..dc62adf 100644
--- a/tests/all.sh
+++ b/tests/all.sh
@@ -5,10 +5,8 @@ mkdir -p tests/tmp
for filename in tests/*.sh tests/*.c; do
testcase="$(basename "$filename")"
- testcase="${testcase/%.sh/}"
- testcase="${testcase/%.c/}"
case "$testcase" in
- all|run|helpers)
+ all.sh|run.sh|helpers.sh|helpers.h)
;;
*)
source tests/run.sh "$testcase"
diff --git a/tests/empty_statements.c b/tests/empty_statements.c
new file mode 100644
index 0000000..0424cf2
--- /dev/null
+++ b/tests/empty_statements.c
@@ -0,0 +1 @@
+int main() { ; }
diff --git a/tests/empty_statements.sh b/tests/empty_statements.sh
deleted file mode 100644
index 8588944..0000000
--- a/tests/empty_statements.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-cat <<'EOF' > expected
-EOF
-
-test_diff <<'EOF'
-int main() { ; }
-EOF
diff --git a/tests/expressions.c b/tests/expressions.c
new file mode 100644
index 0000000..4214519
--- /dev/null
+++ b/tests/expressions.c
@@ -0,0 +1,107 @@
+#include <helpers.h>
+
+char get_char() {
+ return 65;
+}
+
+int glob_x, glob_y, glob_z = 5;
+
+int main() {
+ ASSERT_EQ(0, !1);
+ ASSERT_EQ(1, !0);
+ ASSERT_EQ(0, !23);
+
+ int a = 42;
+ ++a;
+ a++;
+ ASSERT_EQ(44, a);
+ ASSERT_EQ(44, a++);
+ ASSERT_EQ(46, ++a);
+ ASSERT_EQ(46, a);
+ --a;
+ a--;
+ ASSERT_EQ(44, a--);
+ ASSERT_EQ(42, --a);
+ ASSERT_EQ(42, a);
+
+ int va, vb;
+ va = 1, vb = 2;
+ int vc = 3, vd = 4;
+ ASSERT_EQ(1, va);
+ ASSERT_EQ(2, vb);
+ ASSERT_EQ(3, vc);
+ ASSERT_EQ(4, vd);
+ ASSERT_EQ(0, glob_x);
+ ASSERT_EQ(0, glob_y);
+ ASSERT_EQ(5, glob_z);
+
+ char c = 65;
+ int i = (int)c;
+ ASSERT_EQ(65, i);
+
+ int i2 = 321;
+ char c2 = (char)i2;
+ ASSERT_EQ(65, c2);
+
+ short s = 127;
+ int i3 = (int)s;
+ ASSERT_EQ(127, i3);
+
+ int i4 = 65537;
+ short s2 = (short)i4;
+ ASSERT_EQ(1, s2);
+
+ long l = 42;
+ int i5 = (int)l;
+ ASSERT_EQ(42, i5);
+
+ int i6 = 99;
+ long l2 = (long)i6;
+ ASSERT_EQ(99, (int)l2);
+
+ char c3 = 10;
+ short s3 = (short)c3;
+ int i7 = (int)s3;
+ long l3 = (long)i7;
+ ASSERT_EQ(10, (int)l3);
+
+ int ca = 42;
+ int cb = -(int)ca;
+ ASSERT_EQ(-42, cb);
+
+ char ce = 65;
+ int result = (int)ce + (int)ce;
+ ASSERT_EQ(130, result);
+
+ char ca2 = 5;
+ char cb2 = 5;
+ int sum = (int)ca2 + (int)cb2;
+ ASSERT_EQ(10, sum);
+
+ short s1 = 10;
+ short s2b = 10;
+ int sum2 = (int)s1 + (int)s2b;
+ ASSERT_EQ(20, sum2);
+
+ long l1 = 15;
+ long l2b = 15;
+ int sum3 = (int)(l1 + l2b);
+ ASSERT_EQ(30, sum3);
+
+ char cn = -10;
+ int in = (int)cn;
+ ASSERT_EQ(10, -in);
+
+ char cf = get_char();
+ int ifr = (int)get_char();
+ ASSERT_EQ(65, cf);
+ ASSERT_EQ(65, ifr);
+
+ char cmp = 42;
+ int icmp = 42;
+ ASSERT_EQ(1, (int)cmp == icmp);
+
+ long lc = 55;
+ char cc2 = (char)(short)(int)lc;
+ ASSERT_EQ(55, cc2);
+}
diff --git a/tests/expressions.sh b/tests/expressions.sh
index 8443774..bb0743b 100644
--- a/tests/expressions.sh
+++ b/tests/expressions.sh
@@ -1,4 +1,4 @@
-# logical operators
+# logical operators: short-circuit evaluation
cat <<'EOF' > expected
foo
EOF
@@ -51,53 +51,26 @@ int main() {
}
EOF
+# cast with typedef
cat <<'EOF' > expected
-0
-1
-0
+Result: -42
+Result: 0
EOF
test_diff <<'EOF'
-int printf();
-
-int main() {
- printf("%d\n", !1);
- printf("%d\n", !0);
- printf("%d\n", !23);
- return 0;
-}
-EOF
-
-# increment/decrement operators
-cat <<'EOF' > expected
-44
-44
-46
-46
-44
-42
-42
-EOF
+int printf(const char*, ...);
-test_diff <<'EOF'
-int printf();
+typedef int foo;
int main() {
int a = 42;
- ++a;
- a++;
- printf("%d\n", a);
- printf("%d\n", a++);
- printf("%d\n", ++a);
- printf("%d\n", a);
- --a;
- a--;
- printf("%d\n", a--);
- printf("%d\n", --a);
- printf("%d\n", a);
+ int b = -(int)a;
+ int c = !(foo)a;
+ printf("Result: %d\n", b);
+ printf("Result: %d\n", c);
}
EOF
-# comma operator
+# comma operator in for loop
cat <<'EOF' > expected
0 0
1 1
@@ -118,197 +91,7 @@ int main() {
}
EOF
-cat <<'EOF' > expected
-1 2 3 4
-0 0 5
-EOF
-
-test_diff <<'EOF'
-int printf();
-int x, y, z = 5;
-int main() {
- int a, b;
- a = 1, b = 2;
- int c = 3, d = 4;
- printf("%d %d %d %d\n", a, b, c, d);
- printf("%d %d %d\n", x, y, z);
-}
-EOF
-
-# cast expressions
-cat <<'EOF' > expected
-65
-65
-127
-1
-42
-99
-10
-EOF
-test_diff <<'EOF'
-int printf(const char*, ...);
-
-int main() {
- char c = 65;
- int i = (int)c;
- printf("%d\n", i);
-
- int i2 = 321;
- char c2 = (char)i2;
- printf("%d\n", c2);
-
- short s = 127;
- int i3 = (int)s;
- printf("%d\n", i3);
-
- int i4 = 65537;
- short s2 = (short)i4;
- printf("%d\n", s2);
-
- long l = 42;
- int i5 = (int)l;
- printf("%d\n", i5);
-
- int i6 = 99;
- long l2 = (long)i6;
- printf("%d\n", (int)l2);
-
- char c3 = 10;
- short s3 = (short)c3;
- int i7 = (int)s3;
- long l3 = (long)i7;
- printf("%d\n", (int)l3);
-
- return 0;
-}
-EOF
-
-cat <<'EOF' > expected
-Result: -42
-Result: 0
-EOF
-test_diff <<'EOF'
-int printf(const char*, ...);
-
-typedef int foo;
-
-int main() {
- int a = 42;
- int b = -(int)a;
- int c = !(foo)a;
- printf("Result: %d\n", b);
- printf("Result: %d\n", c);
-}
-EOF
-
-cat <<'EOF' > expected
-Result: 130
-EOF
-test_diff <<'EOF'
-int printf(const char*, ...);
-
-int main() {
- char c = 65;
- int result = (int)c + (int)c;
- printf("Result: %d\n", result);
- return 0;
-}
-EOF
-
-cat <<'EOF' > expected
-10
-20
-30
-EOF
-test_diff <<'EOF'
-int printf(const char*, ...);
-
-int main() {
- char a = 5;
- char b = 5;
- int sum = (int)a + (int)b;
- printf("%d\n", sum);
-
- short s1 = 10;
- short s2 = 10;
- int sum2 = (int)s1 + (int)s2;
- printf("%d\n", sum2);
-
- long l1 = 15;
- long l2 = 15;
- int sum3 = (int)(l1 + l2);
- printf("%d\n", sum3);
-
- return 0;
-}
-EOF
-
-cat <<'EOF' > expected
-10
-EOF
-test_diff <<'EOF'
-int printf(const char*, ...);
-
-int main() {
- char c = -10;
- int i = (int)c;
- printf("%d\n", -i);
- return 0;
-}
-EOF
-
-cat <<'EOF' > expected
-Char: 65
-Int: 65
-EOF
-test_diff <<'EOF'
-int printf(const char*, ...);
-
-char get_char() {
- return 65;
-}
-
-int main() {
- char c = get_char();
- int i = (int)get_char();
- printf("Char: %d\n", c);
- printf("Int: %d\n", i);
- return 0;
-}
-EOF
-
-cat <<'EOF' > expected
-Equal
-EOF
-test_diff <<'EOF'
-int printf(const char*, ...);
-
-int main() {
- char c = 42;
- int i = 42;
- if ((int)c == i) {
- printf("Equal\n");
- } else {
- printf("Not equal\n");
- }
- return 0;
-}
-EOF
-
-cat <<'EOF' > expected
-55
-EOF
-test_diff <<'EOF'
-int printf(const char*, ...);
-
-int main() {
- long l = 55;
- char c = (char)(short)(int)l;
- printf("%d\n", c);
- return 0;
-}
-EOF
-
+# void cast
cat <<'EOF' > expected
42
EOF
diff --git a/tests/for_loops.c b/tests/for_loops.c
new file mode 100644
index 0000000..9a70737
--- /dev/null
+++ b/tests/for_loops.c
@@ -0,0 +1,86 @@
+#include <helpers.h>
+
+int main() {
+ int i;
+ int ret;
+ i = 0;
+ ret = 0;
+ for (i = 0; i < 10; i = i + 1) {
+ ret = ret + i;
+ }
+ ASSERT_EQ(45, ret);
+
+ i = 0;
+ ret = 0;
+ for (i = 0; i < 10; i = i + 1) {
+ if (i % 2 == 0) {
+ continue;
+ }
+ ret = ret + i;
+ }
+ ASSERT_EQ(25, ret);
+
+ i = 0;
+ ret = 0;
+ for (i = 0; i < 100; i = i + 1) {
+ if (i == 12) {
+ break;
+ }
+ ret = ret + i;
+ }
+ ASSERT_EQ(66, ret);
+
+ int sum = 0;
+ i = 0;
+ for (; i < 5; i = i + 1) {
+ sum = sum + i;
+ }
+ ASSERT_EQ(10, sum);
+
+ sum = 0;
+ for (i = 10; i < 15; ) {
+ sum = sum + i;
+ i = i + 1;
+ }
+ ASSERT_EQ(60, sum);
+
+ sum = 0;
+ for (i = 20; ; i = i + 1) {
+ sum = sum + i;
+ if (i == 25) break;
+ }
+ ASSERT_EQ(135, sum);
+
+ sum = 0;
+ for (int j = 0; j < 10; j++) {
+ sum = sum + j;
+ }
+ ASSERT_EQ(45, sum);
+
+ int sum1 = 0;
+ for (int j = 0; j < 5; j++) {
+ sum1 = sum1 + j;
+ }
+ int sum2 = 0;
+ for (int j = 0; j < 5; j++) {
+ sum2 = sum2 + j;
+ }
+ ASSERT_EQ(10, sum1);
+ ASSERT_EQ(10, sum2);
+
+ int x = 42;
+ {
+ int x = 43;
+ ASSERT_EQ(43, x);
+ }
+ ASSERT_EQ(42, x);
+
+ int last_i = -1;
+ int last_j = -1;
+ for (int k = 0, l = 1; k < 5; k++, l += 2) {
+ last_i = k;
+ last_j = l;
+ }
+ ASSERT_EQ(4, last_i);
+ ASSERT_EQ(9, last_j);
+}
diff --git a/tests/for_loops.sh b/tests/for_loops.sh
deleted file mode 100644
index ef54d06..0000000
--- a/tests/for_loops.sh
+++ /dev/null
@@ -1,158 +0,0 @@
-test_exit_code 45 <<'EOF'
-int main() {
- int i;
- int ret;
- i = 0;
- ret = 0;
- for (i = 0; i < 10; i = i + 1) {
- ret = ret + i;
- }
- return ret;
-}
-EOF
-
-test_exit_code 25 <<'EOF'
-int main() {
- int i;
- int ret;
- i = 0;
- ret = 0;
- for (i = 0; i < 10; i = i + 1) {
- if (i % 2 == 0) {
- continue;
- }
- ret = ret + i;
- }
- return ret;
-}
-EOF
-
-test_exit_code 66 <<'EOF'
-int main() {
- int i;
- int ret;
- i = 0;
- ret = 0;
- for (i = 0; i < 100; i = i + 1) {
- if (i == 12) {
- break;
- }
- ret = ret + i;
- }
- return ret;
-}
-EOF
-
-cat <<'EOF' > expected
-0
-1
-2
-3
-4
-10
-11
-12
-13
-14
-20
-21
-22
-23
-24
-25
-EOF
-test_diff <<'EOF'
-int printf();
-
-int main() {
- int i = 0;
- for (; i < 5; i = i + 1) {
- printf("%d\n", i);
- }
- for (i = 10; i < 15; ) {
- printf("%d\n", i);
- i = i + 1;
- }
- for (i = 20; ; i = i + 1) {
- printf("%d\n", i);
- if (i == 25) break;
- }
-
- return 0;
-}
-EOF
-
-cat <<'EOF' > expected
-0
-1
-2
-3
-4
-5
-6
-7
-8
-9
-EOF
-
-test_diff <<'EOF'
-int printf();
-
-int main() {
- for (int i = 0; i < 10; i++) {
- printf("%d\n", i);
- }
-}
-EOF
-
-cat <<'EOF' > expected
-0
-1
-2
-3
-4
-0
-1
-2
-3
-4
-43
-42
-EOF
-
-test_diff <<'EOF'
-int printf();
-
-int main() {
- for (int i = 0; i < 5; i++) {
- printf("%d\n", i);
- }
- for (int i = 0; i < 5; i++) {
- printf("%d\n", i);
- }
- int x = 42;
- {
- int x = 43;
- printf("%d\n", x);
- }
- printf("%d\n", x);
-}
-EOF
-
-cat <<'EOF' > expected
-0 1
-1 3
-2 5
-3 7
-4 9
-EOF
-
-test_diff <<'EOF'
-int printf();
-
-int main() {
- for (int i = 0, j = 1; i < 5; i++, j += 2) {
- printf("%d %d\n", i, j);
- }
-}
-EOF
diff --git a/tests/functions.c b/tests/functions.c
index eef9496..6e4622c 100644
--- a/tests/functions.c
+++ b/tests/functions.c
@@ -1,4 +1,5 @@
#include <helpers.h>
+#include <stdarg.h>
int sprintf(char*, const char*, ...);
@@ -99,6 +100,17 @@ int f10() {
return 12345;
}
+int sum(int n, ...) {
+ va_list args;
+ va_start(args, n);
+ int s = 0;
+ for (int i = 0; i < n; ++i) {
+ s += va_arg(args, int);
+ }
+ va_end(args);
+ return s;
+}
+
// recursive functions
int fib(int n) {
if (n <= 1) {
@@ -154,6 +166,8 @@ int main() {
int (*fp4)(int, int, int, int, int, int, int, int, int, int, int) = f7;
ASSERT_EQ(7, fp4(6, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
+ ASSERT_EQ(400, sum(5, 100, 90, 80, 70, 60));
+
// recursive functions
ASSERT_EQ(89, fib(10));
}
diff --git a/tests/functions.sh b/tests/functions.sh
index ddae9b2..e15c900 100644
--- a/tests/functions.sh
+++ b/tests/functions.sh
@@ -107,26 +107,6 @@ int main() {
}
EOF
-test_exit_code 0 <<'EOF'
-#include <stdarg.h>
-#include <helpers.h>
-
-int sum(int n, ...) {
- va_list args;
- va_start(args, n);
- int s = 0;
- for (int i = 0; i < n; ++i) {
- s += va_arg(args, int);
- }
- va_end(args);
- return s;
-}
-
-int main() {
- ASSERT_EQ(400, sum(5, 100, 90, 80, 70, 60));
-}
-EOF
-
# implicit return
# C99: 5.1.2.2.3
test_exit_code 0 <<'EOF'
diff --git a/tests/pointers.c b/tests/pointers.c
new file mode 100644
index 0000000..8fd1d9c
--- /dev/null
+++ b/tests/pointers.c
@@ -0,0 +1,134 @@
+#include <helpers.h>
+
+void* calloc(long, long);
+
+int glob_a;
+int glob_b[12];
+
+int main() {
+ int a1;
+ int* a2;
+ char a3;
+ char* a4;
+ long a5;
+ long* a6;
+ void* a8;
+ int** a10;
+ char** a12;
+ long** a14;
+ void** a16;
+ int*** a18;
+ char*** a20;
+ long*** a22;
+ void*** a24;
+ int* const* const* a25;
+
+ int x;
+ int* y;
+ y = &x;
+ *y = 42;
+ ASSERT_EQ(42, x);
+ ASSERT_EQ(42, *y);
+
+ char c;
+ int ii;
+ long l;
+ c = 42;
+ ii = 42 * 2;
+ l = 42 * 3;
+
+ char* cp1;
+ char* cp2;
+ int* ip1;
+ int* ip2;
+ long* lp1;
+ long* lp2;
+
+ cp1 = &c;
+ cp2 = &c + 3;
+
+ ip1 = &ii;
+ ip2 = &ii + 3;
+
+ lp1 = &l;
+ lp2 = &l + 3;
+
+ ASSERT_EQ(3, cp2 - cp1);
+ ASSERT_EQ(3, ip2 - ip1);
+ ASSERT_EQ(3, lp2 - lp1);
+
+ int b;
+ int* a = &b;
+ a[0] = 42;
+ ASSERT_EQ(42, *a);
+
+ long* arr = calloc(10, sizeof(long));
+ long i = 0;
+ for (i = 0; i < 10; i = i + 1) {
+ arr[i] = i;
+ }
+ for (i = 0; i < 10; i = i + 1) {
+ ASSERT_EQ(i, *(arr + i));
+ ASSERT_EQ(i, arr[i]);
+ }
+
+ char* source = calloc(4, sizeof(char));
+ source[0] = 'A';
+ source[1] = 'B';
+ source[2] = 'C';
+ source[3] = 'D';
+
+ int ca = source[0];
+ ASSERT_EQ(65, ca);
+ ASSERT_EQ(65, source[0]);
+ ASSERT_EQ(66, source[1]);
+ ASSERT_EQ(67, source[2]);
+ ASSERT_EQ(68, source[3]);
+
+ int sa[10];
+ for (int j = 0; j < 10; ++j) {
+ sa[j] = j * j;
+ }
+ for (int j = 0; j < 10; ++j) {
+ ASSERT_EQ(j * j, sa[j]);
+ }
+
+ ASSERT_EQ(0, glob_a);
+ glob_a = 42;
+ ASSERT_EQ(42, glob_a);
+ ASSERT_EQ(48, sizeof(glob_b));
+ for (int j = 0; j < 12; ++j) {
+ ASSERT_EQ(0, glob_b[j]);
+ }
+ glob_b[11] = 123;
+ ASSERT_EQ(123, glob_b[11]);
+
+ int arr_a[10 * 10];
+ int arr_b[10 + 10];
+ int arr_c[1 << 2];
+ ASSERT_EQ(400, sizeof(arr_a));
+ ASSERT_EQ(80, sizeof(arr_b));
+ ASSERT_EQ(16, sizeof(arr_c));
+
+ "";
+ "abc";
+ "\"foo\"bar\\\n\"";
+
+ ASSERT_EQ_STR("defghijkl", "def" "ghi"
+ "jkl");
+
+ char* h = " hello,world" + 1;
+ ASSERT_EQ('h', *h);
+ ASSERT_EQ('l', h[2]);
+ ASSERT_EQ(',', *(h + 5));
+
+ char* s = "hi";
+ int results[3];
+ int count = 0;
+ while (*s++) {
+ results[count++] = *s;
+ }
+ ASSERT_EQ(2, count);
+ ASSERT_EQ(105, results[0]);
+ ASSERT_EQ(0, results[1]);
+}
diff --git a/tests/pointers.sh b/tests/pointers.sh
deleted file mode 100644
index bbd4ed4..0000000
--- a/tests/pointers.sh
+++ /dev/null
@@ -1,317 +0,0 @@
-# pointer basics
-cat <<'EOF' > expected
-EOF
-test_diff <<'EOF'
-int main() {
- int a1;
- int* a2;
- char a3;
- char* a4;
- long a5;
- long* a6;
- void* a8;
- int** a10;
- char** a12;
- long** a14;
- void** a16;
- int*** a18;
- char*** a20;
- long*** a22;
- void*** a24;
- int* const* const* a25;
- return 0;
-}
-EOF
-
-cat <<'EOF' > expected
-42 42
-EOF
-test_diff <<'EOF'
-int printf();
-
-int main() {
- int x;
- int* y;
- y = &x;
- *y = 42;
- printf("%d %d\n", x, *y);
- return 0;
-}
-EOF
-
-cat <<'EOF' > expected
-3
-3
-3
-EOF
-test_diff <<'EOF'
-int printf();
-
-int main() {
- char c;
- int i;
- long l;
- c = 42;
- i = 42*2;
- l = 42*3;
-
- char* cp1;
- char* cp2;
- int* ip1;
- int* ip2;
- long* lp1;
- long* lp2;
-
- cp1 = &c;
- cp2 = &c + 3;
-
- ip1 = &i;
- ip2 = &i + 3;
-
- lp1 = &l;
- lp2 = &l + 3;
-
- printf("%d\n", cp2 - cp1);
- printf("%d\n", ip2 - ip1);
- printf("%d\n", lp2 - lp1);
-
- return 0;
-}
-EOF
-
-# arrays
-cat <<'EOF' > expected
-42
-EOF
-test_diff <<'EOF'
-int printf();
-void* calloc();
-
-int main() {
- int b;
- int* a = &b;
- a[0] = 42;
- printf("%d\n", *a);
- return 0;
-}
-EOF
-
-cat <<'EOF' > expected
-0 0
-1 1
-2 2
-3 3
-4 4
-5 5
-6 6
-7 7
-8 8
-9 9
-EOF
-test_diff <<'EOF'
-int printf();
-void* calloc();
-
-int main() {
- long* a = calloc(10, sizeof(long));
- long i = 0;
- for (i = 0; i < 10; i = i + 1) {
- a[i] = i;
- }
- for (i = 0; i < 10; i = i + 1) {
- printf("%d %d\n", *(a + i), a[i]);
- }
- return 0;
-}
-EOF
-
-cat <<'EOF' > expected
-65
-65
-66
-67
-68
-EOF
-test_diff <<'EOF'
-void* calloc();
-int printf();
-
-int main() {
- char* source = calloc(4, sizeof(char));
-
- source[0] = 'A';
- source[1] = 'B';
- source[2] = 'C';
- source[3] = 'D';
-
- int a = source[0];
-
- printf("%d\n", a);
- printf("%d\n", source[0]);
- printf("%d\n", source[1]);
- printf("%d\n", source[2]);
- printf("%d\n", source[3]);
-
- return 0;
-}
-EOF
-
-cat <<'EOF' > expected
-0
-1
-4
-9
-16
-25
-36
-49
-64
-81
-EOF
-
-test_diff <<'EOF'
-int printf();
-
-int main() {
- int i;
- int a[10];
- for (i = 0; i < 10; ++i) {
- a[i] = i * i;
- }
- for (i = 0; i < 10; ++i) {
- printf("%d\n", a[i]);
- }
-}
-EOF
-
-cat <<'EOF' > expected
-0
-42
-48
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-123
-EOF
-
-test_diff <<'EOF'
-int printf();
-
-int a;
-int b[12];
-
-int main() {
- printf("%d\n", a);
- a = 42;
- printf("%d\n", a);
- printf("%zu\n", sizeof(b));
- int i;
- for (i = 0; i < 12; ++i) {
- printf("%d\n", b[i]);
- }
- b[11] = 123;
- printf("%d\n", b[11]);
-}
-EOF
-
-cat <<'EOF' > expected
-400
-80
-16
-EOF
-
-test_diff <<'EOF'
-int printf();
-
-int main() {
- int a[10 * 10];
- int b[10 + 10];
- int c[1 << 2];
-
- printf("%zu\n", sizeof(a));
- printf("%zu\n", sizeof(b));
- printf("%zu\n", sizeof(c));
-}
-EOF
-
-# string operations
-> expected
-test_diff <<'EOF'
-int main() {
- "";
- return 0;
-}
-EOF
-
-> expected
-test_diff <<'EOF'
-int main() {
- "abc";
- return 0;
-}
-EOF
-
-> expected
-test_diff <<'EOF'
-int main() {
- "\"foo\"bar\\\n\"";
- return 0;
-}
-EOF
-
-cat <<'EOF' > expected
-abc
-defghijkl
-EOF
-
-test_diff <<'EOF'
-int printf();
-
-int main() {
- printf("abc\n");
- printf("def" "ghi"
- "jkl\n");
-}
-EOF
-
-cat <<'EOF' > expected
-h
-l
-,
-EOF
-
-test_diff <<'EOF'
-int printf();
-
-int main() {
- char* h = " hello,world" + 1;
- printf("%c\n", *h);
- printf("%c\n", h[2]);
- printf("%c\n", *(h + 5));
-}
-EOF
-
-cat <<'EOF' > expected
-105
-0
-EOF
-
-test_diff <<'EOF'
-int printf();
-
-int main() {
- char* s = "hi";
- while (*s++) {
- printf("%d\n", *s);
- }
-}
-EOF
diff --git a/tests/run.sh b/tests/run.sh
index 6b3bb00..7626424 100644
--- a/tests/run.sh
+++ b/tests/run.sh
@@ -2,29 +2,47 @@ set -e
export ducc="../../../build/$BIN"
-export testcase=$1
+arg=$1
+export testcase="${arg%.sh}"
+testcase="${testcase%.c}"
export tmp_dir="tests/tmp/$testcase"
-c_test_file="tests/$testcase.c"
-sh_test_file="tests/$testcase.sh"
+run_c=0
+run_sh=0
+if [[ "$arg" == *.c ]]; then
+ run_c=1
+elif [[ "$arg" == *.sh ]]; then
+ run_sh=1
+else
+ run_c=1
+ run_sh=1
+fi
-if [[ -f "$c_test_file" ]]; then
+found=0
+
+if [[ $run_c -eq 1 && -f "tests/$testcase.c" ]]; then
+ found=1
source tests/helpers.sh
- echo "$c_test_file"
+ echo "tests/$testcase.c"
mkdir -p "$tmp_dir"
cd "$tmp_dir"
- test_exit_code 0 < "../../../$c_test_file"
+ test_exit_code 0 < "../../../tests/$testcase.c"
cd "../../.."
-elif [[ -f "$sh_test_file" ]]; then
+fi
+
+if [[ $run_sh -eq 1 && -f "tests/$testcase.sh" ]]; then
+ found=1
source tests/helpers.sh
- echo "$sh_test_file"
+ echo "tests/$testcase.sh"
mkdir -p "$tmp_dir"
cd "$tmp_dir"
- source "../../../$sh_test_file"
+ source "../../../tests/$testcase.sh"
cd "../../.."
-else
+fi
+
+if [[ $found -eq 0 ]]; then
echo "no test $testcase" >&2
exit 1
fi
diff --git a/tests/structs.c b/tests/structs.c
new file mode 100644
index 0000000..734d501
--- /dev/null
+++ b/tests/structs.c
@@ -0,0 +1,241 @@
+#include <helpers.h>
+
+void* calloc(long, long);
+
+struct Token {
+ int kind;
+ char* value;
+};
+
+struct Define {
+ char* from;
+ struct Token* to;
+};
+
+struct AstNode0;
+
+struct Type0 {
+ int kind;
+ struct Type0* to;
+ struct AstNode0* members;
+};
+
+struct AstNode0 {
+ int kind;
+ struct AstNode0* next;
+ struct AstNode0* last;
+ char* name;
+ struct AstNode0* func_params;
+ struct AstNode0* func_body;
+ int int_value;
+ struct AstNode0* expr1;
+ struct AstNode0* expr2;
+ struct AstNode0* expr3;
+ int op;
+ struct Type0* ty;
+ int var_index;
+ struct AstNode0* node1;
+ struct AstNode0* node2;
+ char** str_literals;
+};
+
+struct LVar {
+ char* name;
+ struct Type0* ty;
+};
+
+struct Func0 {
+ char* name;
+ struct Type0* ty;
+};
+
+struct Parser {
+ struct Token* tokens;
+ int pos;
+ struct LVar* locals;
+ int n_locals;
+ struct Func0* funcs;
+ int n_funcs;
+ char** str_literals;
+ int n_str_literals;
+};
+
+struct CodeGen {
+ int next_label;
+ int* loop_labels;
+};
+
+struct S1 {
+ int a;
+ int b;
+};
+
+struct T1;
+
+struct S2 {
+ struct T1* a;
+};
+
+struct T1 {
+ int b;
+};
+
+struct S3 {
+ int a, b;
+};
+
+struct T3 {
+ short *a, b, c[12];
+};
+
+struct S4 {
+ int a[5];
+};
+
+struct S5 {
+ int a;
+ int b;
+};
+
+struct S6 {
+ long a;
+ long b;
+};
+typedef struct S6 S6;
+
+struct S7 {
+ int x;
+};
+typedef struct S7 S7;
+
+struct S8_fwd;
+typedef struct S8_fwd S8_fwd;
+
+struct S9 {
+ int x;
+};
+
+struct S10 {
+ int x;
+};
+
+struct S11 {
+ int x;
+};
+
+struct S12 {
+ int x;
+};
+
+struct S8_fwd {
+ int x;
+};
+
+typedef struct {
+ int x;
+ int y;
+} AnonS;
+
+typedef union {
+ int a;
+ char b;
+} AnonU;
+
+typedef enum {
+ RED,
+ GREEN,
+ BLUE
+} AnonE;
+
+struct S_nested {
+ struct {
+ int x;
+ int y;
+ };
+ struct {
+ int z;
+ };
+};
+
+int main() {
+ struct S1* sp;
+ sp = calloc(1, sizeof(struct S1));
+ sp->a = 42;
+ ASSERT_EQ(42, sp->a);
+ (*sp).b = 123;
+ ASSERT_EQ(123, (*sp).b);
+
+ struct S2* s2 = calloc(1, sizeof(struct S2));
+ s2->a = calloc(1, sizeof(struct T1));
+ s2->a->b = 42;
+ ASSERT_EQ(42, s2->a->b);
+
+ ASSERT_EQ(8, sizeof(struct S3));
+ ASSERT_EQ(40, sizeof(struct T3));
+
+ struct S4 x;
+ x.a[0] = 10;
+ x.a[1] = 20;
+ x.a[2] = 30;
+ x.a[3] = 40;
+ x.a[4] = 50;
+ ASSERT_EQ(20, sizeof(struct S4));
+ ASSERT_EQ(10, x.a[0]);
+ ASSERT_EQ(20, x.a[1]);
+ ASSERT_EQ(30, x.a[2]);
+ ASSERT_EQ(40, x.a[3]);
+ ASSERT_EQ(50, x.a[4]);
+
+ struct S5* s5 = calloc(1, sizeof(struct S5));
+ s5->b = 1;
+ ASSERT_EQ(0, s5->a);
+ ASSERT_EQ(1, s5->b);
+
+ struct S1* sc1 = calloc(1, sizeof(struct S1));
+ struct S1* sc2 = calloc(1, sizeof(struct S1));
+ sc1->a = 123;
+ sc1->b = 456;
+ ASSERT_EQ(123, sc1->a);
+ ASSERT_EQ(456, sc1->b);
+ ASSERT_EQ(0, sc2->a);
+ ASSERT_EQ(0, sc2->b);
+ *sc2 = *sc1;
+ ASSERT_EQ(123, sc2->a);
+ ASSERT_EQ(456, sc2->b);
+
+ S6* sl1 = calloc(1, sizeof(S6));
+ S6* sl2 = calloc(1, sizeof(S6));
+ sl1->a = 123;
+ sl1->b = 456;
+ ASSERT_EQ(123, sl1->a);
+ ASSERT_EQ(456, sl1->b);
+ ASSERT_EQ(0, sl2->a);
+ ASSERT_EQ(0, sl2->b);
+ *sl2 = *sl1;
+ ASSERT_EQ(123, sl2->a);
+ ASSERT_EQ(456, sl2->b);
+
+ S6 sv1;
+ S6 sv2;
+ sv1.a = 123;
+ sv1.b = 456;
+ sv2.a = 0;
+ sv2.b = 0;
+ ASSERT_EQ(123, sv1.a);
+ ASSERT_EQ(456, sv1.b);
+ ASSERT_EQ(0, sv2.a);
+ ASSERT_EQ(0, sv2.b);
+ sv2 = sv1;
+ ASSERT_EQ(123, sv2.a);
+ ASSERT_EQ(456, sv2.b);
+
+ S7* s7 = calloc(1, sizeof(S7));
+ s7->x = 42;
+ ASSERT_EQ(42, s7->x);
+
+ ASSERT_EQ(4, sizeof(S8_fwd));
+
+ ASSERT_EQ(8, sizeof(AnonS));
+ ASSERT_EQ(4, sizeof(AnonU));
+ ASSERT_EQ(4, sizeof(AnonE));
+}
diff --git a/tests/structs.sh b/tests/structs.sh
deleted file mode 100644
index 3df4f9c..0000000
--- a/tests/structs.sh
+++ /dev/null
@@ -1,389 +0,0 @@
-cat <<'EOF' > expected
-EOF
-test_diff <<'EOF'
-struct Token {
- int kind;
- char* value;
-};
-
-struct Define {
- char* from;
- struct Token* to;
-};
-
-struct AstNode;
-
-struct Type {
- int kind;
- struct Type* to;
- struct AstNode* members;
-};
-
-struct AstNode {
- int kind;
- struct AstNode* next;
- struct AstNode* last;
- char* name;
- struct AstNode* func_params;
- struct AstNode* func_body;
- int int_value;
- struct AstNode* expr1;
- struct AstNode* expr2;
- struct AstNode* expr3;
- int op;
- struct Type* ty;
- int var_index;
- struct AstNode* node1;
- struct AstNode* node2;
- char** str_literals;
-};
-
-struct LVar {
- char* name;
- struct Type* ty;
-};
-
-struct Func {
- char* name;
- struct Type* ty;
-};
-
-struct Parser {
- struct Token* tokens;
- int pos;
- struct LVar* locals;
- int n_locals;
- struct Func* funcs;
- int n_funcs;
- char** str_literals;
- int n_str_literals;
-};
-
-struct CodeGen {
- int next_label;
- int* loop_labels;
-};
-
-int main() {
- return 0;
-}
-EOF
-
-cat <<'EOF' > expected
-42
-123
-EOF
-test_diff <<'EOF'
-struct S {
- int a;
- int b;
-};
-
-int printf();
-void* calloc();
-
-int main() {
- struct S* sp;
- sp = calloc(1, sizeof(struct S));
- sp->a = 42;
- printf("%d\n", sp->a);
- (*sp).b = 123;
- printf("%d\n", (*sp).b);
- return 0;
-}
-EOF
-
-cat <<'EOF' > expected
-42
-EOF
-test_diff <<'EOF'
-void* calloc();
-int printf();
-
-struct T;
-
-struct S {
- struct T* a;
-};
-
-struct T {
- int b;
-};
-
-int main() {
- struct S* s = calloc(1, sizeof(struct S));
- s->a = calloc(1, sizeof(struct T));
- s->a->b = 42;
- printf("%d\n", s->a->b);
- return 0;
-}
-EOF
-
-test_exit_code 0 <<'EOF'
-#include <helpers.h>
-
-struct S {
- int a, b;
-};
-
-struct T {
- short *a, b, c[12];
-};
-
-int main() {
- ASSERT_EQ(8, sizeof(struct S));
- ASSERT_EQ(40, sizeof(struct T));
-}
-EOF
-
-cat <<'EOF' > expected
-20
-10
-20
-30
-40
-50
-EOF
-
-test_diff <<'EOF'
-int printf();
-
-struct S {
- int a[5];
-};
-
-int main() {
- struct S x;
- x.a[0] = 10;
- x.a[1] = 20;
- x.a[2] = 30;
- x.a[3] = 40;
- x.a[4] = 50;
-
- printf("%zu\n", sizeof(struct S));
-
- printf("%d\n", x.a[0]);
- printf("%d\n", x.a[1]);
- printf("%d\n", x.a[2]);
- printf("%d\n", x.a[3]);
- printf("%d\n", x.a[4]);
-}
-EOF
-
-cat <<'EOF' > expected
-0
-1
-EOF
-test_diff <<'EOF'
-int printf();
-void* calloc();
-
-struct S {
- int a;
- int b;
-};
-
-int main() {
- struct S* s = calloc(1, sizeof(struct S));
- s->b = 1;
- printf("%ld\n", s->a);
- printf("%ld\n", s->b);
- return 0;
-}
-EOF
-
-cat <<'EOF' > expected
-123 456
-0 0
-123 456
-EOF
-
-test_diff <<'EOF'
-struct S {
- int a;
- int b;
-};
-typedef struct S S;
-
-void* calloc();
-int printf();
-
-int main() {
- S* s1 = calloc(1, sizeof(S));
- S* s2 = calloc(1, sizeof(S));
- s1->a = 123;
- s1->b = 456;
- printf("%d %d\n", s1->a, s1->b);
- printf("%d %d\n", s2->a, s2->b);
- *s2 = *s1;
- printf("%d %d\n", s2->a, s2->b);
-}
-EOF
-
-cat <<'EOF' > expected
-123 456
-0 0
-123 456
-EOF
-
-test_diff <<'EOF'
-struct S {
- long a;
- long b;
-};
-typedef struct S S;
-
-void* calloc();
-int printf();
-
-int main() {
- S* s1 = calloc(1, sizeof(S));
- S* s2 = calloc(1, sizeof(S));
- s1->a = 123;
- s1->b = 456;
- printf("%d %d\n", s1->a, s1->b);
- printf("%d %d\n", s2->a, s2->b);
- *s2 = *s1;
- printf("%d %d\n", s2->a, s2->b);
-}
-EOF
-
-cat <<'EOF' > expected
-123 456
-0 0
-123 456
-EOF
-
-test_diff <<'EOF'
-struct S {
- long a;
- long b;
-};
-typedef struct S S;
-
-void* calloc();
-int printf();
-
-int main() {
- S s1;
- S s2;
- s1.a = 123;
- s1.b = 456;
- s2.a = 0;
- s2.b = 0;
- printf("%d %d\n", s1.a, s1.b);
- printf("%d %d\n", s2.a, s2.b);
- s2 = s1;
- printf("%d %d\n", s2.a, s2.b);
-}
-EOF
-
-cat <<'EOF' > expected
-42
-EOF
-test_diff <<'EOF'
-void* calloc();
-int printf();
-
-struct S {
- int x;
-};
-typedef struct S S;
-
-int main() {
- S* s = calloc(1, sizeof(S));
- s->x = 42;
- printf("%d\n", s->x);
- return 0;
-}
-EOF
-
-cat <<'EOF' > expected
-4
-EOF
-test_diff <<'EOF'
-struct S0;
-typedef struct S0 S0;
-
-struct S1 {
- int x;
-};
-
-struct S2 {
- int x;
-};
-
-struct S3 {
- int x;
-};
-
-struct S4 {
- int x;
-};
-
-struct S0 {
- int x;
-};
-
-int printf(const char*, ...);
-int main() {
- printf("%zu\n", sizeof(S0));
-}
-EOF
-
-cat <<'EOF' > expected
-8
-4
-4
-EOF
-
-test_diff <<'EOF'
-int printf();
-
-typedef struct {
- int x;
- int y;
-} S;
-
-typedef union {
- int a;
- char b;
-} U;
-
-typedef enum {
- RED,
- GREEN,
- BLUE
-} E;
-
-int main() {
- printf("%zu\n", sizeof(S));
- printf("%zu\n", sizeof(U));
- printf("%zu\n", sizeof(E));
-}
-EOF
-
-cat <<'EOF' > expected
-EOF
-
-test_diff <<'EOF'
-int printf();
-
-struct S1 {
- struct {
- int x;
- int y;
- };
- struct {
- int z;
- };
-};
-
-int main() {
- // TODO
- // struct S1 a = {1, 2, 3};
- // printf("%d\n", a.x);
- // printf("%d\n", a.y);
- // printf("%d\n", a.z);
-}
-EOF
diff --git a/tests/switch.c b/tests/switch.c
new file mode 100644
index 0000000..18368b2
--- /dev/null
+++ b/tests/switch.c
@@ -0,0 +1,148 @@
+#include <helpers.h>
+
+int switch_fallthrough(int x) {
+ switch (x) {
+ case 1:
+ case 2:
+ return 12;
+ case 3:
+ case 4:
+ return 34;
+ }
+ return 0;
+}
+
+int main() {
+ int x = 2;
+ int result = 0;
+
+ switch (x) {
+ case 1:
+ result = 10;
+ break;
+ case 2:
+ result = 20;
+ break;
+ case 3:
+ result = 30;
+ break;
+ }
+ ASSERT_EQ(20, result);
+
+ x = 5;
+ result = 0;
+ switch (x) {
+ case 1:
+ result = 10;
+ break;
+ case 2:
+ result = 20;
+ break;
+ default:
+ result = 99;
+ break;
+ }
+ ASSERT_EQ(99, result);
+
+ x = 2;
+ result = 0;
+ switch (x) {
+ case 1:
+ result = result + 10;
+ case 2:
+ result = result + 20;
+ case 3:
+ result = result + 30;
+ break;
+ }
+ ASSERT_EQ(50, result);
+
+ x = 1;
+ int y = 2;
+ result = 0;
+ switch (x) {
+ case 1:
+ switch (y) {
+ case 1:
+ result = 11;
+ break;
+ case 2:
+ result = 12;
+ break;
+ }
+ break;
+ case 2:
+ result = 20;
+ break;
+ }
+ ASSERT_EQ(12, result);
+
+ int a = 3;
+ int b = 2;
+ result = 0;
+ switch (a + b) {
+ case 4:
+ result = 40;
+ break;
+ case 5:
+ result = 50;
+ break;
+ case 6:
+ result = 60;
+ break;
+ }
+ ASSERT_EQ(50, result);
+
+ x = 2;
+ result = 0;
+ int temp = 0;
+ switch (x) {
+ case 1:
+ temp = 5;
+ result = temp * 2;
+ break;
+ case 2:
+ temp = 10;
+ result = temp * 2;
+ break;
+ case 3:
+ temp = 15;
+ result = temp * 2;
+ break;
+ }
+ ASSERT_EQ(20, result);
+ ASSERT_EQ(10, temp);
+
+ x = 1;
+ result = 0;
+ switch (x) {
+ case 1: {
+ int local = 100;
+ result = local;
+ break;
+ }
+ case 2: {
+ int local = 200;
+ result = local;
+ break;
+ }
+ }
+ ASSERT_EQ(100, result);
+
+ x = 10;
+ result = 42;
+ switch (x) {
+ case 1:
+ result = 10;
+ break;
+ case 2:
+ result = 20;
+ break;
+ }
+ ASSERT_EQ(42, result);
+
+ ASSERT_EQ(12, switch_fallthrough(1));
+ ASSERT_EQ(12, switch_fallthrough(2));
+ ASSERT_EQ(34, switch_fallthrough(3));
+ ASSERT_EQ(34, switch_fallthrough(4));
+}
diff --git a/tests/switch.sh b/tests/switch.sh
index 7d9f894..0207aa6 100644
--- a/tests/switch.sh
+++ b/tests/switch.sh
@@ -1,196 +1,3 @@
-#!/bin/bash
-
-test_exit_code 0 <<'EOF'
-#include <helpers.h>
-
-int main() {
- int x = 2;
- int result = 0;
-
- switch (x) {
- case 1:
- result = 10;
- break;
- case 2:
- result = 20;
- break;
- case 3:
- result = 30;
- break;
- }
-
- ASSERT_EQ(20, result);
-}
-EOF
-
-test_exit_code 0 <<'EOF'
-#include <helpers.h>
-
-int main() {
- int x = 5;
- int result = 0;
-
- switch (x) {
- case 1:
- result = 10;
- break;
- case 2:
- result = 20;
- break;
- default:
- result = 99;
- break;
- }
-
- ASSERT_EQ(99, result);
-}
-EOF
-
-test_exit_code 0 <<'EOF'
-#include <helpers.h>
-
-int main() {
- int x = 2;
- int result = 0;
-
- switch (x) {
- case 1:
- result = result + 10;
- case 2:
- result = result + 20;
- case 3:
- result = result + 30;
- break;
- }
-
- ASSERT_EQ(50, result); // 20 + 30 due to fall-through
-}
-EOF
-
-test_exit_code 0 <<'EOF'
-#include <helpers.h>
-
-int main() {
- int x = 1;
- int y = 2;
- int result = 0;
-
- switch (x) {
- case 1:
- switch (y) {
- case 1:
- result = 11;
- break;
- case 2:
- result = 12;
- break;
- }
- break;
- case 2:
- result = 20;
- break;
- }
-
- ASSERT_EQ(12, result);
-}
-EOF
-
-test_exit_code 0 <<'EOF'
-#include <helpers.h>
-
-int main() {
- int a = 3;
- int b = 2;
- int result = 0;
-
- switch (a + b) {
- case 4:
- result = 40;
- break;
- case 5:
- result = 50;
- break;
- case 6:
- result = 60;
- break;
- }
-
- ASSERT_EQ(50, result);
-}
-EOF
-
-test_exit_code 0 <<'EOF'
-#include <helpers.h>
-
-int main() {
- int x = 2;
- int result = 0;
- int temp = 0;
-
- switch (x) {
- case 1:
- temp = 5;
- result = temp * 2;
- break;
- case 2:
- temp = 10;
- result = temp * 2;
- break;
- case 3:
- temp = 15;
- result = temp * 2;
- break;
- }
-
- ASSERT_EQ(20, result);
- ASSERT_EQ(10, temp);
-}
-EOF
-
-test_exit_code 0 <<'EOF'
-#include <helpers.h>
-
-int main() {
- int x = 1;
- int result = 0;
-
- switch (x) {
- case 1: {
- int local = 100;
- result = local;
- break;
- }
- case 2: {
- int local = 200;
- result = local;
- break;
- }
- }
-
- ASSERT_EQ(100, result);
-}
-EOF
-
-test_exit_code 0 <<'EOF'
-#include <helpers.h>
-
-int main() {
- int x = 10;
- int result = 42;
-
- switch (x) {
- case 1:
- result = 10;
- break;
- case 2:
- result = 20;
- break;
- }
-
- ASSERT_EQ(42, result);
-}
-EOF
-
cat <<'EOF' > expected
main.c:2: 'case' label not within a switch statement
EOF
@@ -210,25 +17,3 @@ int main() {
return 0;
}
EOF
-
-test_exit_code 0 <<'EOF'
-#include <helpers.h>
-
-int f(int x) {
- switch (x) {
- case 1:
- case 2:
- return 12;
- case 3:
- case 4:
- return 34;
- }
-}
-
-int main() {
- ASSERT_EQ(12, f(1));
- ASSERT_EQ(12, f(2));
- ASSERT_EQ(34, f(3));
- ASSERT_EQ(34, f(4));
-}
-EOF
diff --git a/tests/types.c b/tests/types.c
new file mode 100644
index 0000000..7743489
--- /dev/null
+++ b/tests/types.c
@@ -0,0 +1,156 @@
+#include <helpers.h>
+#include <stdarg.h>
+
+struct Token {
+ int kind;
+ char* value;
+};
+
+struct Define {
+ char* from;
+ struct Token* to;
+};
+
+struct AstNode;
+
+struct Type {
+ int kind;
+ struct Type* to;
+ struct AstNode* members;
+};
+
+struct AstNode {
+ int kind;
+ struct AstNode* next;
+ struct AstNode* last;
+ char* name;
+ struct AstNode* func_params;
+ struct AstNode* func_body;
+ int int_value;
+ struct AstNode* expr1;
+ struct AstNode* expr2;
+ struct AstNode* expr3;
+ int op;
+ struct Type* ty;
+ int var_index;
+ struct AstNode* node1;
+ struct AstNode* node2;
+ char** str_literals;
+};
+
+struct LVar {
+ char* name;
+ struct Type* ty;
+};
+
+struct Func {
+ char* name;
+ struct Type* ty;
+};
+
+struct Parser {
+ struct Token* tokens;
+ int pos;
+ struct LVar* locals;
+ int n_locals;
+ struct Func* funcs;
+ int n_funcs;
+ char** str_literals;
+ int n_str_literals;
+};
+
+struct CodeGen {
+ int next_label;
+ int* loop_labels;
+};
+
+struct S_var {
+ long x;
+ long y;
+};
+
+enum E {
+ A,
+ B,
+ C,
+};
+
+enum E1 {
+ E1_A = 10,
+ E1_B,
+ E1_C = 20,
+ E1_D,
+};
+
+enum E2 {
+ E2_E,
+ E2_F = 5,
+ E2_G,
+ E2_H = E2_G,
+};
+
+int main() {
+ short a = 42;
+ ASSERT_EQ(2, sizeof(a));
+ ASSERT_EQ(42, a);
+ short* b = &a;
+ *b = 123;
+ ASSERT_EQ(8, sizeof(b));
+ ASSERT_EQ(123, *b);
+
+ ASSERT_EQ(4, sizeof(int));
+ ASSERT_EQ(8, sizeof(int*));
+ ASSERT_EQ(1, sizeof(char));
+ ASSERT_EQ(8, sizeof(char*));
+ ASSERT_EQ(8, sizeof(long));
+ ASSERT_EQ(8, sizeof(long*));
+ ASSERT_EQ(8, sizeof(void*));
+ ASSERT_EQ(8, sizeof(int**));
+ ASSERT_EQ(8, sizeof(char**));
+ ASSERT_EQ(8, sizeof(long**));
+ ASSERT_EQ(8, sizeof(void**));
+ ASSERT_EQ(8, sizeof(int***));
+ ASSERT_EQ(8, sizeof(char***));
+ ASSERT_EQ(8, sizeof(long***));
+ ASSERT_EQ(8, sizeof(void***));
+
+ ASSERT_EQ(16, sizeof(struct Token));
+ ASSERT_EQ(16, sizeof(struct Define));
+ ASSERT_EQ(24, sizeof(struct Type));
+ ASSERT_EQ(128, sizeof(struct AstNode));
+ ASSERT_EQ(16, sizeof(struct LVar));
+ ASSERT_EQ(16, sizeof(struct Func));
+ ASSERT_EQ(64, sizeof(struct Parser));
+ ASSERT_EQ(16, sizeof(struct CodeGen));
+
+ ASSERT_EQ(24, sizeof(va_list));
+
+ int va;
+ long vb;
+ char vc[123];
+ struct S_var vd;
+ void* ve;
+ struct S_var vf[123];
+
+ ASSERT_EQ(4, sizeof(va));
+ ASSERT_EQ(8, sizeof(vb));
+ ASSERT_EQ(123, sizeof(vc));
+ ASSERT_EQ(16, sizeof(vd));
+ ASSERT_EQ(8, sizeof(ve));
+ ASSERT_EQ(1968, sizeof(vf));
+
+ ASSERT_EQ(4, sizeof(enum E));
+ ASSERT_EQ(0, A);
+ ASSERT_EQ(1, B);
+ ASSERT_EQ(2, C);
+
+ ASSERT_EQ(10, E1_A);
+ ASSERT_EQ(11, E1_B);
+ ASSERT_EQ(20, E1_C);
+ ASSERT_EQ(21, E1_D);
+
+ ASSERT_EQ(0, E2_E);
+ ASSERT_EQ(5, E2_F);
+ ASSERT_EQ(6, E2_G);
+ ASSERT_EQ(6, E2_H);
+}
diff --git a/tests/types.sh b/tests/types.sh
deleted file mode 100644
index 892f85b..0000000
--- a/tests/types.sh
+++ /dev/null
@@ -1,245 +0,0 @@
-# short type
-cat <<'EOF' > expected
-2 42
-8 123
-EOF
-
-test_diff <<'EOF'
-int printf();
-
-int main() {
- short a = 42;
- printf("%zu %hd\n", sizeof(a), a);
- short* b = &a;
- *b = 123;
- printf("%zu %hd\n", sizeof(b), *b);
-}
-EOF
-
-# sizeof operator
-cat <<'EOF' > expected
-sizeof(int) = 4
-sizeof(int*) = 8
-sizeof(char) = 1
-sizeof(char*) = 8
-sizeof(long) = 8
-sizeof(long*) = 8
-sizeof(void*) = 8
-sizeof(int**) = 8
-sizeof(char**) = 8
-sizeof(long**) = 8
-sizeof(void**) = 8
-sizeof(int***) = 8
-sizeof(char***) = 8
-sizeof(long***) = 8
-sizeof(void***) = 8
-EOF
-test_diff <<'EOF'
-int printf();
-
-int main() {
- printf("sizeof(int) = %d\n", sizeof(int));
- printf("sizeof(int*) = %d\n", sizeof(int*));
- printf("sizeof(char) = %d\n", sizeof(char));
- printf("sizeof(char*) = %d\n", sizeof(char*));
- printf("sizeof(long) = %d\n", sizeof(long));
- printf("sizeof(long*) = %d\n", sizeof(long*));
- printf("sizeof(void*) = %d\n", sizeof(void*));
- printf("sizeof(int**) = %d\n", sizeof(int**));
- printf("sizeof(char**) = %d\n", sizeof(char**));
- printf("sizeof(long**) = %d\n", sizeof(long**));
- printf("sizeof(void**) = %d\n", sizeof(void**));
- printf("sizeof(int***) = %d\n", sizeof(int***));
- printf("sizeof(char***) = %d\n", sizeof(char***));
- printf("sizeof(long***) = %d\n", sizeof(long***));
- printf("sizeof(void***) = %d\n", sizeof(void***));
- return 0;
-}
-EOF
-
-cat <<'EOF' > expected
-sizeof(struct Token) = 16
-sizeof(struct Define) = 16
-sizeof(struct Type) = 24
-sizeof(struct AstNode) = 128
-sizeof(struct LVar) = 16
-sizeof(struct Func) = 16
-sizeof(struct Parser) = 64
-sizeof(struct CodeGen) = 16
-EOF
-test_diff <<'EOF'
-struct Token {
- int kind;
- char* value;
-};
-
-struct Define {
- char* from;
- struct Token* to;
-};
-
-struct AstNode;
-
-struct Type {
- int kind;
- struct Type* to;
- struct AstNode* members;
-};
-
-struct AstNode {
- int kind;
- struct AstNode* next;
- struct AstNode* last;
- char* name;
- struct AstNode* func_params;
- struct AstNode* func_body;
- int int_value;
- struct AstNode* expr1;
- struct AstNode* expr2;
- struct AstNode* expr3;
- int op;
- struct Type* ty;
- int var_index;
- struct AstNode* node1;
- struct AstNode* node2;
- char** str_literals;
-};
-
-struct LVar {
- char* name;
- struct Type* ty;
-};
-
-struct Func {
- char* name;
- struct Type* ty;
-};
-
-struct Parser {
- struct Token* tokens;
- int pos;
- struct LVar* locals;
- int n_locals;
- struct Func* funcs;
- int n_funcs;
- char** str_literals;
- int n_str_literals;
-};
-
-struct CodeGen {
- int next_label;
- int* loop_labels;
-};
-
-int printf();
-
-int main() {
- printf("sizeof(struct Token) = %d\n", sizeof(struct Token));
- printf("sizeof(struct Define) = %d\n", sizeof(struct Define));
- printf("sizeof(struct Type) = %d\n", sizeof(struct Type));
- printf("sizeof(struct AstNode) = %d\n", sizeof(struct AstNode));
- printf("sizeof(struct LVar) = %d\n", sizeof(struct LVar));
- printf("sizeof(struct Func) = %d\n", sizeof(struct Func));
- printf("sizeof(struct Parser) = %d\n", sizeof(struct Parser));
- printf("sizeof(struct CodeGen) = %d\n", sizeof(struct CodeGen));
- return 0;
-}
-EOF
-
-cat <<'EOF' > expected
-24
-EOF
-
-test_diff <<'EOF'
-#include <stdarg.h>
-
-int printf();
-
-int main() {
- printf("%d\n", sizeof(va_list));
-}
-EOF
-
-cat <<'EOF' > expected
-sizeof(a) = 4
-sizeof(b) = 8
-sizeof(c) = 123
-sizeof(d) = 16
-sizeof(e) = 8
-sizeof(f) = 1968
-EOF
-test_diff <<'EOF'
-int printf();
-
-struct S {
- long x;
- long y;
-};
-
-int main() {
- int a;
- long b;
- char c[123];
- struct S d;
- void* e;
- struct S f[123];
-
- printf("sizeof(a) = %d\n", sizeof(a));
- printf("sizeof(b) = %d\n", sizeof(b));
- printf("sizeof(c) = %d\n", sizeof(c));
- printf("sizeof(d) = %d\n", sizeof(d));
- printf("sizeof(e) = %d\n", sizeof(e));
- printf("sizeof(f) = %d\n", sizeof(f));
- return 0;
-}
-EOF
-
-# enums
-cat <<'EOF' > expected
-4
-0,1,2
-EOF
-test_diff <<'EOF'
-int printf();
-
-enum E {
- A,
- B,
- C,
-};
-
-int main() {
- enum E x = A;
- printf("%d\n", sizeof(enum E));
- printf("%d,%d,%d\n", A, B, C);
- return 0;
-}
-EOF
-
-cat <<'EOF' > expected
-10,11,20,21
-0,5,6,6
-EOF
-
-test_diff <<'EOF'
-int printf();
-
-enum E1 {
- A = 10,
- B,
- C = 20,
- D,
-};
-
-enum E2 {
- E,
- F = 5,
- G,
- H = G,
-};
-
-int main() {
- printf("%d,%d,%d,%d\n", A, B, C, D);
- printf("%d,%d,%d,%d\n", E, F, G, H);
-}
-EOF
diff --git a/tests/unions.c b/tests/unions.c
new file mode 100644
index 0000000..923a5b6
--- /dev/null
+++ b/tests/unions.c
@@ -0,0 +1,14 @@
+#include <helpers.h>
+
+union U {
+ int i;
+ long l;
+};
+
+int main() {
+ union U u;
+ ASSERT_EQ(8, sizeof(u));
+ u.l = 42;
+ ASSERT_EQ(42, u.i);
+ ASSERT_EQ(42, u.l);
+}
diff --git a/tests/unions.sh b/tests/unions.sh
deleted file mode 100644
index d1e87d6..0000000
--- a/tests/unions.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-cat <<'EOF' > expected
-8
-42
-42
-EOF
-
-test_diff <<'EOF'
-int printf();
-
-union U {
- int i;
- long l;
-};
-
-int main() {
- union U u;
- printf("%zu\n", sizeof(u));
- u.l = 42;
- printf("%d\n", u.i);
- printf("%ld\n", u.l);
-}
-EOF