# Pictogenesis: Stack Transpiling

Much like transpiling register machines, now we have a chance to transpile stack machines. Unfortunately, it doesn’t actually speed up the code nearly so much (the stack is just not as effective of a memory structure in this case), but it’s still an interesting bit of code.

In this case, we turn something like this:

invsub
polT
writeG
id
neg
zero?
sin
invsub
ZERO
inv

Into this:

function(X, Y) {
this.x = X;
this.y = Y;

this.stack = [];
this.r = undefined;
this.g = undefined;
this.b = undefined;

this.stack.push(X);
this.stack.push(Y);

var arg0 = 0;
var arg1 = 0;
var arg2 = 0;
var result = 0;

// invsub
arg0 = this.stack.pop() || 0;
result = 1 - arg0;
result = result % 1.0;
this.stack.push(result);

// polT
arg0 = this.stack.pop() || 0;
arg1 = this.stack.pop() || 0;
result = Math.atan2(arg0, arg1);
result = result % 1.0;
this.stack.push(result);

// writeG
arg0 = this.stack.pop() || 0;
this.g = arg0;

// id
arg0 = this.stack.pop() || 0;
result = arg0;
result = result % 1.0;
this.stack.push(result);

// neg
arg0 = this.stack.pop() || 0;
result = -arg0;
result = result % 1.0;
this.stack.push(result);

// zero?
arg0 = this.stack.pop() || 0;
arg1 = this.stack.pop() || 0;
arg2 = this.stack.pop() || 0;
result = arg0 === 0 ? arg1 : arg2;
result = result % 1.0;
this.stack.push(result);

// sin
arg0 = this.stack.pop() || 0;
result = Math.sin(arg0);
result = result % 1.0;
this.stack.push(result);

// invsub
arg0 = this.stack.pop() || 0;
result = 1 - arg0;
result = result % 1.0;
this.stack.push(result);

// ZERO
result = 0;
result = result % 1.0;
this.stack.push(result);

// inv
arg0 = this.stack.pop() || 0;
result = 1 / arg0;
result = result % 1.0;
this.stack.push(result);

return [
this.r === undefined ? this.stack.pop() || 0 : this.r,
this.g === undefined ? this.stack.pop() || 0 : this.g,
this.b === undefined ? this.stack.pop() || 0 : this.b,
];
}


# Pictogenesis: Stack Machine

Okay, enough with register machines. Let’s make something new. This time, a stack based machine!

Rather than keeping it’s memory in a series of memory cells, there will be a single stack of values. All functions can pop values from the top of the stack or push them back on. I will add the ability to read the X/Y value and directly write R/G/B, but you can’t write to the former or read from the latter, so you can’t use them as registers. Let’s see what that looks like!

# Pictogenesis: Transpiling

Okay. That is slow… Let’s make it faster!

So the main problem we have is that we’re interpreting the code. For every single pixel, for every line of code, we’re doing a few housekeeping things and making at least one function call. For a 400x400 image with just 10 lines of code, that’s 1.6M function calls. Like I said, slow.

So let’s make it faster!

My first idea? Transpile it to Javascript!

# Pictogenesis: Wrapping Modes

Now that I’ve got register machines working, one of the next ideas I had was to implement different wrapping modes. Currently, as it stands, X and Y are passed into the machine as floating point numbers from [0, 1] across the image and output is expected to be [0, 1] for each of R, G, and B. Any values that end up outside of that range, we truncate down to that range. But some of our mathematical functions (multiplication, exponentiation, negation, etc) tend to generate numbers way out of this range. But they don’t have to!

# Pictogenesis: Register Machine

Okay. First Pictogeneis machine: a register based machine. Today we’re going to create a very small language with a small number of registers that can read from the outside world, write colors, and act as temporary variables.

Something like this:

gt? t0 b y x r
abs b x
inv t0 g
sub t0 b r
mul x r b
abs y x

In each case, the first argument is the output and the rest are inputs. So:

# gt? t0 b y x r
if (b > y) {
t0 = x;
} else {
t0 = r;
}

g = y + x

# abs b x
b = |x|
...


Where x and y are the input point x and y mapped to the range [0, 1]; r, g, b are the output colors in the same range and t{n} are temporary registers just used during the program.