SOCC is a simple C Compiler written in OCaml using ocamllex and menhir.
Dependences: core, ppx_jane
opam update
opam install core ppx_jane
git clone git@github.com:noti0na1/socc.git
cd socc
make
The executable file is main.native
# use gcc to preprocess the source code
gcc -E test.c -o test.e.c
./main.native < test.e.c > test.s
gcc test.s -o test
./test
There are 4 buildin functions for test:
void println(int)
int readi()
void *malloc(size_t)
void free(void *)
int main() {
int *pi = malloc(sizeof(int));
int max = readi();
for (int i = 0; i < max; i += 2) {
println(i);
*pi += i;
}
println(*pi);
free(pi);
return 0;
}
.LC0:
.string "%d\n"
.globl println
println:
movq %rdi, %rsi
movq $0, %rax
movl $.LC0, %edi
jmp printf
.LC1:
.string "%d"
.globl readi
readi:
subq $24, %rsp
movl $.LC1, %edi
movq $0, %rax
leaq 12(%rsp), %rsi
movl $0, 12(%rsp)
call __isoc99_scanf
movl 12(%rsp), %eax
addq $24, %rsp
ret
.globl main
main:
pushq %rbp
movq %rsp, %rbp
movq $4, %rax
movq %rax, %rdi
call malloc
pushq %rax
call readi
pushq %rax
movl $0, %eax
pushq %rax
LmainFORA0:
movq -24(%rbp), %rax
pushq %rax
movq -16(%rbp), %rax
movq %rax, %rcx
popq %rax
cmpl %ecx, %eax
movl $0, %eax
setl %al
cmpl $0, %eax
je LmainFORC0
movq -24(%rbp), %rax
movq %rax, %rdi
call println
movq -8(%rbp), %rax
pushq %rax
movq -8(%rbp), %rax
movq (%rax), %rax
pushq %rax
movq -24(%rbp), %rax
movq %rax, %rcx
popq %rax
addl %ecx, %eax
movq %rax, %rcx
popq %rax
movl %ecx, (%rax)
addq $0, %rsp
LmainFORB0:
movq -24(%rbp), %rax
pushq %rax
movl $2, %eax
movq %rax, %rcx
popq %rax
addl %ecx, %eax
movq %rax, -24(%rbp)
jmp LmainFORA0
LmainFORC0:
addq $8, %rsp
movq -8(%rbp), %rax
movq (%rax), %rax
movq %rax, %rdi
call println
movq -8(%rbp), %rax
movq %rax, %rdi
call free
movl $0, %eax
leave
ret
In: 23
Out:
0
2
4
6
8
10
12
14
16
18
20
22
132
socc/src
source codeast.ml
abstract syntax treeparser.mly
parserlexer.mll
lexercontext.ml
x64.ml
X64 assemblytemplib.ml
temporery lib (println
,readi
)generate.ml
code generatorutil.ml
utilsmain.ml
program entry
socc/test
some test files
Core
is used across the project
The output assembly is for x64 Linux platform
- follow the C11 to edit lexer
- add array type and array operate
- implement
++
and--
- support comments
- add more type, implement struct, union, enum
- complete type system
- optimize stack usage
- improve parser further more
- add error, warning print ...
- add semantic check pass
- add intermediate lang
Parsing with OCamllex and Menhir
Lexer and parser generators (ocamllex, ocamlyacc)
SOCC is distributed under the terms of MIT License
Copyright (c) 2018 noti0na1