diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-01-24 01:43:01 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-01-24 01:43:01 +0900 |
| commit | c780cbb6acd0e0526f2d305138190392bdc8cdd7 (patch) | |
| tree | df1edba6eb5778a00e1f4c8a5051414d5bb37e71 | |
| parent | d179d944c0633d3aa2420009335791b115f67052 (diff) | |
| download | ducc-c780cbb6acd0e0526f2d305138190392bdc8cdd7.tar.gz ducc-c780cbb6acd0e0526f2d305138190392bdc8cdd7.tar.zst ducc-c780cbb6acd0e0526f2d305138190392bdc8cdd7.zip | |
refactor: organize test files
60 files changed, 1969 insertions, 1952 deletions
diff --git a/tests/arithmetic_operators.c b/tests/arithmetic_operators.c deleted file mode 100644 index e7cfe95..0000000 --- a/tests/arithmetic_operators.c +++ /dev/null @@ -1,9 +0,0 @@ -#include <helpers.h> - -int main() { - ASSERT_EQ(42, 42); - ASSERT_EQ(21, 5 + 20 - 4); - ASSERT_EQ(26, 2 * 3 + 4 * 5); - ASSERT_EQ(197, (((3 + 5) / 2) + (5 * (9 - 6)) * (5 + 6 * 7)) % 256); - ASSERT_EQ(30, (-10 + 20 * -3) + 100); -} diff --git a/tests/assignment_operators.c b/tests/assignment_operators.c deleted file mode 100644 index 1edc574..0000000 --- a/tests/assignment_operators.c +++ /dev/null @@ -1,64 +0,0 @@ -#include <helpers.h> - -int main() { - int i = 0; - for (; i < 5; i += 1) { - } - ASSERT_EQ(5, i); - - for (i = 5; i >= 0; i -= 1) - ; - ASSERT_EQ(-1, i); - - int x = 123; - x *= 456; - ASSERT_EQ(56088, x); - - int y = 120; - y /= 5; - ASSERT_EQ(24, y); - - int z = 17; - z %= 7; - ASSERT_EQ(3, z); - - int a = 0x05; - a |= 0x0A; - ASSERT_EQ(0x0F, a); - - int b = 0x0F; - b &= 0x0A; - ASSERT_EQ(0x0A, b); - - int c = 7; - c |= 8; - ASSERT_EQ(15, c); - - int d = 15; - d &= 6; - ASSERT_EQ(6, d); - - int e = 0x0F; - e ^= 0x05; - ASSERT_EQ(0x0A, e); - - int f = 3; - f <<= 2; - ASSERT_EQ(12, f); - - int g = 16; - g >>= 2; - ASSERT_EQ(4, g); - - int h = -16; - h >>= 2; - ASSERT_EQ(-4, h); - - int j = 1; - j <<= 4; - ASSERT_EQ(16, j); - - int k = 64; - k >>= 3; - ASSERT_EQ(8, k); -} diff --git a/tests/bitwise_operators.c b/tests/bitwise_operators.c deleted file mode 100644 index e8a5619..0000000 --- a/tests/bitwise_operators.c +++ /dev/null @@ -1,38 +0,0 @@ -#include <helpers.h> - -int main() { - ASSERT_EQ(123, 0 | 123); - ASSERT_EQ(460, 12 | 456); - - ASSERT_EQ(8, 1 << 3); - ASSERT_EQ(336, 21 << 4); - ASSERT_EQ(13, 111 >> 3); - ASSERT_EQ(0, 15 >> 14); - - int a = 5; - int b = 3; - ASSERT_EQ(1, a & b); - ASSERT_EQ(7, a | b); - ASSERT_EQ(6, a ^ b); - ASSERT_EQ(4, 2 + 3 & 4); - - int c = 1 + 2 & 3; - int d = 4 & 5 ^ 6; - int e = 1 ^ 2 | 3; - int f = 0 | 1 & 2; - ASSERT_EQ(3, c); - ASSERT_EQ(2, d); - ASSERT_EQ(3, e); - ASSERT_EQ(0, f); - - ASSERT_EQ(-1, ~0); - ASSERT_EQ(-2, ~1); - ASSERT_EQ(-6, ~5); - ASSERT_EQ(0, ~(-1)); - ASSERT_EQ(5, ~(-6)); - - int x = 10; - ASSERT_EQ(-11, ~x); - ASSERT_EQ(-1, ~(x & 0)); - ASSERT_EQ(-16, ~(x | 5)); -} diff --git a/tests/bool_type.c b/tests/bool_type.c deleted file mode 100644 index 7313410..0000000 --- a/tests/bool_type.c +++ /dev/null @@ -1,10 +0,0 @@ -#include <helpers.h> - -int main() { - bool b1 = true, b0 = false; - ASSERT_EQ(1, b1); - ASSERT_EQ(0, b0); - ASSERT_EQ(1, sizeof(b1)); - ASSERT_EQ(1, sizeof(b0)); - ASSERT_EQ(1, sizeof(bool)); -} diff --git a/tests/cli.sh b/tests/cli.sh new file mode 100644 index 0000000..fc8a481 --- /dev/null +++ b/tests/cli.sh @@ -0,0 +1,79 @@ +# --version +expected="ducc v0.3.0" + +if [[ "$("$ducc" --version)" != "$expected" ]]; then + echo "invalid output" >&2 + exit 1 +fi + +# assembly output +cat > foo.c <<'EOF' +int main() {} +EOF + +"$ducc" -o bar.s foo.c +if [[ $? -ne 0 ]]; then + exit 1 +fi +gcc -o a.out bar.s +./a.out "$@" +exit_code=$? + +if [[ $exit_code -ne 0 ]]; then + echo "invalid exit code: $exit_code" >&2 + exit 1 +fi + +# argc/argv +cat <<'EOF' > expected +argc = 4 +argv[1] = hoge +argv[2] = piyo +argv[3] = fuga +EOF +test_diff hoge piyo fuga<<'EOF' +int printf(); + +int main(int argc, char** argv) { + printf("argc = %d\n", argc); + int i; + for (i = 1; i < argc; ++i) { + printf("argv[%d] = %s\n", i, argv[i]); + } + return 0; +} +EOF + +# compile errors +cat <<'EOF' > expected +main.c:2: undefined function: f +EOF +test_compile_error <<'EOF' +int main() { + f(); +} +EOF + +# TODO: improve error message +# cat <<'EOF' > expected +# main.c:1: expected ';' or '{', but got '}' +# EOF +cat <<'EOF' > expected +main.c:1: expected ';', but got '}' +EOF + +test_compile_error <<'EOF' +int main() } +EOF + +# TODO: improve error message +# cat <<'EOF' > expected +# main.c:1: expected ';' or '{', but got '}' +# EOF +cat <<'EOF' > expected +main.c:1: expected ';', but got '123' +EOF + +test_compile_error <<'EOF' +int main() 123 +EOF diff --git a/tests/comma_operator.sh b/tests/comma_operator.sh deleted file mode 100644 index b754cf5..0000000 --- a/tests/comma_operator.sh +++ /dev/null @@ -1,36 +0,0 @@ -cat <<'EOF' > expected -0 0 -1 1 -2 2 -3 3 -4 4 -EOF - -test_diff <<'EOF' -int printf(); - -int main() { - int i = 1000; - int j = 1000; - for (i = 0, j = 0; i < 5; i++, j++) { - printf("%d %d\n", i, j); - } -} -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 diff --git a/tests/command_line_args.sh b/tests/command_line_args.sh deleted file mode 100644 index 7286815..0000000 --- a/tests/command_line_args.sh +++ /dev/null @@ -1,18 +0,0 @@ -cat <<'EOF' > expected -argc = 4 -argv[1] = hoge -argv[2] = piyo -argv[3] = fuga -EOF -test_diff hoge piyo fuga<<'EOF' -int printf(); - -int main(int argc, char** argv) { - printf("argc = %d\n", argc); - int i; - for (i = 1; i < argc; ++i) { - printf("argv[%d] = %s\n", i, argv[i]); - } - return 0; -} -EOF diff --git a/tests/comments.sh b/tests/comments.sh deleted file mode 100644 index 1318f93..0000000 --- a/tests/comments.sh +++ /dev/null @@ -1,24 +0,0 @@ -cat <<'EOF' > expected -EOF -test_diff <<'EOF' -// TODO: check if the token is at the beginning of line. -// TODO: check if skipped whitespaces do not contain line breaks. -int main() { - return 0; -} -EOF - -cat <<'EOF' > expected -EOF - -test_diff <<'EOF' -/* lorem ipsum */ -/* -lorem ipsum -*/ -// /* -/* /* - */ -int/**/main() { -} -EOF diff --git a/tests/comparison_operators.c b/tests/comparison_operators.c deleted file mode 100644 index 7e0600d..0000000 --- a/tests/comparison_operators.c +++ /dev/null @@ -1,12 +0,0 @@ -#include <helpers.h> - -int main() { - ASSERT_EQ(1, 0 == 0); - ASSERT_EQ(0, 123 != 123); - ASSERT_EQ(1, 123 != 456); - ASSERT_EQ(0, 123 == 124); - ASSERT_EQ(1, 123 < 567); - ASSERT_EQ(1, 123 <= 567); - ASSERT_EQ(1, 123 <= 123); - ASSERT_EQ(0, 123 < 123); -} diff --git a/tests/compile_errors.sh b/tests/compile_errors.sh deleted file mode 100644 index e99282b..0000000 --- a/tests/compile_errors.sh +++ /dev/null @@ -1,32 +0,0 @@ -cat <<'EOF' > expected -main.c:2: undefined function: f -EOF -test_compile_error <<'EOF' -int main() { - f(); -} -EOF - -# TODO: improve error message -# cat <<'EOF' > expected -# main.c:1: expected ';' or '{', but got '}' -# EOF -cat <<'EOF' > expected -main.c:1: expected ';', but got '}' -EOF - -test_compile_error <<'EOF' -int main() } -EOF - -# TODO: improve error message -# cat <<'EOF' > expected -# main.c:1: expected ';' or '{', but got '}' -# EOF -cat <<'EOF' > expected -main.c:1: expected ';', but got '123' -EOF - -test_compile_error <<'EOF' -int main() 123 -EOF diff --git a/tests/compiler_output.sh b/tests/compiler_output.sh deleted file mode 100644 index 33c4f17..0000000 --- a/tests/compiler_output.sh +++ /dev/null @@ -1,16 +0,0 @@ -cat > foo.c <<'EOF' -int main() {} -EOF - -"$ducc" -o bar.s foo.c -if [[ $? -ne 0 ]]; then - exit 1 -fi -gcc -o a.out bar.s -./a.out "$@" -exit_code=$? - -if [[ $exit_code -ne 0 ]]; then - echo "invalid exit code: $exit_code" >&2 - exit 1 -fi diff --git a/tests/compiler_version.sh b/tests/compiler_version.sh deleted file mode 100644 index 76ba104..0000000 --- a/tests/compiler_version.sh +++ /dev/null @@ -1,6 +0,0 @@ -expected="ducc v0.3.0" - -if [[ "$("$ducc" --version)" != "$expected" ]]; then - echo "invalid output" >&2 - exit 1 -fi diff --git a/tests/define_macros.sh b/tests/define_macros.sh deleted file mode 100644 index c92560f..0000000 --- a/tests/define_macros.sh +++ /dev/null @@ -1,91 +0,0 @@ -cat <<'EOF' > expected -EOF -test_diff <<'EOF' -#define A 1 -int main() { - return 0; -} -EOF - -cat <<'EOF' > expected -1,2,3 -EOF -test_diff <<'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 -test_diff <<'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 - -cat <<'EOF' > expected -42,123 -EOF -test_diff <<'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 - -cat <<'EOF' > expected -123 -EOF - -test_diff <<'EOF' -#define foo() 123 - -int printf(); - -int main() { - printf("%d\n", foo()); -} -EOF - -cat <<'EOF' > expected -579 -975 -EOF - -test_diff <<'EOF' -#define foo 123 + 456 -#define bar() 321 + 654 - -int printf(); - -int main() { - printf("%d\n", foo); - printf("%d\n", bar()); -} -EOF diff --git a/tests/empty_preprocessor.sh b/tests/empty_preprocessor.sh index 5a744a8..c9000b3 100644 --- a/tests/empty_preprocessor.sh +++ b/tests/empty_preprocessor.sh @@ -1,4 +1,4 @@ -touch expected +> expected test_diff <<'EOF' # # diff --git a/tests/enums.sh b/tests/enums.sh deleted file mode 100644 index 3fc15a0..0000000 --- a/tests/enums.sh +++ /dev/null @@ -1,48 +0,0 @@ -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/ex_fizzbuzz.sh b/tests/ex_fizzbuzz.sh deleted file mode 100644 index b7a9e6b..0000000 --- a/tests/ex_fizzbuzz.sh +++ /dev/null @@ -1,106 +0,0 @@ -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 - -test_example fizzbuzz diff --git a/tests/ex_hello.sh b/tests/ex_hello.sh deleted file mode 100644 index 750c14a..0000000 --- a/tests/ex_hello.sh +++ /dev/null @@ -1,7 +0,0 @@ -set -e - -cat <<'EOF' > expected -Hello, World! -EOF - -test_example hello diff --git a/tests/example_programs.sh b/tests/examples.sh index 24b3f29..6b15ed8 100644 --- a/tests/example_programs.sh +++ b/tests/examples.sh @@ -1,3 +1,117 @@ +# hello +cat <<'EOF' > expected +Hello, World! +EOF + +test_example hello + +# fizzbuzz +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 + +test_example fizzbuzz + +# example programs cat <<'EOF' > expected 1 2 diff --git a/tests/cast_expressions.sh b/tests/expressions.sh index b493e04..dadfade 100644 --- a/tests/cast_expressions.sh +++ b/tests/expressions.sh @@ -1,3 +1,141 @@ +# logical operators +cat <<'EOF' > expected +foo +EOF +test_diff <<'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 +test_diff <<'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 +0 +1 +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 + +test_diff <<'EOF' +int printf(); + +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); +} +EOF + +# comma operator +cat <<'EOF' > expected +0 0 +1 1 +2 2 +3 3 +4 4 +EOF + +test_diff <<'EOF' +int printf(); + +int main() { + int i = 1000; + int j = 1000; + for (i = 0, j = 0; i < 5; i++, j++) { + printf("%d %d\n", i, j); + } +} +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 diff --git a/tests/function_macros.sh b/tests/function_macros.sh deleted file mode 100644 index 1108650..0000000 --- a/tests/function_macros.sh +++ /dev/null @@ -1,110 +0,0 @@ -cat <<'EOF' > expected -42 -246 -221 -EOF - -test_diff <<'EOF' -int printf(); - -#define A(x) x -#define B(x) x+x -#define C(x, y) x*y - -int main() { - printf("%d\n", A(42)); - printf("%d\n", B - (123)); - printf("%d\n", C (13, 17)); -} -EOF - -cat <<'EOF' > expected -123 -EOF -test_diff <<'EOF' -#define A(x) x - -int printf(); - -int main() { - printf("%d\n", A ( 123 )); -} -EOF - -cat <<'EOF' > expected -main.c:4: expected ')', but got '<new-line>' -EOF -test_compile_error <<'EOF' -#define A(x) x - -int main() { -#if A ( - 123) < A(345) - printf("1\n"); -#endif -} -EOF - -cat <<'EOF' > expected -42 -100 200 -300 -0 -1 2 3 -15 -42 -123 -879 -EOF - -test_diff <<'EOF' -int printf(); - -#define ADD(a, b) ((a) + (b)) -#define PRINT_TWO(x, y) printf("%d %d\n", x, y) -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#define NESTED(x) (x) -#define CONCAT3(a, b, c) a ## b ## c - -int main() { - printf("%d\n", ADD(40, 2)); - PRINT_TWO(100, 200); - printf("%d\n", MAX(100 + 200, 250)); - printf("%d\n"); - NESTED((printf("1 "), printf("2 "), printf("3\n"), 0)); - - int x = 5, y = 10; - printf("%d\n", ADD(x + 2, y - 2)); - printf("%d\n", ADD(MAX(10, 20), MAX(15 + 5, 22))); - printf("%d\n", ADD( 100 , 23 )); - printf("%d\n", ADD(NESTED((100 + 200)), MAX((123 + 456), (111 + 222)))); -} -EOF - -cat <<'EOF' > expected -int printf ( const char *, ...); - -int main () { - int foo = 42; - printf ( %d\n, foo); - - int a = 123; - printf ( %d\n, a); -} -EOF -test_cpp <<'EOF' -int printf(const char*, ...); - -int main() { -#define foo foo - int foo = 42; - printf("%d\n", foo); - -#define a b -#define b c -#define c a - int a = 123; - printf("%d\n", a); -} -EOF diff --git a/tests/function_pointers.sh b/tests/function_pointers.sh deleted file mode 100644 index cddc623..0000000 --- a/tests/function_pointers.sh +++ /dev/null @@ -1,24 +0,0 @@ -cat <<'EOF' > expected -a -h -g -EOF - -test_diff <<'EOF' -int* f1(int a); -int (*f2)(int a); - -extern int atexit (void (*) (void)); -extern int atexit (void (*fn) (void)); - -int printf(const char*, ...); - -void g() { printf("g\n"); } -void h() { printf("h\n"); } - -int main() { - atexit(g); - atexit(h); - printf("a\n"); -} -EOF diff --git a/tests/function_basics.c b/tests/functions.c index 83fb66e..e9e622e 100644 --- a/tests/function_basics.c +++ b/tests/functions.c @@ -96,7 +96,17 @@ int f9(int select, int a, int b, int c, int d, S e, int f, int g) { } } +// recursive functions +int fib(int n) { + if (n <= 1) { + return 1; + } else { + return fib(n - 1) + fib(n - 2); + } +} + int main() { + // function basics ASSERT_EQ(66, foo()); ASSERT_EQ(10, 10 * f(1, 2, 3, 4, 5, 6)); ASSERT_EQ(20, 10 * f2(1, 2, 3, 4, 5, 6)); @@ -126,4 +136,7 @@ int main() { ASSERT_EQ(6, f9(5, 1, 2, 3, 4, s, 7, 8)); ASSERT_EQ(7, f9(6, 1, 2, 3, 4, s, 7, 8)); ASSERT_EQ(8, f9(7, 1, 2, 3, 4, s, 7, 8)); + + // recursive functions + ASSERT_EQ(89, fib(10)); } diff --git a/tests/functions.sh b/tests/functions.sh new file mode 100644 index 0000000..ddae9b2 --- /dev/null +++ b/tests/functions.sh @@ -0,0 +1,148 @@ +# function pointers +cat <<'EOF' > expected +a +h +g +EOF + +test_diff <<'EOF' +int* f1(int a); +int (*f2)(int a); + +extern int atexit (void (*) (void)); +extern int atexit (void (*fn) (void)); + +int printf(const char*, ...); + +void g() { printf("g\n"); } +void h() { printf("h\n"); } + +int main() { + atexit(g); + atexit(h); + printf("a\n"); +} +EOF + +# void functions +cat <<'EOF' > expected +123 +EOF +test_diff <<'EOF' +int printf(); + +void foo_bar(int hoge_piyo) { + printf("%d\n", hoge_piyo); +} + +int main() { + foo_bar(123); + return 0; +} +EOF + +cat <<'EOF' > expected +EOF +test_diff <<'EOF' +struct S { + int a; +}; + +struct S* f(); + +struct S* g() {} + +int main() { + return 0; +} +EOF + +cat <<'EOF' > expected +hi +EOF +test_diff <<'EOF' +int printf(); + +void f() { + printf("hi\n"); + return; +} + +int main() { + f(); + return 0; +} +EOF + +# variadic functions +cat <<'EOF' > expected +123 +456 789 +EOF + +test_diff <<'EOF' +#include <stdarg.h> + +int fprintf(); + +struct FILE; +typedef struct FILE FILE; + +extern FILE* stdout; + +int vfprintf(FILE*, const char*, va_list); + +void fatal_error(const char* msg, ...) { + va_list args; + va_start(args, msg); + vfprintf(stdout, msg, args); + va_end(args); + fprintf(stdout, "\n"); +} + +int main() { + fatal_error("%d", 123); + fatal_error("%d %d", 456, 789); + return 0; +} +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' +int main() { +} +EOF + +test_exit_code 0 <<'EOF' +int main() { + 1 + 2 + 3; +} +EOF + +test_exit_code 0 <<'EOF' +int main() { + if (1); + else return 1; +} +EOF diff --git a/tests/global_variables.c b/tests/global_variables.c deleted file mode 100644 index 20e0a64..0000000 --- a/tests/global_variables.c +++ /dev/null @@ -1,36 +0,0 @@ -#include <helpers.h> - -int printf(const char*, ...); -int strcmp(const char*, const char*); - -int a; -int* b = &a; -int c[10]; -int* d = c; -int e, *f = e, g[10], *h = g; - -char i = 42; -short j = 123; -int k = 999; - -char l[6] = "hello"; - -int main() { - *b = 123; - ASSERT_EQ(123, a); - - d[2] = 42; - ASSERT_EQ(42, c[2]); - - *f = 456; - ASSERT_EQ(456, e); - - h[5] = 789; - ASSERT_EQ(789, g[5]); - - ASSERT_EQ(42, i); - ASSERT_EQ(123, j); - ASSERT_EQ(999, k); - - ASSERT_EQ(0, strcmp("hello", l)); -} diff --git a/tests/goto.sh b/tests/goto.sh index 1e28a51..4d00031 100644 --- a/tests/goto.sh +++ b/tests/goto.sh @@ -1,4 +1,4 @@ -touch expected +> expected test_diff <<'EOF' int main() { goto end; diff --git a/tests/identifiers.sh b/tests/identifiers.sh deleted file mode 100644 index ae00bd3..0000000 --- a/tests/identifiers.sh +++ /dev/null @@ -1,15 +0,0 @@ -cat <<'EOF' > expected -42,123 -EOF -test_diff <<'EOF' -int printf(); - -int main() { - int _a = 42; - int _b = 123; - - printf("%d,%d\n", _a, _b); - - return 0; -} -EOF diff --git a/tests/implicit_return.sh b/tests/implicit_return.sh deleted file mode 100644 index 20a8bed..0000000 --- a/tests/implicit_return.sh +++ /dev/null @@ -1,18 +0,0 @@ -# C99: 5.1.2.2.3 -test_exit_code 0 <<'EOF' -int main() { -} -EOF - -test_exit_code 0 <<'EOF' -int main() { - 1 + 2 + 3; -} -EOF - -test_exit_code 0 <<'EOF' -int main() { - if (1); - else return 1; -} -EOF diff --git a/tests/include.sh b/tests/include.sh new file mode 100644 index 0000000..33cabb4 --- /dev/null +++ b/tests/include.sh @@ -0,0 +1,189 @@ +cat <<'EOF' > header.h +int add(int a, int b) { + return a + b; +} + +int printf(const char*, ...); +EOF + +cat <<'EOF' > expected +8 +EOF +test_diff <<'EOF' +#include "header.h" + +int main() { + printf("%d\n", add(5, 3)); + return 0; +} +EOF + +mkdir -p foo +cat <<'EOF' > bar.h +#include "baz.h" +EOF +cat <<'EOF' > baz.h +#define A 123 +EOF +cat <<'EOF' > foo/bar.h +#include "baz.h" +EOF +cat <<'EOF' > foo/baz.h +#define A 456 +EOF + +cat <<'EOF' > expected +123 +456 +EOF +test_diff <<'EOF' +int printf(const char*, ...); + +int main() { +#include "bar.h" + printf("%d\n", A); + +#undef A + +#include "foo/bar.h" + printf("%d\n", A); +} +EOF + +cat <<'EOF' > expected +12 +EOF + +cat <<'EOF' > math.h +int multiply(int a, int b) { + return a * b; +} +EOF + +cat <<'EOF' > calc.h +#include "math.h" + +int calculate(int x) { + return multiply(x, 2); +} + +int printf(const char*, ...); +EOF + +test_diff <<'EOF' +#include "calc.h" + +int main() { + printf("%d\n", calculate(6)); + return 0; +} +EOF + +cat <<'EOF' > expected +42 +EOF + +cat <<'EOF' > header.h +#define A 42 +EOF + +test_diff <<'EOF' +#include "header.h" + +int printf(); + +int main() { + printf("%d\n", A); + return 0; +} +EOF + +cat <<'EOF' > expected +42 +EOF + +cat <<'EOF' > header.h +#ifndef HEADER_H +#define HEADER_H + +int f() { return 42; } + +#endif +EOF + +test_diff <<'EOF' +#include "header.h" +#include "header.h" +#include "header.h" + +int printf(); + +int main() { + printf("%d\n", HEADER_H HEADER_H HEADER_H f() HEADER_H HEADER_H HEADER_H); + return 0; +} +EOF + +cat <<'EOF' > expected +main.c:1: cannot open include file: "nonexistent.h" +EOF + +test_compile_error <<'EOF' +#include "nonexistent.h" + +int main() { + return 0; +} +EOF + +cat <<'EOF' > expected +include depth limit exceeded +EOF + +# Create circular include files +cat <<'EOF' > a.h +#include "b.h" +int a() { return 1; } +EOF + +cat <<'EOF' > b.h +#include "a.h" +int b() { return 2; } +EOF + +test_compile_error <<'EOF' +#include "a.h" + +int main() { + a() + b(); + return 0; +} +EOF + +cat <<'EOF' > expected +main.c:1: cannot open include file: "hoge.h" +EOF + +test_compile_error <<'EOF' +#include "hoge.h" +EOF + +cat <<'EOF' > expected +main.c:1: cannot resolve include file name: <hoge.h> +EOF + +test_compile_error <<'EOF' +#include <hoge.h> +EOF + +cat <<'EOF' > expected +42 +EOF + +test_exit_code 0 <<'EOF' +#ifdef FOO +#include FOO +#endif + +int main() { 1 < 2; } +EOF diff --git a/tests/include_errors.sh b/tests/include_errors.sh deleted file mode 100644 index e0f856e..0000000 --- a/tests/include_errors.sh +++ /dev/null @@ -1,63 +0,0 @@ -cat <<'EOF' > expected -main.c:1: cannot open include file: "nonexistent.h" -EOF - -test_compile_error <<'EOF' -#include "nonexistent.h" - -int main() { - return 0; -} -EOF - -cat <<'EOF' > expected -include depth limit exceeded -EOF - -# Create circular include files -cat <<'EOF' > a.h -#include "b.h" -int a() { return 1; } -EOF - -cat <<'EOF' > b.h -#include "a.h" -int b() { return 2; } -EOF - -test_compile_error <<'EOF' -#include "a.h" - -int main() { - a() + b(); - return 0; -} -EOF - -cat <<'EOF' > expected -main.c:1: cannot open include file: "hoge.h" -EOF - -test_compile_error <<'EOF' -#include "hoge.h" -EOF - -cat <<'EOF' > expected -main.c:1: cannot resolve include file name: <hoge.h> -EOF - -test_compile_error <<'EOF' -#include <hoge.h> -EOF - -cat <<'EOF' > expected -42 -EOF - -test_exit_code 0 <<'EOF' -#ifdef FOO -#include FOO -#endif - -int main() { 1 < 2; } -EOF diff --git a/tests/include_guards.sh b/tests/include_guards.sh deleted file mode 100644 index f8f0462..0000000 --- a/tests/include_guards.sh +++ /dev/null @@ -1,25 +0,0 @@ -cat <<'EOF' > expected -42 -EOF - -cat <<'EOF' > header.h -#ifndef HEADER_H -#define HEADER_H - -int f() { return 42; } - -#endif -EOF - -test_diff <<'EOF' -#include "header.h" -#include "header.h" -#include "header.h" - -int printf(); - -int main() { - printf("%d\n", HEADER_H HEADER_H HEADER_H f() HEADER_H HEADER_H HEADER_H); - return 0; -} -EOF diff --git a/tests/include_local.sh b/tests/include_local.sh deleted file mode 100644 index 05c42b7..0000000 --- a/tests/include_local.sh +++ /dev/null @@ -1,99 +0,0 @@ -cat <<'EOF' > header.h -int add(int a, int b) { - return a + b; -} - -int printf(const char*, ...); -EOF - -cat <<'EOF' > expected -8 -EOF -test_diff <<'EOF' -#include "header.h" - -int main() { - printf("%d\n", add(5, 3)); - return 0; -} -EOF - -mkdir -p foo -cat <<'EOF' > bar.h -#include "baz.h" -EOF -cat <<'EOF' > baz.h -#define A 123 -EOF -cat <<'EOF' > foo/bar.h -#include "baz.h" -EOF -cat <<'EOF' > foo/baz.h -#define A 456 -EOF - -cat <<'EOF' > expected -123 -456 -EOF -test_diff <<'EOF' -int printf(const char*, ...); - -int main() { -#include "bar.h" - printf("%d\n", A); - -#undef A - -#include "foo/bar.h" - printf("%d\n", A); -} -EOF - -cat <<'EOF' > expected -12 -EOF - -cat <<'EOF' > math.h -int multiply(int a, int b) { - return a * b; -} -EOF - -cat <<'EOF' > calc.h -#include "math.h" - -int calculate(int x) { - return multiply(x, 2); -} - -int printf(const char*, ...); -EOF - -test_diff <<'EOF' -#include "calc.h" - -int main() { - printf("%d\n", calculate(6)); - return 0; -} -EOF - -cat <<'EOF' > expected -42 -EOF - -cat <<'EOF' > header.h -#define A 42 -EOF - -test_diff <<'EOF' -#include "header.h" - -int printf(); - -int main() { - printf("%d\n", A); - return 0; -} -EOF diff --git a/tests/increment_operators.sh b/tests/increment_operators.sh deleted file mode 100644 index e7fb221..0000000 --- a/tests/increment_operators.sh +++ /dev/null @@ -1,28 +0,0 @@ -cat <<'EOF' > expected -44 -44 -46 -46 -44 -42 -42 -EOF - -test_diff <<'EOF' -int printf(); - -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); -} -EOF diff --git a/tests/keywords.sh b/tests/keywords.sh deleted file mode 100644 index 0bdb6f7..0000000 --- a/tests/keywords.sh +++ /dev/null @@ -1,14 +0,0 @@ -cat <<'EOF' > expected - - -int printf (); -int main () {} -EOF - -test_cpp <<'EOF' -// A keyword is treated as a normal identifier in preprocessing phase. -#define auto int - -auto printf(); -auto main() {} -EOF diff --git a/tests/char_literals.c b/tests/literals.c index cc592ff..7b84ea1 100644 --- a/tests/char_literals.c +++ b/tests/literals.c @@ -1,6 +1,13 @@ #include <helpers.h> int main() { + // number literals + ASSERT_EQ(0, 0); + ASSERT_EQ(291, 0x123); + ASSERT_EQ(3405691582, 0xcafebabe); + ASSERT_EQ(436, 0664); + + // char literals ASSERT_EQ(97, 'a'); ASSERT_EQ(48, '0'); ASSERT_EQ(92, '\\'); @@ -22,4 +29,12 @@ int main() { ASSERT_EQ(0, '\0'); ASSERT_EQ(27, '\e'); + + // bool type + bool b1 = true, b0 = false; + ASSERT_EQ(1, b1); + ASSERT_EQ(0, b0); + ASSERT_EQ(1, sizeof(b1)); + ASSERT_EQ(1, sizeof(b0)); + ASSERT_EQ(1, sizeof(bool)); } diff --git a/tests/local_variables.c b/tests/local_variables.c deleted file mode 100644 index ac63f04..0000000 --- a/tests/local_variables.c +++ /dev/null @@ -1,38 +0,0 @@ -#include <helpers.h> - -int main() { - int foo; - foo = 42; - ASSERT_EQ(42, foo); - - int bar; - bar = 28; - ASSERT_EQ(70, foo + bar); - - 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; - - ASSERT_EQ(45, a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + 0); - - int d = 2, e = d, f = d + e; - ASSERT_EQ(2, d); - ASSERT_EQ(2, e); - ASSERT_EQ(4, f); -} diff --git a/tests/logical_operators.sh b/tests/logical_operators.sh deleted file mode 100644 index b4332e5..0000000 --- a/tests/logical_operators.sh +++ /dev/null @@ -1,67 +0,0 @@ -cat <<'EOF' > expected -foo -EOF -test_diff <<'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 -test_diff <<'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 -0 -1 -0 -EOF -test_diff <<'EOF' -int printf(); - -int main() { - printf("%d\n", !1); - printf("%d\n", !0); - printf("%d\n", !23); - return 0; -} -EOF diff --git a/tests/macro_operators.sh b/tests/macro_operators.sh deleted file mode 100644 index 2954d53..0000000 --- a/tests/macro_operators.sh +++ /dev/null @@ -1,134 +0,0 @@ -cat <<'EOF' > expected -int printf (); - - -int foobar = 100; -int prefix_test = 200; -int test_suffix = 300; - -int var_1 = 10; -int var_2 = 20; - -int var_A = 30; - -int number_12 = 12; - -int bazqux = 42; - -int main () { - printf ( foobar=%d\n, foobar); - printf ( prefix_test=%d\n, prefix_test); - printf ( test_suffix=%d\n, test_suffix); - printf ( var_1=%d\n, var_1); - printf ( var_2=%d\n, var_2); - printf ( var_A=%d\n, var_A); - printf ( number_12=%d\n, number_12); - return 0; -} -EOF - -test_cpp <<'EOF' -int printf(); - -#define CONCAT(a, b) a##b -#define PREFIX(name) prefix_##name -#define SUFFIX(name) name##_suffix - -int CONCAT(foo, bar) = 100; -int PREFIX(test) = 200; -int SUFFIX(test) = 300; - -#define MAKE_VAR(n) var_##n -int MAKE_VAR(1) = 10; -int MAKE_VAR(2) = 20; - -#define A 0 -int MAKE_VAR(A) = 30; - -#define NUMBER(x, y) number_##x##y -int NUMBER(1, 2) = 12; - -#define CONCAT2(a, b) a ## b -int CONCAT2(baz, qux) = 42; - -int main() { - printf("foobar=%d\n", foobar); - printf("prefix_test=%d\n", prefix_test); - printf("test_suffix=%d\n", test_suffix); - printf("var_1=%d\n", var_1); - printf("var_2=%d\n", var_2); - printf("var_A=%d\n", var_A); - printf("number_12=%d\n", number_12); - return 0; -} -EOF - -cat <<'EOF' > expected -int printf ( const char *, ...); - - -int H ( int n) { return n; } - -int main () { - printf ( %d\n, H ( 123)); -} -EOF - -test_cpp <<'EOF' -int printf(const char*, ...); - -#define F(x) CHECK(G(x)) -#define G(x) CHECK(H(x)) -#define CHECK(x) x - -int H(int n) { return n; } - -int main() { - printf("%d\n", F(123)); -} -EOF - -test_exit_code 0 <<'EOF' -#include <helpers.h> - -int strcmp(const char*, const char*); - -#define FOO 42 - -#define TO_STRING(x) TO_STRING_HELPER(x) -#define TO_STRING_HELPER(x) #x -#define BAR TO_STRING(FOO) - -#define TO_STRING2(x) #x -#define BAZ TO_STRING2(FOO) - -int main() { - ASSERT_EQ(0, strcmp("42", BAR)); - ASSERT_EQ(0, strcmp("FOO", BAZ)); -} -EOF - -test_exit_code 0 <<'EOF' -#include <helpers.h> - -#define CONCAT3(x, y, z) x##y##z -#define FOO CONCAT3(, 2, 3) -#define BAR CONCAT3(1, , 3) -#define BAZ CONCAT3(1, 2, ) - -int main() { - ASSERT_EQ(23, FOO); - ASSERT_EQ(13, BAR); - ASSERT_EQ(12, BAZ); -} -EOF - -cat <<'EOF' > expected -foo -EOF - -test_cpp <<'EOF' -#define CONCAT(x, y) x ## y -#define CONCAT2(name, r) CONCAT(name, r) -CONCAT2(foo,) -EOF diff --git a/tests/macros.sh b/tests/macros.sh new file mode 100644 index 0000000..69baae5 --- /dev/null +++ b/tests/macros.sh @@ -0,0 +1,426 @@ +cat <<'EOF' > expected +EOF +test_diff <<'EOF' +#define A 1 +int main() { + return 0; +} +EOF + +cat <<'EOF' > expected +1,2,3 +EOF +test_diff <<'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 +test_diff <<'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 + +cat <<'EOF' > expected +42,123 +EOF +test_diff <<'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 + +cat <<'EOF' > expected +123 +EOF + +test_diff <<'EOF' +#define foo() 123 + +int printf(); + +int main() { + printf("%d\n", foo()); +} +EOF + +cat <<'EOF' > expected +579 +975 +EOF + +test_diff <<'EOF' +#define foo 123 + 456 +#define bar() 321 + 654 + +int printf(); + +int main() { + printf("%d\n", foo); + printf("%d\n", bar()); +} +EOF + +cat <<'EOF' > expected +42 +246 +221 +EOF + +test_diff <<'EOF' +int printf(); + +#define A(x) x +#define B(x) x+x +#define C(x, y) x*y + +int main() { + printf("%d\n", A(42)); + printf("%d\n", B + (123)); + printf("%d\n", C (13, 17)); +} +EOF + +cat <<'EOF' > expected +123 +EOF +test_diff <<'EOF' +#define A(x) x + +int printf(); + +int main() { + printf("%d\n", A ( 123 )); +} +EOF + +cat <<'EOF' > expected +main.c:4: expected ')', but got '<new-line>' +EOF +test_compile_error <<'EOF' +#define A(x) x + +int main() { +#if A ( + 123) < A(345) + printf("1\n"); +#endif +} +EOF + +cat <<'EOF' > expected +42 +100 200 +300 +0 +1 2 3 +15 +42 +123 +879 +EOF + +test_diff <<'EOF' +int printf(); + +#define ADD(a, b) ((a) + (b)) +#define PRINT_TWO(x, y) printf("%d %d\n", x, y) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define NESTED(x) (x) +#define CONCAT3(a, b, c) a ## b ## c + +int main() { + printf("%d\n", ADD(40, 2)); + PRINT_TWO(100, 200); + printf("%d\n", MAX(100 + 200, 250)); + printf("%d\n"); + NESTED((printf("1 "), printf("2 "), printf("3\n"), 0)); + + int x = 5, y = 10; + printf("%d\n", ADD(x + 2, y - 2)); + printf("%d\n", ADD(MAX(10, 20), MAX(15 + 5, 22))); + printf("%d\n", ADD( 100 , 23 )); + printf("%d\n", ADD(NESTED((100 + 200)), MAX((123 + 456), (111 + 222)))); +} +EOF + +cat <<'EOF' > expected +int printf ( const char *, ...); + +int main () { + int foo = 42; + printf ( %d\n, foo); + + int a = 123; + printf ( %d\n, a); +} +EOF +test_cpp <<'EOF' +int printf(const char*, ...); + +int main() { +#define foo foo + int foo = 42; + printf("%d\n", foo); + +#define a b +#define b c +#define c a + int a = 123; + printf("%d\n", a); +} +EOF + +cat <<'EOF' > expected +int printf (); + + +int foobar = 100; +int prefix_test = 200; +int test_suffix = 300; + +int var_1 = 10; +int var_2 = 20; + +int var_A = 30; + +int number_12 = 12; + +int bazqux = 42; + +int main () { + printf ( foobar=%d\n, foobar); + printf ( prefix_test=%d\n, prefix_test); + printf ( test_suffix=%d\n, test_suffix); + printf ( var_1=%d\n, var_1); + printf ( var_2=%d\n, var_2); + printf ( var_A=%d\n, var_A); + printf ( number_12=%d\n, number_12); + return 0; +} +EOF + +test_cpp <<'EOF' +int printf(); + +#define CONCAT(a, b) a##b +#define PREFIX(name) prefix_##name +#define SUFFIX(name) name##_suffix + +int CONCAT(foo, bar) = 100; +int PREFIX(test) = 200; +int SUFFIX(test) = 300; + +#define MAKE_VAR(n) var_##n +int MAKE_VAR(1) = 10; +int MAKE_VAR(2) = 20; + +#define A 0 +int MAKE_VAR(A) = 30; + +#define NUMBER(x, y) number_##x##y +int NUMBER(1, 2) = 12; + +#define CONCAT2(a, b) a ## b +int CONCAT2(baz, qux) = 42; + +int main() { + printf("foobar=%d\n", foobar); + printf("prefix_test=%d\n", prefix_test); + printf("test_suffix=%d\n", test_suffix); + printf("var_1=%d\n", var_1); + printf("var_2=%d\n", var_2); + printf("var_A=%d\n", var_A); + printf("number_12=%d\n", number_12); + return 0; +} +EOF + +cat <<'EOF' > expected +int printf ( const char *, ...); + + +int H ( int n) { return n; } + +int main () { + printf ( %d\n, H ( 123)); +} +EOF + +test_cpp <<'EOF' +int printf(const char*, ...); + +#define F(x) CHECK(G(x)) +#define G(x) CHECK(H(x)) +#define CHECK(x) x + +int H(int n) { return n; } + +int main() { + printf("%d\n", F(123)); +} +EOF + +test_exit_code 0 <<'EOF' +#include <helpers.h> + +int strcmp(const char*, const char*); + +#define FOO 42 + +#define TO_STRING(x) TO_STRING_HELPER(x) +#define TO_STRING_HELPER(x) #x +#define BAR TO_STRING(FOO) + +#define TO_STRING2(x) #x +#define BAZ TO_STRING2(FOO) + +int main() { + ASSERT_EQ(0, strcmp("42", BAR)); + ASSERT_EQ(0, strcmp("FOO", BAZ)); +} +EOF + +test_exit_code 0 <<'EOF' +#include <helpers.h> + +#define CONCAT3(x, y, z) x##y##z +#define FOO CONCAT3(, 2, 3) +#define BAR CONCAT3(1, , 3) +#define BAZ CONCAT3(1, 2, ) + +int main() { + ASSERT_EQ(23, FOO); + ASSERT_EQ(13, BAR); + ASSERT_EQ(12, BAZ); +} +EOF + +cat <<'EOF' > expected +foo +EOF + +test_cpp <<'EOF' +#define CONCAT(x, y) x ## y +#define CONCAT2(name, r) CONCAT(name, r) +CONCAT2(foo,) +EOF + +cat <<'EOF' > expected +1 +EOF + +test_diff <<'EOF' +int printf(); + +int main() { + printf("%d\n", __ducc__); + return 0; +} +EOF + +cat <<'EOF' > expected +main.c +main.c +main.c +EOF + +cat <<'EOF' > header.h +#define A __FILE__ +EOF + +test_diff <<'EOF' +#define B __FILE__ +#include "header.h" +int printf(); +int main() { + printf("%s\n", __FILE__); + printf("%s\n", B); + printf("%s\n", A); +} +EOF + +cat <<'EOF' > expected +5 +6 6 +7 7 +EOF + +cat <<'EOF' > header.h +#define A __LINE__ +EOF + +test_diff <<'EOF' +#define B __LINE__ +#include "header.h" +int printf(); +int main() { + printf("%d\n", __LINE__); + printf("%d %d\n", B, B); + printf("%d %d\n", A, A); +} +EOF + +cat <<'EOF' > expected +int printf (); + +int main () { + + printf ( A is defined\n); + + + printf ( A is undefined\n); +} +EOF + +test_cpp <<'EOF' +int printf(); + +int main() { +#define A 1 + +#ifdef A + printf("A is defined\n"); +#else + printf("A is undefined\n"); +#endif + +#undef A + +#ifdef A + printf("A is defined\n"); +#else + printf("A is undefined\n"); +#endif +} +EOF diff --git a/tests/number_literals.c b/tests/number_literals.c deleted file mode 100644 index c28e4e3..0000000 --- a/tests/number_literals.c +++ /dev/null @@ -1,8 +0,0 @@ -#include <helpers.h> - -int main() { - ASSERT_EQ(0, 0); - ASSERT_EQ(291, 0x123); - ASSERT_EQ(3405691582, 0xcafebabe); - ASSERT_EQ(436, 0664); -} diff --git a/tests/operators.c b/tests/operators.c new file mode 100644 index 0000000..9e9ba08 --- /dev/null +++ b/tests/operators.c @@ -0,0 +1,122 @@ +#include <helpers.h> + +int main() { + // arithmetic operators + ASSERT_EQ(42, 42); + ASSERT_EQ(21, 5 + 20 - 4); + ASSERT_EQ(26, 2 * 3 + 4 * 5); + ASSERT_EQ(197, (((3 + 5) / 2) + (5 * (9 - 6)) * (5 + 6 * 7)) % 256); + ASSERT_EQ(30, (-10 + 20 * -3) + 100); + + // comparison operators + ASSERT_EQ(1, 0 == 0); + ASSERT_EQ(0, 123 != 123); + ASSERT_EQ(1, 123 != 456); + ASSERT_EQ(0, 123 == 124); + ASSERT_EQ(1, 123 < 567); + ASSERT_EQ(1, 123 <= 567); + ASSERT_EQ(1, 123 <= 123); + ASSERT_EQ(0, 123 < 123); + + // bitwise operators + ASSERT_EQ(123, 0 | 123); + ASSERT_EQ(460, 12 | 456); + + ASSERT_EQ(8, 1 << 3); + ASSERT_EQ(336, 21 << 4); + ASSERT_EQ(13, 111 >> 3); + ASSERT_EQ(0, 15 >> 14); + + int a = 5; + int b = 3; + ASSERT_EQ(1, a & b); + ASSERT_EQ(7, a | b); + ASSERT_EQ(6, a ^ b); + ASSERT_EQ(4, 2 + 3 & 4); + + int c = 1 + 2 & 3; + int d = 4 & 5 ^ 6; + int e = 1 ^ 2 | 3; + int f = 0 | 1 & 2; + ASSERT_EQ(3, c); + ASSERT_EQ(2, d); + ASSERT_EQ(3, e); + ASSERT_EQ(0, f); + + ASSERT_EQ(-1, ~0); + ASSERT_EQ(-2, ~1); + ASSERT_EQ(-6, ~5); + ASSERT_EQ(0, ~(-1)); + ASSERT_EQ(5, ~(-6)); + + int x = 10; + ASSERT_EQ(-11, ~x); + ASSERT_EQ(-1, ~(x & 0)); + ASSERT_EQ(-16, ~(x | 5)); + + // assignment operators + int i = 0; + for (; i < 5; i += 1) { + } + ASSERT_EQ(5, i); + + for (i = 5; i >= 0; i -= 1) + ; + ASSERT_EQ(-1, i); + + x = 123; + x *= 456; + ASSERT_EQ(56088, x); + + int y = 120; + y /= 5; + ASSERT_EQ(24, y); + + int z = 17; + z %= 7; + ASSERT_EQ(3, z); + + a = 0x05; + a |= 0x0A; + ASSERT_EQ(0x0F, a); + + b = 0x0F; + b &= 0x0A; + ASSERT_EQ(0x0A, b); + + c = 7; + c |= 8; + ASSERT_EQ(15, c); + + d = 15; + d &= 6; + ASSERT_EQ(6, d); + + e = 0x0F; + e ^= 0x05; + ASSERT_EQ(0x0A, e); + + f = 3; + f <<= 2; + ASSERT_EQ(12, f); + + int g = 16; + g >>= 2; + ASSERT_EQ(4, g); + + int h = -16; + h >>= 2; + ASSERT_EQ(-4, h); + + int j = 1; + j <<= 4; + ASSERT_EQ(16, j); + + int k = 64; + k >>= 3; + ASSERT_EQ(8, k); + + // ternary operator + ASSERT_EQ(2, 1 ? 2 : 3); + ASSERT_EQ(5, 0 ? 4 : 5); +} diff --git a/tests/pointer_basics.sh b/tests/pointer_basics.sh deleted file mode 100644 index 6faa421..0000000 --- a/tests/pointer_basics.sh +++ /dev/null @@ -1,79 +0,0 @@ -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 diff --git a/tests/array_basics.sh b/tests/pointers.sh index e50a3c0..bbd4ed4 100644 --- a/tests/array_basics.sh +++ b/tests/pointers.sh @@ -1,3 +1,85 @@ +# 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 @@ -160,3 +242,76 @@ int main() { 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/predefined_macros.sh b/tests/predefined_macros.sh deleted file mode 100644 index ada2fdd..0000000 --- a/tests/predefined_macros.sh +++ /dev/null @@ -1,54 +0,0 @@ -cat <<'EOF' > expected -1 -EOF - -test_diff <<'EOF' -int printf(); - -int main() { - printf("%d\n", __ducc__); - return 0; -} -EOF - -cat <<'EOF' > expected -main.c -main.c -main.c -EOF - -cat <<'EOF' > header.h -#define A __FILE__ -EOF - -test_diff <<'EOF' -#define B __FILE__ -#include "header.h" -int printf(); -int main() { - printf("%s\n", __FILE__); - printf("%s\n", B); - printf("%s\n", A); -} -EOF - -cat <<'EOF' > expected -5 -6 6 -7 7 -EOF - -cat <<'EOF' > header.h -#define A __LINE__ -EOF - -test_diff <<'EOF' -#define B __LINE__ -#include "header.h" -int printf(); -int main() { - printf("%d\n", __LINE__); - printf("%d %d\n", B, B); - printf("%d %d\n", A, A); -} -EOF diff --git a/tests/printf.sh b/tests/printf.sh index 7c4454c..ec805dc 100644 --- a/tests/printf.sh +++ b/tests/printf.sh @@ -1,4 +1,4 @@ -touch expected +> expected test_diff <<'EOF' int printf(); diff --git a/tests/recursive_functions.c b/tests/recursive_functions.c deleted file mode 100644 index b81824a..0000000 --- a/tests/recursive_functions.c +++ /dev/null @@ -1,13 +0,0 @@ -#include <helpers.h> - -int fib(int n) { - if (n <= 1) { - return 1; - } else { - return fib(n - 1) + fib(n - 2); - } -} - -int main() { - ASSERT_EQ(89, fib(10)); -} diff --git a/tests/short_type.sh b/tests/short_type.sh deleted file mode 100644 index b298a98..0000000 --- a/tests/short_type.sh +++ /dev/null @@ -1,16 +0,0 @@ -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 diff --git a/tests/stdlib_declarations.sh b/tests/stdlib_declarations.sh deleted file mode 100644 index efd6a30..0000000 --- a/tests/stdlib_declarations.sh +++ /dev/null @@ -1,21 +0,0 @@ -cat <<'EOF' > expected -EOF -test_diff <<'EOF' -typedef long size_t; - -int atoi(const char*); -void* calloc(size_t, size_t); -void exit(int); -int getchar(void); -int isalnum(int); -int isalpha(int); -int isdigit(int); -int isspace(int); -void* memcpy(void*, void*, size_t); -int printf(const char*, ...); -int sprintf(char*, const char*, ...); -int strcmp(const char*, const char*); -char* strstr(const char*, const char*); - -int main() { return 0; } -EOF diff --git a/tests/string_operations.sh b/tests/string_operations.sh deleted file mode 100644 index 2466145..0000000 --- a/tests/string_operations.sh +++ /dev/null @@ -1,71 +0,0 @@ -touch expected -test_diff <<'EOF' -int main() { - ""; - return 0; -} -EOF - -touch expected -test_diff <<'EOF' -int main() { - "abc"; - return 0; -} -EOF - -touch 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/struct_arrays.sh b/tests/struct_arrays.sh deleted file mode 100644 index 628c0d3..0000000 --- a/tests/struct_arrays.sh +++ /dev/null @@ -1,33 +0,0 @@ -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 diff --git a/tests/struct_basics.sh b/tests/struct_basics.sh deleted file mode 100644 index 13a50a5..0000000 --- a/tests/struct_basics.sh +++ /dev/null @@ -1,137 +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 diff --git a/tests/struct_initialization.sh b/tests/struct_initialization.sh deleted file mode 100644 index f2c92cf..0000000 --- a/tests/struct_initialization.sh +++ /dev/null @@ -1,107 +0,0 @@ -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 diff --git a/tests/structs.sh b/tests/structs.sh new file mode 100644 index 0000000..4c8ff6d --- /dev/null +++ b/tests/structs.sh @@ -0,0 +1,364 @@ +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 diff --git a/tests/ternary_operator.c b/tests/ternary_operator.c deleted file mode 100644 index 1f46dbe..0000000 --- a/tests/ternary_operator.c +++ /dev/null @@ -1,6 +0,0 @@ -#include <helpers.h> - -int main() { - ASSERT_EQ(2, 1 ? 2 : 3); - ASSERT_EQ(5, 0 ? 4 : 5); -} diff --git a/tests/line_continuation.sh b/tests/tokenize.sh index 89f4543..2db9640 100644 --- a/tests/line_continuation.sh +++ b/tests/tokenize.sh @@ -1,3 +1,47 @@ +# comments +cat <<'EOF' > expected +EOF +test_diff <<'EOF' +// TODO: check if the token is at the beginning of line. +// TODO: check if skipped whitespaces do not contain line breaks. +int main() { + return 0; +} +EOF + +cat <<'EOF' > expected +EOF + +test_diff <<'EOF' +/* lorem ipsum */ +/* +lorem ipsum +*/ +// /* +/* /* + */ +int/**/main() { +} +EOF + +# identifiers +cat <<'EOF' > expected +42,123 +EOF +test_diff <<'EOF' +int printf(); + +int main() { + int _a = 42; + int _b = 123; + + printf("%d,%d\n", _a, _b); + + return 0; +} +EOF + +# line continuation cat <<'EOF' > expected 10 20 100 300 500 @@ -54,3 +98,19 @@ test_diff < main_cr.c # Mixed printf 'int printf(const char*, ...);\nint main() {\r\n printf("Hello World\\n");\r printf("Line con\\\r\ntinues\\n");\n return 0;\r\n}\r\n' > main_mixed.c test_diff < main_mixed.c + +# keywords +cat <<'EOF' > expected + + +int printf (); +int main () {} +EOF + +test_cpp <<'EOF' +// A keyword is treated as a normal identifier in preprocessing phase. +#define auto int + +auto printf(); +auto main() {} +EOF diff --git a/tests/typedef_struct.sh b/tests/typedef_struct.sh deleted file mode 100644 index 593d903..0000000 --- a/tests/typedef_struct.sh +++ /dev/null @@ -1,84 +0,0 @@ -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 diff --git a/tests/sizeof_operator.sh b/tests/types.sh index c8df5da..892f85b 100644 --- a/tests/sizeof_operator.sh +++ b/tests/types.sh @@ -1,3 +1,22 @@ +# 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 @@ -174,3 +193,53 @@ int main() { 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/undef.sh b/tests/undef.sh deleted file mode 100644 index 27d03c6..0000000 --- a/tests/undef.sh +++ /dev/null @@ -1,33 +0,0 @@ -cat <<'EOF' > expected -int printf (); - -int main () { - - printf ( A is defined\n); - - - printf ( A is undefined\n); -} -EOF - -test_cpp <<'EOF' -int printf(); - -int main() { -#define A 1 - -#ifdef A - printf("A is defined\n"); -#else - printf("A is undefined\n"); -#endif - -#undef A - -#ifdef A - printf("A is defined\n"); -#else - printf("A is undefined\n"); -#endif -} -EOF diff --git a/tests/variables.c b/tests/variables.c new file mode 100644 index 0000000..0bd2127 --- /dev/null +++ b/tests/variables.c @@ -0,0 +1,74 @@ +#include <helpers.h> + +int printf(const char*, ...); +int strcmp(const char*, const char*); + +// global variables +int g_a; +int* g_b = &g_a; +int g_c[10]; +int* g_d = g_c; +int g_e, *g_f = g_e, g_g[10], *g_h = g_g; + +char g_i = 42; +short g_j = 123; +int g_k = 999; + +char g_l[6] = "hello"; + +int main() { + // global variables + *g_b = 123; + ASSERT_EQ(123, g_a); + + g_d[2] = 42; + ASSERT_EQ(42, g_c[2]); + + *g_f = 456; + ASSERT_EQ(456, g_e); + + g_h[5] = 789; + ASSERT_EQ(789, g_g[5]); + + ASSERT_EQ(42, g_i); + ASSERT_EQ(123, g_j); + ASSERT_EQ(999, g_k); + + ASSERT_EQ(0, strcmp("hello", g_l)); + + // local variables + int foo; + foo = 42; + ASSERT_EQ(42, foo); + + int bar; + bar = 28; + ASSERT_EQ(70, foo + bar); + + 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; + + ASSERT_EQ(45, a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + 0); + + int d = 2, e = d, f = d + e; + ASSERT_EQ(2, d); + ASSERT_EQ(2, e); + ASSERT_EQ(4, f); +} diff --git a/tests/variadic_functions.sh b/tests/variadic_functions.sh deleted file mode 100644 index 155fc1a..0000000 --- a/tests/variadic_functions.sh +++ /dev/null @@ -1,51 +0,0 @@ -cat <<'EOF' > expected -123 -456 789 -EOF - -test_diff <<'EOF' -#include <stdarg.h> - -int fprintf(); - -struct FILE; -typedef struct FILE FILE; - -extern FILE* stdout; - -int vfprintf(FILE*, const char*, va_list); - -void fatal_error(const char* msg, ...) { - va_list args; - va_start(args, msg); - vfprintf(stdout, msg, args); - va_end(args); - fprintf(stdout, "\n"); -} - -int main() { - fatal_error("%d", 123); - fatal_error("%d %d", 456, 789); - return 0; -} -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 diff --git a/tests/void_functions.sh b/tests/void_functions.sh deleted file mode 100644 index 656c2c1..0000000 --- a/tests/void_functions.sh +++ /dev/null @@ -1,48 +0,0 @@ -cat <<'EOF' > expected -123 -EOF -test_diff <<'EOF' -int printf(); - -void foo_bar(int hoge_piyo) { - printf("%d\n", hoge_piyo); -} - -int main() { - foo_bar(123); - return 0; -} -EOF - -cat <<'EOF' > expected -EOF -test_diff <<'EOF' -struct S { - int a; -}; - -struct S* f(); - -struct S* g() {} - -int main() { - return 0; -} -EOF - -cat <<'EOF' > expected -hi -EOF -test_diff <<'EOF' -int printf(); - -void f() { - printf("hi\n"); - return; -} - -int main() { - f(); - return 0; -} -EOF |
