XXIIVV

A few feral cats in an ALGOL trenchcoat.

The syntax of POP-2 is ALGOL-like, assignments are in the infix notation, but the evaluation scheme is deeply concatenative.

foo := 123; ( In Pascal )
123 -> foo; ( In POP-2 )

The language has the explicit notion of an operand stack. Thus, the prior assignment can be written as two separate statements where the first one leaves a value on the stack, and the second, consumes it:

123; -> foo;
Typical POP-2 Programmer

Interpreter

The language can easily be compiled for Uxn, in fact, the language is so elegant and small that an entire compiler is less than 800 lines and fits within 2.5kb of memory.

At first glance, the language looks a little like Pascal. A statement begins with a keyword, followed by expressions, terminated by a semi-colon. Evaluation consists of moving through the program leaving values on the stack as needed.

function sum x y;
	x + y;
end

sum(5,6) * 2;

But it's important to remember that everything is evaluated by a stack machine, a function returning multiple values, is merely leaving them on the stack for the next one to use.

Comment

The comment statement will block out a length of text until a terminating semi-colon.

comment This is a comment,
        these can span multiple lines;

Vars

Variables are allocated inside the vars statement, these can be of any length, by default in a 16-bit system, a variable is made of two 8-bit cells.

comment These are 3 variables x, y and z;
vars x y z;

comment The variable foo is 10 bytes long;
vars foo:10;

If/Then/Elseif/Else/Close

At first glance, the language looks awfully unsurprising, but notice how each case pushes a value on the stack instead of returning a value or doing an assignment:

vars x; 4 -> x;

if x > 4
	then 1;
elseif x = 4
	then 2;
else
	3;
close
2

Function/End

Functions are declared in the typical ALGOL fashion, recursion leaves the arguments on the stack:

function factRec n;
	if n = 0
		then 1;
	else
		n * factRec(n-1);
	close
end

factRec(5);

Goto

Loops are written with simple GOTOs, there are no iterators.

comment Loop for 10 times;
vars i;
loop:
	if i < 10
		then i + 1 -> i, goto loop;
	close
i;
10

I/O

While the original implementation used the big arrow(=>) without a destination, here the host system of this implementing is Varvara and so it can make use of multiple output destinations. The Console port number(0x17, 0x18) to output the ASCII letter "H":

0x48 => 23; Outputs: H

Arrays

A variable can hold a length of cells, each cell is a byte, the absolute position of a reference in memory(a pointer) is accessed with the # prefix. To store the short 0x0048 in the third and fourth cells of the array:

vars array:10 i; 2 -> i; 
0x48 -> (#array+i);

The curlies can enclose pointer arithmetic and load the value at a location in memory. The big arrow is sending it to the Console port.

{array+i} => 23;

Putting it all together, we can make a string printing function:

comment The 23 is a port number in Varvara;
function putChar c;
	c => 23;
end

function printString s;
	vars c:1 i; 0 -> i;
loop:
	{s+i} >> 8 -> c;
	if c
		then putChar(c), i + 1 -> i, goto loop
	close
end

printString("Hello World!\n");

incoming: oscean 2026