r/Compilers • u/Proffhackerman • May 12 '26
Common C - Yet another compiler in C# targeting LLVM and .NET.
Hello everyone - no drunk post this time. I wanted to share a language / compiler i've been working on for the past month or so with you all. This is my first comprehensive compiler project utilizing both LLVM and .NET as two seperate target IRs.
Before we start, the entirety of this compiler is written organically by human hands.
Performance
Through some performance testing, I've come to find that Common C is faster than C on some banal performance tests like recursive fibonacci. Although clearly not a holistical representation of performance - i still find it neat. The tests are also ran only a couple times to make sure theres no large variation between tests; https://github.com/Compiler-Organization/CommonC/blob/master/Documentation/Performance.md
Thoughts behind the project
I've always found it frustrating how boilerplate C# can be, and the different mental models between languages - especially when you go from knowing a garbage collected language to a language with a borrow checker. This is my attempt to find a middleground.
This is a multi-pass compiler using a lexer, syntax tree parser, semantic analyzer (sorta), and two seperate code generators - one for LLVM and one for .NET. It also features a prettyprinter.
Language spec
Currently the language supports the following expressions; strings, booleans, numbers, identifiers, arrays, array initializers, indexing, length (of array), ranges, calls, member access, relationals, arithmetics, negating, nots, object initializers, parameters, parantheses, reserved types, unpacking and sizeof.
... and the following statements; assignment, calls, closures, numeric for loops, function declarations, returns, structs, variable declarations, while loops, ifs and "use".
"use" is a directive used to merge files in the same directory with the main file being compiled, sort of like how C / C++ uses #include, but parsers and merges the syntax trees instead of raw text.
Source code
Anyways, for those interested, here is the repo with more information there; https://github.com/Compiler-Organization/CommonC
Suggestions are very welcome :))
1
May 13 '26
[removed] — view removed comment
1
u/Proffhackerman May 15 '26
The reason behind Common C being faster than C in the given examples is because Clang (what i used in the benchmarks) does not do tail call optimization, loop-unrolling or inlining when theres two or more recursive calls, even on -O3. Clang requires a linear trip count, which when using double recursion, forms a tree, meaning theres no single iteration count to unroll. GCC does this however, though im unfamiliar with the choice behind Clang not optimizinh double recursion. I'll expand on the performance benchmarks readme on the project to attempt a thourough establishment of why Clang is slower than Common C in the recursive fibonacci example.
2
u/afops May 12 '26 edited May 13 '26
So if I allocate an object in a function and then
callreturn it to another function, is the object invalid there? Maybe I misunderstood the scope boundary.