A Lexer, Parser, Interpreter, VM and compiler library built with swift, supporting the addition of new languages and currently implemented for the Monkey Language.
With this project I want to get a better understanding on how compilers and interpreters works, while also have fun in the process 😎🤓. For that purpose I'll be following this book series:
What I like about this two books is that requires no third party or existing libraries it takes you through the entire process of making the interpreter and the compiler. The result might not be a production ready software but will accomplish what I'm looking for which is to learn how they work internally without any black box magic.
The book uses a language called Monkey designed for the book. From the book page the language is described as follows:
Monkey has a C-like syntax, supports variable bindings, prefix and infix operators, has first-class and higher-order functions, can handle closures with ease and has integers, booleans, arrays and hashes built-in.
The book uses Go Lang for the implementation but I want to do it in swift just because I like swift ❤️. For starters I will be using an XCode to compile and test my implementation, later on I'll try to implement a standalone compilation. As in the book this implementation will not use third party libs only standard swift libraries. Maybe I'll include a lib to simplify the CLI implementation but nothing else.
After cloning this repo run
./scripts/install-hooks.sh to configure git hooks. This will ensure documentation
is update on each commit and will prevent broken tests and lint errors to be pushed in the repo.
Documentation can be found here
Download the latest release binaries or compile using
swift build -c release and include the
monkey binary in your path. Then execute:
## To start the interactive REPL console. By default will use ## interpreter mode $ monkey ## To start the interactive REPL console using compiled ## mode $ monkey -m compiler ### To evaluate a file containing Monkey code $ monkey filename.mk -m interpreter ### To compile a file containing Monkey code $ monkey filename.mk -m compiler ### This option will also compile a file by default $ monkey filename.mk ### To run a Monkey binary file containing $ monkey filename.mkc ### To dump a Monkey binary file bytecode $ monkey filename.mkc -d
While using the REPL:
ctrl+cto close the session
ctrl+cto clean the screen
Besides the language features include in the books, I have added the following by my own:
Floats are now supported with the same operation as integers. When an expression uses both float and integer value the resulting value will be a float.
Support of scape characters inside string literals, currently supported values are:
\n = line break \t = tabulation \" = Double quote character inside a string \\ = Back slash character
Any other value will produce an error
Comparison of String values with any other value.
trueif it is not empty
falseif it is empty
Support of declaration constants using
let <identifier> = <expression>;
and variables using
var <identifier> = <expression>;.
Variables can later be assigned to new values but the value must be the same type for example the following lines will produce an error:
var a = 10; a = true;
Support for single line and multiline comments using
let a = 42; // Meaning of life /* Well it actually is: """ Answer to the Ultimate Question of Life, the Universe, and Everything """ */ puts(a);
Initially, I named the project "Rosetta" thinking about the archeological artifact associated with language translation and interpretation, the name made sense however I completely forgot about Apple's Rosetta, only after a couple of days working on the repo the name clicked in my mind. To avoid the confusion the name can generate I have switched to the name "Hermes" after the greek god associated with language.
I'll remove all references to previous name, but I might miss a couple, please forgive me.