I wanted to write a programming language interpreter. But first, I needed to come up with a toy programming language. Thus, Aetherflo.

The language is intentionally eccentric and inelegant—I wanted it to look different from popular languages, because I wanted to focus on writing the interpreter, not the syntax, and because I recognize that underneath the syntax, the heart of all programming languages are alike. In fact, I asked a friend unbiased with programming language experience to jot whatever came to his head on a piece of paper. With some tweaking, we arrived on what looked to be a feasible, yet ugly, syntax.

The purpose of Aetherflo is to stand as a minimal programming language interpreter, both for educational purposes and to use as a baseline for other interpreters. Despite having a very strange syntax, tweaking the language to use a completely different syntax would only involve changing the lexer and grammar, while the bulk of the interpreter could remain the same.

Try Aetherflo

To compile the interpreter and run a sample app:

git clone aetherflo
cd aetherflo
./floc < samples/sample.flo

The first line will compile the interpreter. The second will run the following sample aetherflo script:

def incx() = {

This will print the numbers from 1 to 100.

About the Language

The Aetherflo language supports:

  • Integer Variables
  • Integer Expressions (supporting standard arithmetic and boolean operators)
  • Conditionals
  • Printing variables to standard output
  • Functions/Recursion
  • Closures

To declare a variable, and/or assign the result of an expression to a variable named id, do:

{ expression } | : id

Each expression evaluates to an integer. Standard arithmetic is supported with the +, -, *, and / operators. In addition, boolean logic is supported with operators ==, !=, <, <=, >, and >=.

To define a procedure named id:

def id(arg1,arg2,...) { statements }

Procedures contain scope. All variables and procedures belong to the parent procedure’s (or global) scope when declared for the first time.

To invoke a procedure named id:


Note that procedures can be nested, and in this case, will close over all parent procedure’s in-scope variables or procedures.

To conditionally invoke one or more statements:

( expression ) ? ? ( statements )

Each conditional statement will evaluate the given expression, and conditionally execute the given sub-statement.

To print the value of an expression to standard output:

& expression