All Projects → fabrik42 → Writing_an_interpreter_in_elixir

fabrik42 / Writing_an_interpreter_in_elixir

Elixir implementation of an interpreter for the Monkey programming language

Programming Languages

elixir
2628 projects

Projects that are alternatives of or similar to Writing an interpreter in elixir

Hdbf
Hyper-Dimensional Brainfuck
Stars: ✭ 87 (-26.89%)
Mutual labels:  interpreter
Endbasic
BASIC environment with a REPL, a web interface, and RPi support written in Rust
Stars: ✭ 106 (-10.92%)
Mutual labels:  interpreter
Apple Juice Actionscript
Pure .NET 2.0 code Implementation of the ActionScript3 compiler and runtime. Can be used to run scripts in environments where "just-in-time compilation" is not possible
Stars: ✭ 112 (-5.88%)
Mutual labels:  interpreter
Feral
Feral programming language reference implementation
Stars: ✭ 89 (-25.21%)
Mutual labels:  interpreter
Root
The official repository for ROOT: analyzing, storing and visualizing big data, scientifically
Stars: ✭ 1,377 (+1057.14%)
Mutual labels:  interpreter
Swiftylisp
A minimal LISP implemented in Swift
Stars: ✭ 106 (-10.92%)
Mutual labels:  interpreter
Aceto
A programming language based on a 2D Hilbert curve grid
Stars: ✭ 83 (-30.25%)
Mutual labels:  interpreter
Cpi
Tiny c++ interpreter
Stars: ✭ 116 (-2.52%)
Mutual labels:  interpreter
Lispe
An implementation of a full fledged Lisp interpreter with Data Structure, Pattern Programming and High level Functions with Lazy Evaluation à la Haskell.
Stars: ✭ 105 (-11.76%)
Mutual labels:  interpreter
Quickjs
The official repo is at bellard/quickjs.
Stars: ✭ 1,429 (+1100.84%)
Mutual labels:  interpreter
Wasm Forth
A Forth implementation compiling to WebAssembly.
Stars: ✭ 92 (-22.69%)
Mutual labels:  interpreter
Sniprun
A neovim plugin to run lines/blocs of code (independently of the rest of the file), supporting multiples languages
Stars: ✭ 93 (-21.85%)
Mutual labels:  interpreter
Libforth
libforth: A small Forth interpreter that can be used as a library written in c99
Stars: ✭ 107 (-10.08%)
Mutual labels:  interpreter
Magpie
🐦 Successor of my monkey Interpreter(support for class, linq, sql, net, http, fmt, json and A realtime syntax highlighting REPL).
Stars: ✭ 88 (-26.05%)
Mutual labels:  interpreter
Brain
An esoteric programming language compiler on top of LLVM based on Brainfuck
Stars: ✭ 112 (-5.88%)
Mutual labels:  interpreter
Abrvalg
Python-like programming language interpreter written in Python
Stars: ✭ 83 (-30.25%)
Mutual labels:  interpreter
Angu
A small DSL/interpreter that can be used to evaluate simple expressions
Stars: ✭ 105 (-11.76%)
Mutual labels:  interpreter
Atto
An insanely simple self-hosted functional programming language
Stars: ✭ 119 (+0%)
Mutual labels:  interpreter
Pointless
Pointless: a scripting language for learning and fun
Stars: ✭ 116 (-2.52%)
Mutual labels:  interpreter
Dummylua Tutorial
这是一个仿制lua解释器的项目,我希望通过逐步实现lua解释器的各个部分,更加深刻地掌握lua的基本结构和运作原理。
Stars: ✭ 108 (-9.24%)
Mutual labels:  interpreter

Writing An Interpreter In Elixir

Build Status


Introduction

This project is an interpreter for the Monkey programming language, featuring its own lexer, AST producing parser and evaluator. The Monkey programming language as well as the structure of the interpreter are based on the book Writing An Interpreter In Go.

I really enjoyed reading this book and following the implementation of the interpreter in Go, because it was built using simple and straightforward patterns. You learn to build an interpreter completely by yourself, no generators, no external dependencies, just you and your code. :)

And even though - at first sight - an interpreter seems to be a big, hairy, complex machine, the author manages to implement a fully working version using easy to understand code.

Patterns like early returns, simple for-loops and small amounts of well encapsulated state are well known to most programmers and easy to reason about.

However, none of these things exist in Elixir and I was looking to get my hands dirty with this language. So I decided to implement the interpreter for Monkey in Elixir instead of Go, to see which other patterns can be applied to solve the problems with a more functional approach.

I know that there are way more sophisticated patterns in functional languages, like monads, but I wanted to solve this problem using only the standard lib of Elixir. First of all, because the reference implementation in Golang did the same and second, because I wanted to dive deeper into the standard lib.

It is important to keep in mind, that the whole basic structure of the interpreter is derived from the original Golang book. So maybe there are even better ways to lay out an interpreter in Elixir. If this is the case, let me know! :)

The code in this repository is the current state of this interpreter. It is fully functional, tested and I tried my best to implement it using Elixir best practices. There are still some rough edges and I think there is still a lot to learn for me, about Elixir and functional programming in general.

You are very welcome to walk through this code and if you spot something that could be done better, please let me know.

Monkey Language Features

A list of language features can be found here.

You should be able to try them all out in the REPL (see below).

Usage

This project only uses the stdlib of Elixir, so no mix deps.get is necessary.

Starting the REPL

There is a handy mix task to start a Monkey REPL so you can play around with the language.

mix repl

Running the tests

mix test

Notable changes to the original Golang implementation

Token

  • Does not use constants but atoms to specify a token type.

Lexer

  • Does not maintain state and is implemented using recursive function calls.

Parser

  • Prefix parse functions are defined using pattern matching in function calls instead of a lookup table with functions as values and extra nil handling.

Evaluator

  • As structs are immutable, the evaluator will not only output the evaluated result, but also the environment that was used to evaluate the code (defined variables).
  • As a consequence, the evaluator will also be called with an environment to work with, so it can resume working in the same environment (see REPL).

TODOs

  • Check code quality, Elixir ways of doing things
  • Add Typespecs and Dialyzer for static analysis
  • Try to remove TODOs aka nested conditions
  • Maybe more builtin functions
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].