sk2cc is a compiler for the subset of the C language. It aims to support almost all language features of C11 while keeping the implementation as simple as possible. For example, in lexical analyzer and parser, all code is hand-written, parser generators such as lex/flex and yacc/bison are not used. So you can easily understand the implementation.
sk2cc has been achieved self-hosting, which means we can compile the source code of sk2cc with sk2cc itself. You can understand what features are supported by sk2cc by reading its implementation because the all written code can be compiled with sk2cc.
In sk2cc's code generation, we succeeded in simplifying register allocation by pushing all intermediate calculation results onto the stack.
For example, when calculating 1 + 2
, sk2cc pushes 1
and 2
onto the stack, and then these values are popped into the registers.
Then two values are added, and resulting value is pushed onto the stack again.
While the register allocation is easy, the execution speed of generated assembly is slow.
sk2cc also includes the assembly, so you can generate object file from assembly source code. However, sk2cc can not link object files and generate executable file, and the existing linker is needed for linking. You can link object files by simply passing them gcc.
You can build sk2cc with make command:
make
This repository contains test script of sk2cc. We check the self-hosted executable (self) and the executable generated by self-hosted executable (self2) in addition to the executable generated by gcc (sk2cc). You can run all test suites:
make test
sk2cc recieves path to a source file and generates assembly to stdout. sk2cc also includes assembler, and can convert assmebly source code to object file. To generate executable, use gcc with static link. The example of compiling the sample programs is as follows:
// hello.c
int printf(char *format, ...);
int main() {
printf("Hello World\n");
return 0;
}
# compile
./sk2cc hello.c > hello.s
# assemble
./sk2cc --as hello.s hello.o
# link with gcc
gcc -static hello.o -o hello
# execution
./hello
For example, sk2cc can compile the following program to find fibonacci numbers recursively:
int printf(char *format, ...);
int fib(int n) {
if (n == 0) return 0;
if (n == 1) return 1;
return fib(n - 1) + fib(n - 2);
}
int main() {
for (int i = 0; i < 20) {
printf("%d: %d\n", i, fib(i));
}
return 0;
}
For another example, sk2cc can convert the following assembly program to print Hello World
:
.section .rodata
.S0:
.ascii "Hello World\n\0"
.data
.global hello
hello:
.quad .S0
.text
.global main
main:
pushq %rbp
movq %rsp, %rbp
movq hello(%rip), %rdi
xorl %eax, %eax
call printf
leave
ret
Furthermore, the sk2cc source code itself can also be used as a compilable program.
This compiler is developed by Shinya Kato (Twitter: 0x19f).