2 unstable releases
0.2.0 | Apr 19, 2024 |
---|---|
0.1.0 | Apr 4, 2024 |
#358 in Development tools
555KB
13K
SLoC
wrecc
is a small,lean x86-64 C99 compiler written from scratch. The name is a play on the word wreck which describes a rusting ship on the sea floor.
The compiler emits x86-64 assembly in AT&T syntax, it adheres to the System V ABI which I could only test for Ubuntu and Macos. There are no dependencies you only need your assembler and linker which the compiler then invokes to create the final binary.
Table of contents
Installation
Pre-built binaries
If you don't have the rust toolchain installed on your system you can install the latest binary (MacOs, Linux) from the releases directly:
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/PhilippRados/wrecc/releases/download/v0.2.0/wrecc-installer.sh | sh
Cargo
Using cargo binstall
cargo binstall wrecc
or building from source
cargo install wrecc
Features
Since not all keywords are currently implemented wrecc uses custom standard-headers which are built directly into the binary
Preprocessor
The preprocessor implements all C99 preprocessor directives, except #line
, #error
and #pragma
. Most prominently it currently also misses function-like macros which are on the agenda though.
Compiler
Supported Keywords
Other than that it even supports:
Aggregate initialization with designated initializers
struct {
union {
int foo;
long baz;
} nested;
int array[16];
} bar = { .nested.foo = 3, .array[6] = 1};
Function pointers
#include <stdio.h>
typedef int (*BinaryOperation)(int, int);
typedef struct {
BinaryOperation add;
BinaryOperation subtract;
} Calculator;
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int main() {
Calculator calc = {add, subtract};
printf("Result of addition: %d\n", calc.add(10, 5));
printf("Result of subtraction: %d\n", calc.subtract(10, 5));
}
Constant folding
char **string_offset = (char **)&"hello" + (int)(3 * 1);
int array[(long)3 * 2 - 1];
Unimplemented Features
Aside from the missing keywords these are the main missing features:
- [x] Arrays with unspecified size
- Compiling multiple files at once
- [ ] Raw structs/unions as function argument-/return-types
- [ ] Floating point types
Here is a list of all the stuff still missing: todo
Error messages
Wrecc also has nice looking messages. Error reporting doesn't stop after the first error. Using the --no-color
option you can switch off color-highlighting in errors. Currently there are only errors and no warnings.
C code | Errors |
---|---|
|
Ast pretty-printer
When compiling using the --dump-ast
option it prints the parse-tree
C code | AST |
---|---|
|
|
Inspect all options by running wrecc --help
Testing
Unit tests
cargo test --workspace
Snapshot testing
This runs all fixtures and compares them to the expected snapshot
bash tests/snapshot_tests.sh
Fuzzer
Runs the fuzzer using afl.rs
// in fuzzer directory
cargo afl build
cargo afl fuzz -i inputs -o outputs target/debug/fuzz_target
Troubleshooting
Reasons for wrecc
not working properly on your machine:
- Unsupported architecture/OS
- Cannot find libc in standard library search paths (can be fixed by passing custom search path using
-L <path>
option) - If it's not mentioned in the unimplemented features section then please raise an issue
Contribution
If you want to help me with this compiler I would really welcome it. The easiest place to start is probably by implementing one of the missing keywords/types mentioned in the unimplemented features section. Make sure all tests still pass and implement your own if it's something new that is not already being tested.
Have a look at the documentation to get a high level overview of the compiler pipeline.
Project goals
- Not relying on custom headers
- Passing all C99 tests in c-testsuite
- Compiling real-world C projects like Git
Resources
The following resources helped me in building this compiler:
- Crafting Interpreters
- Engineering a Compiler (Book)
- acwj
- saltwater
- chibicc