Skip to content

Implementation of an interpreter for the monkE programming language in Go

Notifications You must be signed in to change notification settings

AtharvaThorve/monkE

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

monkE Interpreter & Compiler

This project is an implementation of an interpreter and compiler for the monkE programming language, inspired by the books "Writing an Interpreter in Go" and "Writing a Compiler in Go" by Thorsten Ball.

>> print("Hello World from monkE!!");
Hello World!!
null

Overview

monkE is a simple, dynamically-typed programming language. The interpreter is written in Go, and work is underway to convert it into a bytecode compiler and virtual machine.

The aim of the project was to learn core concepts of interpreters and compilers such as:

  • lexer
  • parser
  • abstract syntax tree
  • object system
  • evaluator
  • builtin functions
  • bytecode compilation
  • virtual machine execution

Note: The compiler implementation is in progress and currently supports a subset of the interpreter's features.

Table of Contents

Features

Interpreter Features

  • Lexer: Tokenizes the input source code.
  • Parser: Parses the tokens into an Abstract Syntax Tree (AST).
  • REPL: A Read-Eval-Print Loop for interactive programming.
  • Evaluator: Tree-walking evaluator for the AST.

Compiler Features (In Progress)

  • Bytecode Generation: Converts AST into bytecode instructions.
  • Virtual Machine: Executes the generated bytecode.
  • Code Optimization: Optimizes the generated bytecode (partial implementation).

Project Structure

  • ast/: Contains the Abstract Syntax Tree (AST) definitions.
  • lexer/: Contains the lexer implementation.
  • parser/: Contains the parser implementation.
  • repl/: Contains the REPL implementation.
  • token/: Contains token definitions.
  • compiler/: Contains the compiler implementation.
  • vm/: Contains the virtual machine implementation.
  • main.go: Entry point of the interpreter and compiler.

Getting Started

Prerequisites

  • Go 1.23.5 or higher

Installation

  1. Clone the repository:

    git clone https://github.com/yourusername/monkE.git
    cd monkE
  2. Build the project:

    go build
  3. Run the REPL:

    ./monkE

Usage

Once the REPL is running, you can start typing monkE code and see the results immediately.

Print

>> print("Hello World!!");
Hello World!!
null

Basic Arithmetic

>> 5 * 5 + 10
35
>> 3 + 4 * 5 == 3 * 1 + 4 * 5
true
>> 5 * 10 > 40 + 9
true
>> (10 + 2) * 30 == 300 + 20 * 3
true
>> (5 > 5 == true) != false                                                                                                                                                                  
false
>> 500 / 2 != 250
false

Conditional Statements

>> if (5 * 5 + 10 > 34) { 99 } else { 100 }
99
>> if ((1000 / 2) + 250 * 2 == 1000) { 9999 }
9999

Variable Declarations

>> let a = 5;
>> let b = a > 3;
>> let c = a * 99;
>> if (b) { 10 } else { 1 };
10
>> let d = if (c > a) { 99 } else { 100 };
>> d
99
>> d * c * a;
245025

Functions

>> let addTwo = fn(x) { x + 2; };
>> addTwo(2)
4
>> let multiply = fn(x, y) { x * y; };
>> multiply(50 / 2, 1 * 2);
50
>> fn(x) { x == 10 }(5)
false
>> fn(x) { x == 10 }(10) 
true
>> let newAdder = fn(x) { fn(y) { x + y } };
>> let addTwo = newAdder(2);
>> addTwo(3);
5
>> let addThree = newAdder(3);
>> addThree(10);
13

String Manipulation

>> let makeGreeter = fn(greeting) { fn(name) { greeting + " " + name + "!" } };
>> let hello = makeGreeter("Hello");
>> hello("Atharva");
Hello Atharva!
>> let heythere = makeGreeter("Hey there");
>> heythere("Atharva");
Hey there Atharva!

Built-in Functions

>> len("1234")
4
>> len("Hello World!")
12
>> len("Woooooohooo!", "len works!!")
ERROR: wrong number of arguments. got=2, want=1
>> len(12345)

Array Literals

>> [1,2,3,4]
[1, 2, 3, 4]
>> let double = fn(x) { x * 2 };
>> [1, double(2), 3 * 3, 4 - 3]
[1, 4, 9, 1]
>> let a = [1, 2 * 2, 10 - 5, 8 / 2];
>> a[0] 
1
>> a[1]
4
>> a[5-3]
5
>> a[99]
null

Array Builtins

>> let a = [1, 2, 3, 4]
>> first(a)
1
>> last(a)
4
>> rest(a)
[2, 3, 4]
>> rest(rest(a))
[3, 4]
>> rest(rest(rest(a)))
[4]
>> rest(rest(rest(rest(a))))
[]
>> rest(rest(rest(rest(rest(a)))))
null

Hash Literals

>> {"name": "Monkey", "age": 0, "type": "Language", "status": "awesome"}
{name: Monkey, age: 0, type: Language, status: awesome}
>> let people = [{"name": "Alice", "age": 24}, {"name": "Anna", "age": 28}];
>> people[0]["name"];
Alice
>> people[1]["age"]
28
>> people[1]["age"] + people[0]["age"]
52
>> let getName = fn(person) { person["name"]; };
>> getName(people[0]);
Alice
>> getName(people[1]);
Anna

Compiler Implementation

Current Status

The compiler implementation has made significant progress. Currently supported features include:

  • Arithmetic operations (addition, subtraction, multiplication, division)
  • Conditional statements (if/else expressions)
  • Variable declarations and variable access
  • String operations and concatenation
  • Array literals and index expressions
  • Hash map literals and access

Features still being worked on include:

  • Function closures with proper environment handling
  • Built-in functions within the VM context
  • Advanced optimizations

Bytecode Format

The compiler generates bytecode instructions that are executed by the virtual machine. The bytecode format is designed to be compact and efficient.

Virtual Machine

The virtual machine executes the bytecode generated by the compiler. It includes a stack-based execution model and supports basic operations such as arithmetic, variable access, and function calls.

License

This project is licensed under the MIT License.

Acknowledgements

  • Thorsten Ball for his excellent books "Writing an Interpreter in Go" and "Writing a Compiler in Go".

About

Implementation of an interpreter for the monkE programming language in Go

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages