The postfix drum automaton
An experimental programmable drum machine
Programming the machine
Language syntax
Each of the eight tracks is programmed using a custom stack-oriented programming language. The language operates over a Stack of numbers. A Stack is a data type which you can add to the top of ('push'), and remove from the top of ('pop').
To evaluate a program, the interpreter executes each word in the program in order:
- Numbers are pushed to the stack.
- Operations are executed and can pop zero or more numbers from the stack. The result of the operation is pushed to the stack.
returnstops the program executing.if <expression> thenonly executes<expression>if the number on top of the stack is non-zero.
An example [click to expand]
Given the initial stack [] and the program 1 2 +, the interpreter
would execute the following steps:
- Push 1 to the stack:
[1] - Push 2 to the stack:
[1, 2] - Execute the
+operation, which pops two numbers from the stack and pushes the sum:[3]
A more complicated example [click to expand]
Given the initial stack [] and the program 1 if 0 return then 2, the interpreter would execute the following steps:
- Push 1 to the stack:
[1] - Execute the
ifoperation, which pops the top number from the stack and checks if it is non-zero. Since it is, the interpreter runs the code up to thethenblock:0 return. This pushes 0 to the stack and exits:[0] - Since we've returned early, the code after the
thenblock is not executed, so 2 isn't pushed to the stack.
The drum machine
Internally, the drum machine has a clock, which increments 24 times per beat. The number of beats per minute (BPM) is configurable.
On each increment, each track's program is called, with the current clock value passed as the only item on the stack.
24 times per beat is too fast for most music, so the built in operations 4n and 8n, and 16n are provided, which return early unless the current clock
value is for a quarter note, eighth note, or sixteenth note. Most patterms will start with one
of these operations.
Built-in Operations
These operations are built into the interpreter itself.
| Op | Description |
|---|---|
+ | Adds two numbers |
- | Subtracts the number on the top of the stack from the number below it |
* | Multiplies two numbers |
/ | Divides the number on the top of the stack by the number below it |
= | Returns 1 if the two numbers are equal, 0 otherwise |
!= | Returns 1 if the two numbers are not equal, 0 otherwise |
< | Returns 1 if the number on the top of the stack is less than the number below it, 0 otherwise |
> | Returns 1 if the number on the top of the stack is greater than the number below it, 0 otherwise |
mod | Returns the remainder of the division of the number on the top of the stack by the number below it |
rnd | Returns a random number between 0 and 1 |
rrng | Returns a random number between the two numbers on the stack |
dup | Duplicates the number on the top of the stack |
swap | Swaps the two numbers on the stack |
drop | Removes the number on the top of the stack |
Custom Operations
These operations are defined in the language itself, and can be used in patterns. You can define your own.
| Name | Body | |
|---|---|---|
| 4n | dup 24 mod 1 != if drop 0 return then 1 - 24 / 1 + | |
| 8n | dup 12 mod 1 != if drop 0 return then 1 - 12 / 1 + | |
| 16n | dup 6 mod 1 != if drop 0 return then 1 - 6 / 1 + |