This is my implementation of the Monkey programming language, implemented in Rust. The language, as well as the interpreter and compiler were described by Thorsten Ball @mrnugget in his book "Writing an Interpreter in Go" and his book "Writing a Compiler in Go".
Monkey consists of the following elements:
// Basic datatypes:
>> 42; // Integers
42
>> false; // Booleans
false
>> "this is a string"; // Strings
this is a string
// Operators:
// On integers:
>> 1 + 2;
3
>> 1 - 2;
-1
>> 1 * 2;
2
>> 1 / 2; //Integer devision!
0
>> !5;
false
>> 1 == 1;
true
>> 1 != 1;
false
>> 1 < 1;
false
>> 2 > 1;
true
>> 1 <= 1; // not specified by Thorsten Ball, but implemented here
true
>> 2 >= 3; // not specified by Thorsten Ball, but implemented here
false
// On Booleans
>> !true;
false
>> true == false;
false
>> true != false;
true
// On Strings
>> "Foo" + "bar";
Foobar
// Binding a value to an identifier:
>> let a = 42; // let <identifier> = <expression>;
>> a;
42
// Functions:
>> fn(x) { x + 1; } // fn(<identifiers, comma separated>) { <statements, semicolon separated> }
>> let add = fn(a,b) { a+b;};
>> add(1,2); // <function>(<expressions, comma separated>)
3
// Arrays
>> let a = [1,2, "three"]; // [<expressions, comma separated>]
>> a;
[1, 2, "three"]
>> a[0]; // <array>[<expression>]
1
// Hashes
>> let h = {"a": 1, true: false, 2: "two"}; // {<<expression>:<expression>, comma separated>}
>> h["a"];
1
// Builtin functions
>> len([1,2,3]);
3
>> len("three");
5
>> first([1,2,3]);
1
>> last([1,2,3]);
3
>> rest([1,2,3]);
[2,3]
>> puts("Hello World!", 1, true);
// Prints:
// Hello World!
// 1
// true
// Conditionals
>> if (1 > 2) { "Foo"; } else { "Bar" }; // if (<expression, which evaluates truthy>) {<statemens, semiclon separated>} [else {<statements, semicolon separated>}]
Bar
>> if (true) { return 5; "I'm lonely!";} // return early from within block statements (function or conditional)
5
Simply clone this repo and execute it using cargo:
cargo run
Or build and execute the binary
cargo build --release
./target/release/monkey-rs
You will start in an interactive shell, ready to interpret some Monkey code!
To use the compiler and vm to execute Monkey code, add the -c
or --compile
flag.
Executing Monkey-rs, you can also specify a file (using either the -f or --file flag), which contains Monkey code.
The file is then lexed, parsed and evaluated.
Output is only generated by calls to puts(...)
inside your Monkey code.
cargo run -- -f ./examples/hello_world.mky
cargo build --release
./target/release/monkey-rs -f ./examples/hello_world.mky