Camel is a dynamic scripting language. It is primarily meant as a toy project for learning interpreters and Rust programming language. The project is split into two main parts, the Camel Compiler (Cacom) and the Camel Bytecode interpreter (Caby).
The language is very simple, here is an example of calculating factorial:
def fact(x) = if x == 0 { x } else { x * fact(x - 1) };
print("{}\n", fact(10));
And here is another example of finding maximum value in list:
def max(lst) = {
var max = 0;
for x in lst {
if x > max {
max = x;
}
};
max
}
val lst = [1, 2, 5, 3, 1];
print("Max({}) = {}", lst, max(lst));
The language has C-like syntax but supports advanced constructs such as objects, lists, strings and so on. It basically aims to be similar to Python with more C-like syntax and stricter scoping rules.
Following features will hopefully be implemented:
- Fully interpolated strings
- Closures
- Dictionaries
- Sets
Following features are considered
- Exceptions.
The language is first compiled into an AST, from which a bytecode is generated. This step does the Cacom part of the project, which is an compiler from the Camel source code to bytecode. The compiler is written in Rust.
When the compilation is done, an interpreting takes place. This is a task for the bytecode interpreter, which is an Caby part of the project. The interpreter is written in C.
Bytecode can be serialized into byteformat, which is used as common speaking ground for compiler and interpreter. Compiler serializes data into this format, interpreter then deserializes it and interprets it.
The format can be found in Caby/README.md
.
The project is unfortunately split into two parts now. You can use the scripts/build.sh
script to build both of them.
Then you can run Cacom/target/release/cacom compile --input-file=<source-code>
followed by Caby/build/caby execute a.out
.
Both programs have help built into them.
You will need cargo, make, cmake and c compiler to build them.