Caramel is a compiler of a limited subset of the C language. Caramel is divided into 2 parts:
- The front-end, which creates an Abstract Syntax Tree from the source code.
- The back-end, which compile the AST into full assembly language (x86_64 ASM).
Caramel has been created by KALATE Team:
- Kévin Dumanoir ([email protected])
- Alexandre Gourgaud ([email protected])
- Thomas Lacroix ([email protected])
- Aurore Loiseau ([email protected])
- Elise Petit ([email protected])
- Loïc Rouquette ([email protected])
for the CS department - INSA Lyon 2018.
# Git clone with SSH
git clone --recursive [email protected]:hexanome-kalate/pld-comp.git
# Git clone with HTTPS
git clone --recursive https://gitlab.com/hexanome-kalate/pld-comp.git
# If already cloned
git submodule update --init --recursive
Caramel requires a C++17 compiler (at least GCC 6) and at least CMake 3.8.
If you have a C++17 compiler installed, but not defined as your default C++ compiler, you can invoque Chef this way:
# Invoke Chef, specifying the C++ compiler
CXX=/usr/bin/gcc-6 ./chef.py build -a
Caramel uses Chef, it's cooking assistant, for almost every operations.
$ ./chef.py -h
usage: chef.py [-h] [--verbose | --quiet] {clean,build,test} ...
The Caramel Jack of all trades.
optional arguments:
-h, --help show this help message and exit
--verbose, -v increase the verbosity (repeat for even more verbosity)
--quiet, -q decrease the verbosity (repeat for less verbosity)
Available commands:
{clean,build,test}
clean Ask the Chef to clean up his workplace.
build Make the Chef cook some Caramel.
test Test the Caramel quality.
Some commands:
# Build the Antlr parser and Caramel. This is rarely needed as `test all -b` does the same, and more.
./chef.py build -a
# Clean the project
./chef.py clean
$ ./chef.py test -h
usage: chef.py test [-h] {grammar,semantic,backend,programs,all} ...
optional arguments:
-h, --help show this help message and exit
Available sub-commands:
{grammar,semantic,backend,programs,all}
grammar Test the Caramel grammar.
semantic Test the Caramel semantic analysis.
backend Test the Caramel back-end.
programs Test the execution of some example programs.
all Run all tests.
$ ./chef.py test all -b
Will build the project and execute all the tests.
- Tests marked as
[+]
are valid tests that must succeed. - Tests marked as
[-]
are invalid tests that must fail.
Note: Some tests require inputs, such as get_char.c
and interactive_factorial.c
.
For these two, just enter a digit then press Enter.
We encourage you to run ./build/cpp-bin/Caramel --help
to see every
Caramel options. Here is the most common usage:
# Compile (-c), assemble (-A) and execute (-A again), with static analysis (-a)
# the source file path/to/source/file.c. -vv increase the verbosity.
# --ast-dot generates the ast.pdf file, and --ir-dot the ir.pdf file.
cd ./build/cpp-bin
./Caramel -vv -acA --ast-dot --ir-dot path/to/source/file.c
# You can open ast.pdf and ir.pdf
xdg-open ast.pdf
xdg-open ir.pdf
Note: You may encounter an error with a shared library, such as:
./Caramel: error while loading shared libraries:
libantlr4-runtime.so.4.7.1: cannot open shared object file: No such file or directory
You just have to prepend LD_LIBRARY_PATH=lib
:
LD_LIBRARY_PATH=../../lib ./Caramel ...
While writing the grammar, we used Chef to help us: by running grammar
tests, and by showing us the syntax tree. Chef has a lot of useful
options, so we won't show them all. Please refer to the help through
the --help
flag.
# Build the Antlr parser and run all the grammar tests, showing the syntax tree for failed tests
./chef.py test grammar -baG
# Build the Antlr parser and run a single test with the syntax tree
./chef.py test grammar -bg path/to/a/test.c
# Check a source interactively
./chef.py test grammar -i
As for the grammar, we used Chef for executing the tests:
# Run semantic tests
./chef.py test semantic -ba
But we also developped a PDF export of the AST, to have a better insight of our work. It's available as a command line argument for Caramel:
# Generate the ast.pdf file
cd ./build/cpp-bin
./Caramel --ast-dot
- Phase 5.1
- Phase 5.2
- Phase 5.3
- Phase 5.4
- Phase 5.5
- Phase 5.6
- Phase 5.7
- Phase 5.8
- Phase 5.9
- Phase 5.10
- Phase 5.11
- Phase 5.12
- Phase 5.13
- Phase 5.14
- Phase 5.15
As for the semantic phase, we used Chef and Caramel:
# Run back-end tests
./chef.py test semantic -ba
# Generate the ir.pdf file
cd ./build/cpp-bin
./Caramel -c --ir-dot
- variable definition
- function definition
- array definition
- more than 6 args function call
- recursive function call
- operators priority
- complex nested expression (ex:
foo(1 || 4 & 2) || (1>2, 2<4, foo(97 & 8 || 7)) || (1==1 && 4>3)
) - if ... then ... else
- while block
- do while block
- for block
- real stack size (in prolog)
- break / return
- correct types handling (int8_t, int16_t -> int32_t)