![[monkey.webp]]
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.
There is a book about learning how to make an interpreter: [Writing An Interpreter In Go](https://interpreterbook.com/#the-monkey-programming-language). This is where the Monkey programming language come from.
# Software model
The most important part of this project is that both the **lexer** and **parser** are made with the [Nom](https://github.com/Geal/nom) library. Then everything is built up into an **AST** for execution. It has several unit tests to ensure it doesn't break when I update the libraries or add new features.
# Examples of code you can run
```monkey
let map = fn(f, arr) {
if (len(arr) == 0) {
[]
} else {
let h = head(arr);
cons(f(h), map(f, tail(arr)));
}
};
let reduce = fn(f, init, arr) {
if (len(arr) == 0) {
init
} else {
let newInit = f(init, head(arr));
reduce(f, newInit, tail(arr));
}
};
let double = fn(x) {
2 * x
};
let add = fn(x, y) {
x + y
};
let mapped = map(double, [1, 2, 3, 4]);
print(mapped);
let sum = fn(arr) {
reduce(add, 0, arr);
};
let summed = sum([1, 2, 3, 4, 5]);
print(summed);
```
This is totally valid code and will run like so:
```bash
cargo run --release --bin monkey_exe -- --src examples/map-reduce.mk
Finished release [optimized] target(s) in 0.02s
Running `target/release/monkey_exe --src examples/map-reduce.mk`
[2, 4, 6, 8]
15
null
```
# How to run
## Build and test
```bash
$ cargo build
$ cargo test
```
## Running the REPL
```bash
$ cargo run --release --bin monkey_repl
```
## Running the Interpreter
```bash
$ cargo run --release --bin monkey_exe -- --src examples/hash.mk
```
# Source code
You can find it on my GitHub page related to the project: [here](https://github.com/Rydgel/monkey-rust).