POP-2 Programmeertaal

De syntax van POP-2 lijkt op ALGOL en toewijzingen gebeuren in de infix-notatie, maar het evaluatieschema is diepgaand concatenative.

Voorbeeld van toewijzing:

  • In Pascal: foo := 123;
  • In POP-2: 123 -> foo;

De taal maakt expliciet gebruik van een operand-stack. Hierdoor kan de bovenstaande toewijzing worden geschreven als twee afzonderlijke instructies, waarbij de eerste een waarde op de stack plaatst en de tweede deze waarde consumeert: 123; -> foo;

De Interpreter en Compiler

De taal kan eenvoudig worden gecompileerd voor Uxn. De taal is zo elegant en compact dat een volledige compiler minder dan 800 regels code beslaat en in 2,5 KB geheugen past.

Op het eerste gezicht lijkt de taal enigszins op Pascal. Een statement begint met een trefwoord, gevolgd door expressies en wordt afgesloten met een puntkomma. De evaluatie bestaat uit het doorlopen van het programma, waarbij waarden op de stack worden geplaatst wanneer dat nodig is.

Voorbeeld van een functie:

function sum x y;
x + y;
end

sum(5,6) * 2;

Het is belangrijk om te onthouden dat alles wordt uitgevoerd door een stackmachine. Een functie die meerdere waarden teruggeeft, laat deze simpelweg op de stack achter zodat de volgende instructie ze kan gebruiken.

Commentaren

Het comment-statement blokkeert een stuk tekst tot aan de afsluitende puntkomma. Deze kunnen over meerdere regels verspreid zijn.

comment Dit is een commentaar,
deze kunnen over meerdere
regels lopen;

Variabelen (Vars)

Variabelen worden gealloceerd binnen het vars-statement. Deze kunnen elke gewenste lengte hebben. Standaard bestaat een variabele in een 16-bit systeem uit twee 8-bit cellen.

comment Dit zijn 3 variabelen: x, y en z;
vars x y z;

comment De variabele foo is 10 bytes lang;
vars foo:10;

Voorwaardelijke Logica (If/Then/Elseif/Else/Close)

Hoewel de structuur herkenbaar is, is het opvallend dat elke case een waarde op de stack duwt in plaats van een waarde terug te geven of een toewijzing te doen.

vars x;
4 -> x;

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

Resultaat: 2

Functies (Function/End)

Functies worden gedeclareerd op de typische ALGOL-wijze. Bij recursie blijven de argumenten op de stack staan.

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

factRec(5);

Lussen en Goto

Lussen worden geschreven met eenvoudige GOTO-instructies; er zijn geen iteratoren aanwezig.

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

Resultaat: 10

Invoer en Uitvoer (I/O)

Waar de originele implementatie de grote pijl (=>) zonder bestemming gebruikte, maakt deze implementatie gebruik van Varvara, waardoor er meerdere outputbestemmingen mogelijk zijn.

Voorbeeld: Om de ASCII-letter "H" naar de Console-poort (0x17, 0x18) te sturen: 0x48 => 23; (Output: H)

Arrays en Geheugen

Een variabele kan een reeks cellen bevatten, waarbij elke cel één byte is. De absolute positie van een referentie in het geheugen (een pointer) wordt benaderd met het #-prefix.

Voorbeeld: Om de waarde 0x0048 op te slaan in de derde en vierde cel van een array:

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

Accolades {} kunnen worden gebruikt om pointer-aritmetiek in te sluiten en de waarde op een locatie in het geheugen te laden. De grote pijl stuurt deze waarde vervolgens naar de Console-poort: {array+i} => 23;

Praktisch Voorbeeld: String Printing

Door de bovenstaande elementen te combineren, kan een functie worden gemaakt om strings te printen. In dit voorbeeld is 23 het poortnummer in Varvara.

comment Functie om één karakter te printen;
function putChar c;
c => 23;
end

comment Functie om een volledige string te printen;
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");