Skip to content

Monkey programming language interpreter designed in "Writing An Interpreter In Go".

License

Notifications You must be signed in to change notification settings

skatsuta/monkey-interpreter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

92 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Monkey interpreter

wercker status Go Report Card GoDoc

Monkey programming language interpreter designed in Writing An Interpreter In Go.

Usage

Install the Monkey interpreter using go get:

$ go get -v -u github.com/skatsuta/monkey-interpreter/...

Then run REPL:

$ $GOPATH/bin/monkey-interpreter
This is the Monkey programming language!
Feel free to type in commands
>> 

Or run a Monkey script file (for example script.monkey file):

$ $GOPATH/bin/monkey-interpreter script.monkey

Getting started with Monkey

Variable bindings and number types

You can define variables using let keyword. Supported number types are integers and floating-point numbers.

>> let a = 1;
>> a
1
>> let b = 0.5;
>> b
0.5

Arithmetic expressions

You can do usual arithmetic operations against numbers, such as +, -, * and /.

>> let a = 10;
>> let b = a * 2;
>> (a + b) / 2 - 3;
12
>> let c = 2.5;
>> b + c
22.5

If expressions

You can use if and else keywords for conditional expressions. The last value in an executed block are returned from the expression.

>> let a = 10;
>> let b = a * 2;
>> let c = if (b > a) { 99 } else { 100 };
>> c
99

Functions and closures

You can define functions using fn keyword. All functions are closures in Monkey and you must use let along with fn to bind a closure to a variable. Closures enclose an environment where they are defined, and are evaluated in the environment when called. The last value in an executed function body are returned as a return value.

>> let multiply = fn(x, y) { x * y };
>> multiply(50 / 2, 1 * 2)
50
>> fn(x) { x + 10 }(10)
20
>> let newAdder = fn(x) { fn(y) { x + y }; };
>> let addTwo = newAdder(2);
>> addTwo(3);
5
>> let sub = fn(a, b) { a - b };
>> let applyFunc = fn(a, b, func) { func(a, b) };
>> applyFunc(10, 2, sub);
8

Strings

You can build strings using a pair of double quotes "". Strings are immutable values just like numbers. You can concatenate strings with + operator.

>> let makeGreeter = fn(greeting) { fn(name) { greeting + " " + name + "!" } };
>> let hello = makeGreeter("Hello");
>> hello("John");
Hello John!

Arrays

You can build arrays using square brackets []. Arrays can contain any type of values, such as integers, strings, even arrays and functions (closures). To get an element at an index from an array, use array[index] syntax.

>> let myArray = ["Thorsten", "Ball", 28, fn(x) { x * x }];
>> myArray[0]
Thorsten
>> myArray[4 - 2]
28
>> myArray[3](2);
4

Hash tables

You can build hash tables using curly brackets {}. Hash literals are {key1: value1, key2: value2, ...}. You can use numbers, strings and booleans as keys, and any type of objects as values. To get a value of a key from a hash table, use hash[key] syntax.

>> let myHash = {"name": "Jimmy", "age": 72, true: "yes, a boolean", 99: "correct, an integer"};
>> myHash["name"]
Jimmy
>> myHash["age"]
72
>> myHash[true]
yes, a boolean
>> myHash[99]
correct, an integer

Built-in functions

There are many built-in functions in Monkey, for example len(), first() and last(). Special function, quote, returns an unevaluated code block (think it as an AST). Opposite function to quote, unquote, evaluates code inside quote.

>> len("hello");
5
>> len("");
3
>> let myArray = ["one", "two", "three"];
>> len(myArray)
3
>> first(myArray)
one
>> rest(myArray)
[two, three]
>> last(myArray)
three
>> push(myArray, "four")
[one, two, three, four]
>> puts("Hello World")
Hello World
nil
>> quote(2 + 2)
Quote((2 + 2)) # Unevaluated code
>> quote(unquote(1 + 2))
Quote(3)

Macros

You can define macros using macro keyword. Note that macro definitions must return Quote objects generated from quote function.

# Define `unless` macro which does the opposite to `if`
>> let unless = macro(condition, consequence, alternative) {
     quote(
       if (!(unquote(condition))) {
         unquote(consequence);
       } else {
         unquote(alternative);
       }
     );
   };
>> unless(10 > 5, puts("not greater"), puts("greater"));
greater
nil

About

Monkey programming language interpreter designed in "Writing An Interpreter In Go".

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages