aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2025-05-07 09:13:49 +0900
committernsfisis <nsfisis@gmail.com>2025-05-07 09:13:49 +0900
commit68d9da9746d235e2d9a7d0ba61310c533b355847 (patch)
tree573494cc000416a46c35d5bc5e0788f38a126b20 /tests
parent9c618db8b3f68356157596aea86e68b10e6a401a (diff)
downloadducc-68d9da9746d235e2d9a7d0ba61310c533b355847.tar.gz
ducc-68d9da9746d235e2d9a7d0ba61310c533b355847.tar.zst
ducc-68d9da9746d235e2d9a7d0ba61310c533b355847.zip
copy files from P4Dcc
Diffstat (limited to 'tests')
-rw-r--r--tests/001.sh5
-rw-r--r--tests/002.sh5
-rw-r--r--tests/003.sh5
-rw-r--r--tests/004.sh7
-rw-r--r--tests/005.sh7
-rw-r--r--tests/006.sh49
-rw-r--r--tests/007.sh9
-rw-r--r--tests/008.sh11
-rw-r--r--tests/009.sh37
-rw-r--r--tests/010.sh21
-rw-r--r--tests/011.sh14
-rw-r--r--tests/012.sh17
-rw-r--r--tests/013.sh17
-rw-r--r--tests/014.sh21
-rw-r--r--tests/015.sh61
-rw-r--r--tests/016.sh15
-rw-r--r--tests/017.sh7
-rw-r--r--tests/018.sh22
-rw-r--r--tests/019.sh28
-rw-r--r--tests/020.sh123
-rw-r--r--tests/021.sh24
-rw-r--r--tests/022.sh17
-rw-r--r--tests/023.sh41
-rw-r--r--tests/024.sh34
-rw-r--r--tests/025.sh17
-rw-r--r--tests/026.sh43
-rw-r--r--tests/027.sh72
-rw-r--r--tests/028.sh90
-rw-r--r--tests/029.sh25
-rw-r--r--tests/030.sh53
-rw-r--r--tests/031.sh14
-rw-r--r--tests/032.sh17
-rw-r--r--tests/033.sh46
-rw-r--r--tests/034.sh17
-rw-r--r--tests/035.sh17
-rw-r--r--tests/036.sh27
-rw-r--r--tests/037.sh18
-rw-r--r--tests/038.sh38
-rw-r--r--tests/039.sh32
-rw-r--r--tests/040.sh40
-rw-r--r--tests/041.sh32
-rw-r--r--tests/042.sh20
-rw-r--r--tests/043.sh17
-rw-r--r--tests/all.sh14
-rw-r--r--tests/run.sh18
-rw-r--r--tests/test_diff.sh20
-rw-r--r--tests/test_exit_code.sh17
-rw-r--r--tests/test_output.sh22
48 files changed, 1323 insertions, 0 deletions
diff --git a/tests/001.sh b/tests/001.sh
new file mode 100644
index 0000000..00e0aca
--- /dev/null
+++ b/tests/001.sh
@@ -0,0 +1,5 @@
+bash ../../test_exit_code.sh 42 <<'EOF'
+int main() {
+ return 42;
+}
+EOF
diff --git a/tests/002.sh b/tests/002.sh
new file mode 100644
index 0000000..ee54213
--- /dev/null
+++ b/tests/002.sh
@@ -0,0 +1,5 @@
+bash ../../test_exit_code.sh 21 <<'EOF'
+int main() {
+ return 5+20-4;
+}
+EOF
diff --git a/tests/003.sh b/tests/003.sh
new file mode 100644
index 0000000..4fa0b42
--- /dev/null
+++ b/tests/003.sh
@@ -0,0 +1,5 @@
+bash ../../test_exit_code.sh 26 <<'EOF'
+int main() {
+ return 2*3+4*5;
+}
+EOF
diff --git a/tests/004.sh b/tests/004.sh
new file mode 100644
index 0000000..b5ceb16
--- /dev/null
+++ b/tests/004.sh
@@ -0,0 +1,7 @@
+set -e
+
+bash ../../test_exit_code.sh 197 <<'EOF'
+int main() {
+ return (((3+5)/2) + (5*(9-6)) * (5+6*7)) % 256;
+}
+EOF
diff --git a/tests/005.sh b/tests/005.sh
new file mode 100644
index 0000000..1b4611a
--- /dev/null
+++ b/tests/005.sh
@@ -0,0 +1,7 @@
+set -e
+
+bash ../../test_exit_code.sh 30 <<'EOF'
+int main() {
+ return (-10 + 20 * -3) + 100;
+}
+EOF
diff --git a/tests/006.sh b/tests/006.sh
new file mode 100644
index 0000000..2ae85ec
--- /dev/null
+++ b/tests/006.sh
@@ -0,0 +1,49 @@
+set -e
+
+bash ../../test_exit_code.sh 1 <<'EOF'
+int main() {
+ return 0 == 0;
+}
+EOF
+
+bash ../../test_exit_code.sh 0 <<'EOF'
+int main() {
+ return 123 != 123;
+}
+EOF
+
+bash ../../test_exit_code.sh 1 <<'EOF'
+int main() {
+ return 123 != 456;
+}
+EOF
+
+bash ../../test_exit_code.sh 0 <<'EOF'
+int main() {
+ return 123 == 124;
+}
+EOF
+
+bash ../../test_exit_code.sh 1 <<'EOF'
+int main() {
+ return 123 < 567;
+}
+EOF
+
+bash ../../test_exit_code.sh 1 <<'EOF'
+int main() {
+ return 123 <= 567;
+}
+EOF
+
+bash ../../test_exit_code.sh 1 <<'EOF'
+int main() {
+ return 123 <= 123;
+}
+EOF
+
+bash ../../test_exit_code.sh 0 <<'EOF'
+int main() {
+ return 123 < 123;
+}
+EOF
diff --git a/tests/007.sh b/tests/007.sh
new file mode 100644
index 0000000..6f043b7
--- /dev/null
+++ b/tests/007.sh
@@ -0,0 +1,9 @@
+set -e
+
+bash ../../test_exit_code.sh 42 <<'EOF'
+int main() {
+ int foo;
+ foo = 42;
+ return foo;
+}
+EOF
diff --git a/tests/008.sh b/tests/008.sh
new file mode 100644
index 0000000..94936cd
--- /dev/null
+++ b/tests/008.sh
@@ -0,0 +1,11 @@
+set -e
+
+bash ../../test_exit_code.sh 70 <<'EOF'
+int main() {
+ int foo;
+ int bar;
+ foo = 42;
+ bar = 28;
+ return foo + bar;
+}
+EOF
diff --git a/tests/009.sh b/tests/009.sh
new file mode 100644
index 0000000..5ebcd0a
--- /dev/null
+++ b/tests/009.sh
@@ -0,0 +1,37 @@
+set -e
+
+bash ../../test_exit_code.sh 45 <<'EOF'
+int main() {
+ int a1;
+ int a2;
+ int a3;
+ int a4;
+ int a5;
+ int a6;
+ int a7;
+ int a8;
+ int a9;
+
+ a1 = 1;
+ a2 = 2;
+ a3 = 3;
+ a4 = 4;
+ a5 = 5;
+ a6 = 6;
+ a7 = 7;
+ a8 = 8;
+ a9 = 9;
+
+ return
+ a1 +
+ a2 +
+ a3 +
+ a4 +
+ a5 +
+ a6 +
+ a7 +
+ a8 +
+ a9 +
+ 0;
+}
+EOF
diff --git a/tests/010.sh b/tests/010.sh
new file mode 100644
index 0000000..df6601c
--- /dev/null
+++ b/tests/010.sh
@@ -0,0 +1,21 @@
+set -e
+
+bash ../../test_exit_code.sh 12 <<'EOF'
+int main() {
+ if (1) {
+ return 12;
+ } else {
+ return 34;
+ }
+}
+EOF
+
+bash ../../test_exit_code.sh 34 <<'EOF'
+int main() {
+ if (1 + 1 != 2) {
+ return 12;
+ } else {
+ return 34;
+ }
+}
+EOF
diff --git a/tests/011.sh b/tests/011.sh
new file mode 100644
index 0000000..f9ee216
--- /dev/null
+++ b/tests/011.sh
@@ -0,0 +1,14 @@
+set -e
+
+bash ../../test_exit_code.sh 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
diff --git a/tests/012.sh b/tests/012.sh
new file mode 100644
index 0000000..279e3c2
--- /dev/null
+++ b/tests/012.sh
@@ -0,0 +1,17 @@
+set -e
+
+bash ../../test_exit_code.sh 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
diff --git a/tests/013.sh b/tests/013.sh
new file mode 100644
index 0000000..8381d0e
--- /dev/null
+++ b/tests/013.sh
@@ -0,0 +1,17 @@
+set -e
+
+bash ../../test_exit_code.sh 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
diff --git a/tests/014.sh b/tests/014.sh
new file mode 100644
index 0000000..ba32d1f
--- /dev/null
+++ b/tests/014.sh
@@ -0,0 +1,21 @@
+set -e
+
+bash ../../test_exit_code.sh 66 <<'EOF'
+int foo() {
+ 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;
+}
+
+int main() {
+ return foo();
+}
+EOF
diff --git a/tests/015.sh b/tests/015.sh
new file mode 100644
index 0000000..6b084e8
--- /dev/null
+++ b/tests/015.sh
@@ -0,0 +1,61 @@
+set -e
+
+bash ../../test_exit_code.sh 10 <<'EOF'
+int f(int a, int b, int c, int d, int e, int f) {
+ return a;
+}
+
+int main() {
+ return 10 * f(1, 2, 3, 4, 5, 6);
+}
+EOF
+
+bash ../../test_exit_code.sh 20 <<'EOF'
+int f(int a, int b, int c, int d, int e, int f) {
+ return b;
+}
+
+int main() {
+ return 10 * f(1, 2, 3, 4, 5, 6);
+}
+EOF
+
+bash ../../test_exit_code.sh 30 <<'EOF'
+int f(int a, int b, int c, int d, int e, int f) {
+ return c;
+}
+
+int main() {
+ return 10 * f(1, 2, 3, 4, 5, 6);
+}
+EOF
+
+bash ../../test_exit_code.sh 40 <<'EOF'
+int f(int a, int b, int c, int d, int e, int f) {
+ return d;
+}
+
+int main() {
+ return 10 * f(1, 2, 3, 4, 5, 6);
+}
+EOF
+
+bash ../../test_exit_code.sh 50 <<'EOF'
+int f(int a, int b, int c, int d, int e, int f) {
+ return e;
+}
+
+int main() {
+ return 10 * f(1, 2, 3, 4, 5, 6);
+}
+EOF
+
+bash ../../test_exit_code.sh 60 <<'EOF'
+int f(int a, int b, int c, int d, int e, int f) {
+ return f;
+}
+
+int main() {
+ return 10 * f(1, 2, 3, 4, 5, 6);
+}
+EOF
diff --git a/tests/016.sh b/tests/016.sh
new file mode 100644
index 0000000..02d3357
--- /dev/null
+++ b/tests/016.sh
@@ -0,0 +1,15 @@
+set -e
+
+bash ../../test_exit_code.sh 89 <<'EOF'
+int fib(int n) {
+ if (n <= 1) {
+ return 1;
+ } else {
+ return fib(n - 1) + fib(n - 2);
+ }
+}
+
+int main() {
+ return fib(10);
+}
+EOF
diff --git a/tests/017.sh b/tests/017.sh
new file mode 100644
index 0000000..504f7d8
--- /dev/null
+++ b/tests/017.sh
@@ -0,0 +1,7 @@
+set -e
+
+bash ../../test_output.sh "" <<'EOF'
+int main() {
+ return 0;
+}
+EOF
diff --git a/tests/018.sh b/tests/018.sh
new file mode 100644
index 0000000..eb86a5e
--- /dev/null
+++ b/tests/018.sh
@@ -0,0 +1,22 @@
+set -e
+
+bash ../../test_output.sh "" <<'EOF'
+int main() {
+ "";
+ return 0;
+}
+EOF
+
+bash ../../test_output.sh "" <<'EOF'
+int main() {
+ "abc";
+ return 0;
+}
+EOF
+
+bash ../../test_output.sh "" <<'EOF'
+int main() {
+ "\"foo\"bar\\\n\"";
+ return 0;
+}
+EOF
diff --git a/tests/019.sh b/tests/019.sh
new file mode 100644
index 0000000..d31f154
--- /dev/null
+++ b/tests/019.sh
@@ -0,0 +1,28 @@
+set -e
+
+bash ../../test_output.sh "" <<'EOF'
+int printf();
+
+int main() {
+ printf("");
+ return 0;
+}
+EOF
+
+bash ../../test_output.sh "Hello, World!" <<'EOF'
+int printf();
+
+int main() {
+ printf("Hello, World!\n");
+ return 0;
+}
+EOF
+
+bash ../../test_output.sh '"Hello, World!"' <<'EOF'
+int printf();
+
+int main() {
+ printf("\"Hello, World!\"\n");
+ return 0;
+}
+EOF
diff --git a/tests/020.sh b/tests/020.sh
new file mode 100644
index 0000000..146f725
--- /dev/null
+++ b/tests/020.sh
@@ -0,0 +1,123 @@
+set -e
+
+cat <<'EOF' > expected
+1
+2
+Fizz
+4
+Buzz
+Fizz
+7
+8
+Fizz
+Buzz
+11
+Fizz
+13
+14
+FizzBuzz
+16
+17
+Fizz
+19
+Buzz
+Fizz
+22
+23
+Fizz
+Buzz
+26
+Fizz
+28
+29
+FizzBuzz
+31
+32
+Fizz
+34
+Buzz
+Fizz
+37
+38
+Fizz
+Buzz
+41
+Fizz
+43
+44
+FizzBuzz
+46
+47
+Fizz
+49
+Buzz
+Fizz
+52
+53
+Fizz
+Buzz
+56
+Fizz
+58
+59
+FizzBuzz
+61
+62
+Fizz
+64
+Buzz
+Fizz
+67
+68
+Fizz
+Buzz
+71
+Fizz
+73
+74
+FizzBuzz
+76
+77
+Fizz
+79
+Buzz
+Fizz
+82
+83
+Fizz
+Buzz
+86
+Fizz
+88
+89
+FizzBuzz
+91
+92
+Fizz
+94
+Buzz
+Fizz
+97
+98
+Fizz
+Buzz
+EOF
+bash ../../test_diff.sh <<'EOF'
+int printf();
+
+int main() {
+ int i;
+ for (i = 1; i <= 100; i = i + 1) {
+ if (i % 15 == 0) {
+ printf("FizzBuzz\n");
+ } else if (i % 3 == 0) {
+ printf("Fizz\n");
+ } else if (i % 5 == 0) {
+ printf("Buzz\n");
+ } else {
+ printf("%d\n", i);
+ }
+ }
+ return 0;
+}
+EOF
diff --git a/tests/021.sh b/tests/021.sh
new file mode 100644
index 0000000..2f225e1
--- /dev/null
+++ b/tests/021.sh
@@ -0,0 +1,24 @@
+set -e
+
+cat <<'EOF' > expected
+EOF
+bash ../../test_diff.sh <<'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;
+ return 0;
+}
+EOF
diff --git a/tests/022.sh b/tests/022.sh
new file mode 100644
index 0000000..e5749f2
--- /dev/null
+++ b/tests/022.sh
@@ -0,0 +1,17 @@
+set -e
+
+cat <<'EOF' > expected
+42 42
+EOF
+bash ../../test_diff.sh <<'EOF'
+int printf();
+
+int main() {
+ int x;
+ int* y;
+ y = &x;
+ *y = 42;
+ printf("%d %d\n", x, *y);
+ return 0;
+}
+EOF
diff --git a/tests/023.sh b/tests/023.sh
new file mode 100644
index 0000000..cb77c22
--- /dev/null
+++ b/tests/023.sh
@@ -0,0 +1,41 @@
+set -e
+
+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
+bash ../../test_diff.sh <<'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
diff --git a/tests/024.sh b/tests/024.sh
new file mode 100644
index 0000000..99557e1
--- /dev/null
+++ b/tests/024.sh
@@ -0,0 +1,34 @@
+set -e
+
+cat <<'EOF' > expected
+EOF
+bash ../../test_diff.sh <<'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;
+
+ return 0;
+}
+EOF
diff --git a/tests/025.sh b/tests/025.sh
new file mode 100644
index 0000000..1f673a1
--- /dev/null
+++ b/tests/025.sh
@@ -0,0 +1,17 @@
+set -e
+
+cat <<'EOF' > expected
+123
+EOF
+bash ../../test_diff.sh <<'EOF'
+int printf();
+
+void foo_bar(int hoge_piyo) {
+ printf("%d\n", hoge_piyo);
+}
+
+int main() {
+ foo_bar(123);
+ return 0;
+}
+EOF
diff --git a/tests/026.sh b/tests/026.sh
new file mode 100644
index 0000000..cd4500e
--- /dev/null
+++ b/tests/026.sh
@@ -0,0 +1,43 @@
+set -e
+
+cat <<'EOF' > expected
+EOF
+bash ../../test_diff.sh <<'EOF'
+#define A 1
+int main() {
+ return 0;
+}
+EOF
+
+cat <<'EOF' > expected
+1,2,3
+EOF
+bash ../../test_diff.sh <<'EOF'
+int printf();
+
+#define A 1
+#define B 2
+#define C 3
+
+int main() {
+ printf("%d,%d,%d\n", A, B, C);
+ return 0;
+}
+EOF
+
+cat <<'EOF' > expected
+0,0,0,0
+EOF
+bash ../../test_diff.sh <<'EOF'
+int printf();
+
+#define NULL 0
+#define TK_EOF 0
+#define TY_UNKNOWN 0
+#define AST_UNKNOWN 0
+
+int main() {
+ printf("%d,%d,%d,%d\n", NULL, TK_EOF, TY_UNKNOWN, AST_UNKNOWN);
+ return 0;
+}
+EOF
diff --git a/tests/027.sh b/tests/027.sh
new file mode 100644
index 0000000..ee10aa3
--- /dev/null
+++ b/tests/027.sh
@@ -0,0 +1,72 @@
+set -e
+
+cat <<'EOF' > expected
+EOF
+bash ../../test_diff.sh <<'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
diff --git a/tests/028.sh b/tests/028.sh
new file mode 100644
index 0000000..f5f7a6d
--- /dev/null
+++ b/tests/028.sh
@@ -0,0 +1,90 @@
+set -e
+
+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
+bash ../../test_diff.sh <<'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
diff --git a/tests/029.sh b/tests/029.sh
new file mode 100644
index 0000000..7904c17
--- /dev/null
+++ b/tests/029.sh
@@ -0,0 +1,25 @@
+set -e
+
+cat <<'EOF' > expected
+42
+123
+EOF
+bash ../../test_diff.sh <<'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
diff --git a/tests/030.sh b/tests/030.sh
new file mode 100644
index 0000000..e444938
--- /dev/null
+++ b/tests/030.sh
@@ -0,0 +1,53 @@
+set -e
+
+cat <<'EOF' > expected
+foo
+EOF
+bash ../../test_diff.sh <<'EOF'
+int printf();
+
+int foo() {
+ printf("foo\n");
+ return 0;
+}
+
+int bar() {
+ printf("bar\n");
+ return 1;
+}
+
+int main() {
+ if (foo() && bar()) {
+ printf("baz\n");
+ }
+
+ return 0;
+}
+EOF
+
+cat <<'EOF' > expected
+foo
+bar
+baz
+EOF
+bash ../../test_diff.sh <<'EOF'
+int printf();
+
+int foo() {
+ printf("foo\n");
+ return 0;
+}
+
+int bar() {
+ printf("bar\n");
+ return 1;
+}
+
+int main() {
+ if (foo() || bar()) {
+ printf("baz\n");
+ }
+
+ return 0;
+}
+EOF
diff --git a/tests/031.sh b/tests/031.sh
new file mode 100644
index 0000000..7747f84
--- /dev/null
+++ b/tests/031.sh
@@ -0,0 +1,14 @@
+set -e
+
+cat <<'EOF' > expected
+42
+EOF
+bash ../../test_diff.sh <<'EOF'
+int printf();
+
+int main() {
+ int a = 42;
+ printf("%d\n", a);
+ return 0;
+}
+EOF
diff --git a/tests/032.sh b/tests/032.sh
new file mode 100644
index 0000000..5e55b2a
--- /dev/null
+++ b/tests/032.sh
@@ -0,0 +1,17 @@
+set -e
+
+cat <<'EOF' > expected
+97 48
+92 39
+10
+EOF
+bash ../../test_diff.sh <<'EOF'
+int printf();
+
+int main() {
+ printf("%d %d\n", 'a', '0');
+ printf("%d %d\n", '\\', '\'');
+ printf("%d\n", '\n');
+ return 0;
+}
+EOF
diff --git a/tests/033.sh b/tests/033.sh
new file mode 100644
index 0000000..1fb92ac
--- /dev/null
+++ b/tests/033.sh
@@ -0,0 +1,46 @@
+set -e
+
+cat <<'EOF' > expected
+42
+EOF
+bash ../../test_diff.sh <<'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
+bash ../../test_diff.sh <<'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
diff --git a/tests/034.sh b/tests/034.sh
new file mode 100644
index 0000000..12391f4
--- /dev/null
+++ b/tests/034.sh
@@ -0,0 +1,17 @@
+set -e
+
+cat <<'EOF' > expected
+EOF
+bash ../../test_diff.sh <<'EOF'
+struct S {
+ int a;
+};
+
+struct S* f();
+
+struct S* g() {}
+
+int main() {
+ return 0;
+}
+EOF
diff --git a/tests/035.sh b/tests/035.sh
new file mode 100644
index 0000000..a32709e
--- /dev/null
+++ b/tests/035.sh
@@ -0,0 +1,17 @@
+set -e
+
+cat <<'EOF' > expected
+0
+1
+0
+EOF
+bash ../../test_diff.sh <<'EOF'
+int printf();
+
+int main() {
+ printf("%d\n", !1);
+ printf("%d\n", !0);
+ printf("%d\n", !23);
+ return 0;
+}
+EOF
diff --git a/tests/036.sh b/tests/036.sh
new file mode 100644
index 0000000..2a60cf9
--- /dev/null
+++ b/tests/036.sh
@@ -0,0 +1,27 @@
+set -e
+
+cat <<'EOF' > expected
+42
+EOF
+bash ../../test_diff.sh <<'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
diff --git a/tests/037.sh b/tests/037.sh
new file mode 100644
index 0000000..bc6867b
--- /dev/null
+++ b/tests/037.sh
@@ -0,0 +1,18 @@
+set -e
+
+cat <<'EOF' > expected
+hi
+EOF
+bash ../../test_diff.sh <<'EOF'
+int printf();
+
+void f() {
+ printf("hi\n");
+ return;
+}
+
+int main() {
+ f();
+ return 0;
+}
+EOF
diff --git a/tests/038.sh b/tests/038.sh
new file mode 100644
index 0000000..66ab0ed
--- /dev/null
+++ b/tests/038.sh
@@ -0,0 +1,38 @@
+set -e
+
+cat <<'EOF' > input
+abc
+EOF
+cat <<'EOF' > expected
+4
+abc
+EOF
+bash ../../test_diff.sh <<'EOF'
+void* calloc();
+int getchar();
+int printf();
+
+int read_all(char* buf) {
+ int c;
+ int n = 0;
+ for (0; 1; 0) {
+ c = getchar();
+ if (c == -1) {
+ break;
+ }
+ buf[n] = c;
+ n = n + 1;
+ }
+ return n;
+}
+
+int main() {
+ char* source = calloc(1024, sizeof(char));
+ int source_len = read_all(source);
+
+ printf("%d\n", source_len);
+ printf("%s", source);
+
+ return 0;
+}
+EOF
diff --git a/tests/039.sh b/tests/039.sh
new file mode 100644
index 0000000..fb9dbdb
--- /dev/null
+++ b/tests/039.sh
@@ -0,0 +1,32 @@
+set -e
+
+cat <<'EOF' > expected
+65
+65
+66
+67
+68
+EOF
+bash ../../test_diff.sh <<'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
diff --git a/tests/040.sh b/tests/040.sh
new file mode 100644
index 0000000..647a0e7
--- /dev/null
+++ b/tests/040.sh
@@ -0,0 +1,40 @@
+set -e
+
+cat <<'EOF' > expected
+0
+1
+2
+3
+4
+10
+11
+12
+13
+14
+20
+21
+22
+23
+24
+25
+EOF
+bash ../../test_diff.sh <<'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
diff --git a/tests/041.sh b/tests/041.sh
new file mode 100644
index 0000000..b4bb21e
--- /dev/null
+++ b/tests/041.sh
@@ -0,0 +1,32 @@
+set -e
+
+cat <<'EOF' > expected
+0
+1
+2
+3
+4
+
+5
+4
+3
+2
+1
+0
+EOF
+bash ../../test_diff.sh <<'EOF'
+int printf();
+
+int main() {
+ int i = 0;
+ for (; i < 5; i += 1) {
+ printf("%d\n", i);
+ }
+ printf("\n");
+ for (i = 5; i >= 0; i -= 1) {
+ printf("%d\n", i);
+ }
+
+ return 0;
+}
+EOF
diff --git a/tests/042.sh b/tests/042.sh
new file mode 100644
index 0000000..b9f1749
--- /dev/null
+++ b/tests/042.sh
@@ -0,0 +1,20 @@
+set -e
+
+cat <<'EOF' > expected
+42,123
+EOF
+bash ../../test_diff.sh <<'EOF'
+int printf();
+
+#define A foo_a
+#define B foo_b
+
+int main() {
+ int foo_a = 42;
+ int foo_b = 123;
+
+ printf("%d,%d\n", A, B);
+
+ return 0;
+}
+EOF
diff --git a/tests/043.sh b/tests/043.sh
new file mode 100644
index 0000000..a343918
--- /dev/null
+++ b/tests/043.sh
@@ -0,0 +1,17 @@
+set -e
+
+cat <<'EOF' > expected
+42,123
+EOF
+bash ../../test_diff.sh <<'EOF'
+int printf();
+
+int main() {
+ int _a = 42;
+ int _b = 123;
+
+ printf("%d,%d\n", _a, _b);
+
+ return 0;
+}
+EOF
diff --git a/tests/all.sh b/tests/all.sh
new file mode 100644
index 0000000..70776cf
--- /dev/null
+++ b/tests/all.sh
@@ -0,0 +1,14 @@
+set -e
+
+rm -rf tests/tmp
+mkdir -p tests/tmp
+for i in $(seq 1 999); do
+ testcase=$(printf '%03d' $i)
+ test_file="tests/$testcase.sh"
+ if [[ -f "$test_file" ]]; then
+ bash tests/run.sh "$testcase"
+ else
+ echo "All tests passed."
+ exit
+ fi
+done
diff --git a/tests/run.sh b/tests/run.sh
new file mode 100644
index 0000000..2a5d9be
--- /dev/null
+++ b/tests/run.sh
@@ -0,0 +1,18 @@
+set -e
+
+export p4dcc="../../../$BIN"
+
+export testcase=$1
+export tmp_dir="tests/tmp/$testcase"
+
+test_file="tests/$testcase.sh"
+
+if [[ ! -f "$test_file" ]]; then
+ echo "no test $testcase" >&2
+ exit 1
+fi
+
+echo "$test_file"
+mkdir -p "$tmp_dir"
+cd "$tmp_dir"
+bash "../../../$test_file"
diff --git a/tests/test_diff.sh b/tests/test_diff.sh
new file mode 100644
index 0000000..44e00d0
--- /dev/null
+++ b/tests/test_diff.sh
@@ -0,0 +1,20 @@
+cat > main.c
+
+"$p4dcc" < main.c > main.s
+if [[ $? -ne 0 ]]; then
+ cat main.s >&2
+ exit 1
+fi
+gcc -Wl,-z,noexecstack -o a.out main.s
+if [[ ! -f input ]]; then
+ touch input
+fi
+./a.out < input > output
+exit_code=$?
+
+if [[ $exit_code -ne 0 ]]; then
+ echo "invalid exit code: $exit_code" >&2
+ exit 1
+fi
+
+diff -u expected output
diff --git a/tests/test_exit_code.sh b/tests/test_exit_code.sh
new file mode 100644
index 0000000..f49d468
--- /dev/null
+++ b/tests/test_exit_code.sh
@@ -0,0 +1,17 @@
+cat > main.c
+
+"$p4dcc" < main.c > main.s
+if [[ $? -ne 0 ]]; then
+ cat main.s >&2
+ exit 1
+fi
+gcc -Wl,-z,noexecstack -o a.out main.s
+./a.out
+exit_code=$?
+
+expected=$1
+
+if [[ $exit_code -ne $expected ]]; then
+ echo "invalid exit code: expected $expected, but got $exit_code" >&2
+ exit 1
+fi
diff --git a/tests/test_output.sh b/tests/test_output.sh
new file mode 100644
index 0000000..2c8fb29
--- /dev/null
+++ b/tests/test_output.sh
@@ -0,0 +1,22 @@
+cat > main.c
+
+"$p4dcc" < main.c > main.s
+if [[ $? -ne 0 ]]; then
+ cat main.s >&2
+ exit 1
+fi
+gcc -Wl,-z,noexecstack -o a.out main.s
+output="$(./a.out)"
+exit_code=$?
+
+if [[ $exit_code -ne 0 ]]; then
+ echo "invalid exit code: $exit_code" >&2
+ exit 1
+fi
+
+expected="$1"
+
+if [[ "$output" != "$expected" ]]; then
+ echo "invalid output: expected '$expected', but got '$output'" >&2
+ exit 1
+fi