Code Monkey home page Code Monkey logo

wrecc's Introduction

Test

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

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:

  •  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
int foo(void);
int main() {
  int a = foo(1);
  long *p = a;

  return p * 2;
}
error

Ast pretty-printer

When compiling using the --dump-ast option it prints the parse-tree

C code AST
#define SIZE 16
void foo(char);
int main() {
  int arr[SIZE] = {1, 2};
  char p = (char)(*arr + 3);

  switch (p) {
  case 'c':
    foo(p);
  }
}
Declaration:
-Decl: 'foo'
FuncDef: 'main'
-Declaration:
--Init: 'arr'
---Aggregate:
----Scalar:
-----Literal: 1
----Scalar:
-----Literal: 2
-Declaration:
--Init: 'p'
---Scalar:
----Cast: 'char'
-----Grouping:
------Binary: '+'
-------Unary: '*'
--------Ident: 'arr'
-------Literal: 3
-Switch:
--Ident: 'p'
--Block:
---Case:
----Literal: 99
----Expr:
-----FuncCall:
------Ident: 'foo'
------Ident: 'p'

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:

wrecc's People

Contributors

philipprados avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

wrecc's Issues

Problem with array argv in argument of main function

Hi, good job !

I've tested the Wrecc compiler and found an error. I couldn't find in the documentation whether it's a feature that isn't already supported. Forgive me if this is not the case.

#include <stdio.h>

int main(int argc, char *argv[]) {
    printf("Hello, World!\n");
    return 0;
}

The compiler generate this error :

error: expected expression, found: ']'
|  --> in main.c:3:31
|
3 int main(int argc, char *argv[]) {
|                               ^
1 error generated.

Unfortunately, I don't have the required skills to fix this and propose a pull request.

Why is the dynamic linker explicitly overridden?

wrecc/src/main.rs

Lines 152 to 153 in 37a8413

.arg("-dynamic-linker")
.arg("/lib64/ld-linux-x86-64.so.2")

This explicitly sets the dynamic linker to a fixed value.
This could fail in a few ways:

  • the system only has /lib64/ld-linux-x86-64.so.1 (unlikely)
  • the system doesn't have /lib64/ld-linux-x86-64.so.2 -> like NixOS (which is a linux distribution!), and of course BSDs (if you want to support them in the future).

I did a few tests and it looks like LD has its own logic for resolving a dynamic linker.

man 1 ld also warns against setting your own dynamic linker, saying "The default dynamic linker is normally correct".

By removing these lines, the executables generated by wrecc could run unpatched on NixOS.

Preprocessor has problem comparing numbers with the `l` suffix.

The l is lowercase L.
Steps to reproduce:

$ cat program.c
#if defined __cplusplus && __cplusplus >= 199711l
#endif

int main(void)
{
}
$ wrecc -D NDEBUG program.c
error: found trailing tokens after preprocessor expression
|  --> in program.c:1:49
|
1 #if defined __cplusplus && __cplusplus >= 199711l
|                                                 ^
1 error generated.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.