snusp2c [1] is a slightly optimizing compiler from Modular SNUSP to C in Python.
SNUSP (SNUSP’s Not Unix, but a Structured Path) is a 2-dimensional esoteric language, a successor to Path, and a relative of Brainfuck. In SNUSP source code is a grid of characters, each being a command. The instruction pointer starts at the first column of the first row (or at the $ character location, if present) and travels to the right, executing each command.
The core SNUSP commands are:
> -- increase the current memory pointer by 1 cell;
< -- decrease the current memory pointer by 1 cell;
+ -- increment the current memory cell;
- -- decrement the current memory cell;
, -- read a byte from the input into the current memory cell;
. -- print a byte from the current memory cell onto the output;
\ -- mirror the instruction pointer direction between right-bottom and left-top;
/ -- mirror the instruction pointer direction between right-top and left-bottom;
! -- skip the next command;
? -- skip the next command if the current memory cell is zero.
Modular SNUSP adds two more commands:
@ -- save the current direction and instruction pointer on the call stack;
# -- restore direction and instruction pointer from the call stack and skip @.
All other characters are comments.
You can read more about SNUSP and its variants at [2] and [3].
The SNUSP specification leaves a number of corner cases underspecified; to clarify snusp2c behavior:
memory cells are 8-bit wide;
at the end of input , sets current memory cell to -1;
the program will halt if instruction pointer runs off the edge of code space, even if call stack is not empty;
the program will also halt if # is encountered while the call stack is empty.
Here’s a SNUSP program that echoes to stdout whatever it reads from stdin:
cat = !/,+?\#
\=.-/
snusp2c will compile it into this (or similar) code:
#include <stdio.h>
#include <stdlib.h>
#define LEFT(n) ptr -= n
#define RIGHT(n) ptr += n
#define INCR(n) mem[ptr] += n
#define DECR(n) mem[ptr] -= n
#define READ mem[ptr] = getc(stdin)
#define WRITE putc(mem[ptr], stdout)
#define ZERO (mem[ptr] == 0)
static unsigned char *mem;
static long ptr;
int main() {
mem = malloc(30000);
ptr = 0;
r_9_1:
READ;
INCR(1);
if (ZERO) goto r_13_1;
DECR(1);
WRITE;
goto r_9_1;
r_13_1:
return 0;
}