oOonoOo

A surprisingly convenient, moderately esoteric, programming language.

Adjectives that apply to this language (gotta use lots of buzzwords, right?):

Building Instructions

  1. Download and extract the latest oOonoOo.zip.
  2. Install SBCL. Note that in principle any implementation of Common Lisp should work (builds are tested working with ECL).
  3. Run sbcl --load build.lisp from the root directory of the project.
  4. (Optional) Move the resulting ooonooo to somewhere on your path (eg. /usr/local/bin on Linux).

Usage Instructions

Run the command with the form ooonooo [OPTIONS] [FILE].

Where OPTIONS are one of:

Where FILE is a path to the file you want to run. If file is not specified, the program runs in interactive mode, otherwise it runs in non-interactive mode.

In interactive mode the stack will start with a valid load command (you just have to Eval) which points to modules/basic-math.ooonooo.

In non-interactive mode the stack will start empty.

Language Description

A command is notated by the number of 0 characters there are on a single line (hence the unary). Any other characters are ignored (use them towards your advantage).

General Behavior

If there are 0 0 characters on a line, a NOP instruction is executed. It does nothing, but still counts as an instruction (important for function/macro).

If there are 1-9 0 characters on a line, special evaluation rules are applied (see Stack Operations for 2-5, Conditions for 6, Eval/Function/Macro for 1, 7-8, and Load for 9).

If there are more than 10 0 characters on a line, then the number of 0 characters -10 is pushed onto the stack.

Stack Operations

Used to manipulate the stack (when there are 2-5 0 characters on a line), they are:

# of 0s Action Rule
2 Drop Remove the last number added to the stack.
3 Duplicate Duplicate the last number added to the stack (and add it to the stack).
4 Swap Swap the positions of the last two numbers added to the stack.
5 Rotate Remove the third most recent number on the stack and add it to the stack.

Conditions

If there are 6 0 characters on a line, then the Branch operation is run. The Branch instruction consumes 3 values on the stack. Branch requires the following stack setup.

If the if part is nonzero, then all three values are dropped, and the then part is then added to the stack.

If the if part is zero, then all three values are dropped, and the else part is then added to the stack.

Eval/Function/Macro

If there is 1 0 character on a line, then the Eval instruction is run. Eval consumes the top element of the stack, finds the function at that location, and executes it.

If there are 7 0 characters on a line, then the Function instruction is run. Function declares some amount of oOonoOo code to be run when you call it. Function requires the following stack setup:

Note that if the last instruction in your function is Eval, the compiler will do tail call optimization.

If there are 8 0 characters on a line, then the Macro instruction is run. Macro declares common lisp code to be run upon it being called. Macro requires the following stack setup:

Load

If there are 9 0 characters on a line, then the Load instruction is run. Load requires the following stack setup:

Load evaluates a file with all locations shifted by the base offset specified (with one exception: 0-9 0 characters are evaluated as if there was a 0 offset). This allows for proper namespacing of functions/macros, and allows you to reuse low (small) addresses.

Strings

By convention strings are denoted by pushing each character code in reverse order followed by pushing the length of the string onto the stack.

Copyright/Licensing

All code files include an SPDX-License-Identifier describing which license it falls under.

In general: