Skip to content

Latest commit

 

History

History
180 lines (121 loc) · 3.28 KB

File metadata and controls

180 lines (121 loc) · 3.28 KB

The Monkey Language

This is a port of the Monkey interpreter from Writing An Interpreter In Go to TypeScript.

From monkeylang.org:

Monkey is a programming language that you can build yourself by reading through Writing An Interpreter In Go and Writing A Compiler In Go.

There is no official implementation of Monkey — it lives in these books and it's up to you, the reader, to implement it.

Data Types

Monkey supports integers, strings, and booleans:

let n = 1;
let word = "Hi";
let bool = true;

You can use these data types with basic arithmetic (+, -, /, *) and logical (==, !=, >, <, !) operators:

let n = ((1 + 1) * 5) / 2 - 4;
let bool = n > 5;
let greeting = "Hi" + " " + "there" + "!";

Monkey also supports arrays and hashes:

let array = ["a", 5, false];
let hash = { one: 1 };

Items in arrays in hashes can be accessed via the index operator:

["a", "b"][0]
{"c": true}["c"]

Expressions are allowed as both keys and values in hashes. Strings, integers, and booleans can be used as keys:

let key = "one"
let hash = {key: 1, 1 < 2: 2, "another": 2 * (5 + 10)}

You can define functions with the fn keyword:

let double = fn (x) { x * 2 }

The last value evaluated in a function's body is implicitly returned, but explicit returns are also allowed:

let implicitReturn = fn () { "implicit" }
let explicitReturn = fn () { return "explicit" }

Functions are first-class citizens and can be passed around as values to other functions. The following code returns 5:

let addOne = fn (x) { x + 1}
let doTwice = fn (x, func) { func(func(x)) }
doTwice(3, addOne)

Assigning Variables

let is used to assign a value to an identifier. Values are immutable, but different values can be re-bound to the same identifier.

The following code returns true:

let a = "text";
let a = true;
a;

Built-in Functions

Monkey supports a handful of built-in functions.

first

Returns the first element of an array. Returns null, if the array is empty.

The following code returns 1:

let myArray = [1, 2, 3];
first(myArray);

last

Returns the last element of an array. Returns null, if the array is empty.

The following code returns 3:

let myArray = [1, 2, 3];
last(myArray);

len

Returns the length of an array or string.

The following code returns 5:

len("hello");

rest

Returns all items in an array except for the first item.

The following code returns [2, 3]:

rest([1, 2, 3]);

push

Returns a new array with the given value pushed the end of the input array.

The following code returns [1, 2, 3]:

push([1, 2], 3);

puts

Logs each item on a new line and returns null.

puts("hi");
puts(1, true, "more than one arg");

Control Flow

Monkey supports if/else statements for control flow:

if (1 < 2) {
  "yep";
} else {
  "nope";
}

else is optional:

if (1 < 2) {
  return "yep";
}

return "nope";

Other Notes on Syntax

Semicolons are optional:

let a = "This is a valid let statement";
let b = "This is also a valid let statement";