The test suite for the upcoming book Writing a C Compiler, a hands-on guide to writing your own compiler for a big chunk of C. These tests are still a work in progress!
Each test case is a C program. Some (in the valid/
subdirectories) are valid, and others (in the invalid_*/
subdirectories) have compile-time errors.
The test runner compiles each test program with the compiler under test. An invalid test case passes if the compiler rejects it (i.e. terminates with a non-zero exit code and does not produce any output files). A valid test case passes if it's compiled correctly (i.e. the compiler produces an executable which, when run, produces the expected output and terminates with the expected exit code).
Some invalid test cases include errors that most compilers don't warn about by default. If GCC or Clang isn't complaining about an invalid test case, try compiling it again with the -pedantic
flag.
You need the gcc
command on your path. (On macOS this is an alias for Clang; this is fine.) You also need Python 3.8 or later.
git clone https://github.com/nlsandler/writing-a-c-compiler-tests.git
cd writing-a-c-compiler-tests
./test_compiler --check-setup # make sure you meet all the system requirements
Run the tests for chapters 1-4
./test_compiler ~/mycc --chapter 4
Run the tests for chapter 4 but not chapters 1-3
./test_compiler ~/mycc --chapter 4 --latest-only
./test_compiler ~/mycc --chapter 4 --skip-invalid
./test_compiler ~/mycc --chapter 4 -f
./test_compiler ~/mycc --chapter 9 --bitwise --compound
1
or 2
if it hits a lexer or parser error. When specified, an invalid test case passes only if the compiler exits with one of these exit codes, and fails otherwise. Useful for distinguishing expected failures (i.e. the compiler detected an error) from unexpected failures (e.g. internal errors, segfaults)../test_compiler ~/my_cc --chapter 1 --expected-error-codes 1 2
Two things have changed since the initial early access version of the book:
int main(void)
instead of int main()
to declare a function with no parameters. You'll need to define a void
token in the lexer and include it in the grammar rule for function definitions.