PLZero (PL/0) Compiler
The compiler is almost done. The Nikluas Wirth Pascal has been recoded in C. The structure completely rebuilt. I don't even think Mr Wirth would recognise his code! I removed the tokeniser and interpreter from the compiler and are now stand alone programs (part of the tool train).
Here are a couple of working programs.
Multiplication:
const m=7, n = 85;
var print, x, y, z; { Assignment to print variable is printed }
procedure multiply;
var a, b;
begin
a := x; b := y; z := 0;
while b > 0 do
begin
if odd b then z := z + a;
a := 2 * a; b := b / 2;
end;
end;
begin
x := m;
y := n;
call multiply;
print:=z;
end.
Prime number search (http://www.dustyoldcomputers.com/pdp-8/software/pl0/):
{ calculate prime numbers }
const
pcmax = 101; { max on 8 is 2045 }
var
print, { memory mapped print routine memory location }
pc, { prime candidate }
d, { divisor }
t1, { temp #1 }
t2, { temp #2 }
isnot; { isnot a prime flag }
begin
print := 1;
print := 2;
pc := 3;
t1 := pc/2;
while pc <= pcmax do
begin
{ trial division to test for prime }
d := 3;
isnot := 0;
{ This keeps t1 >= to the sqrt(pc) }
if (t1*t1) < pc then t1 := t1 + 1;
while d <= t1 do
begin
t2 := pc / d;
if (t2*d) = pc then { not prime }
begin
isnot := 1; { remember not prime }
d := pc; { force loop exit because we don't have break }
end;
d := d + 2;
end;
if isnot = 0 then print := pc; { store at print will print it }
pc := pc + 2;
end;
end.
Wirth's test program:CONST
m = 7,
n = 85;
VAR
print, putc, x, y, z, q, r;
PROCEDURE multiply;
VAR a, b;
BEGIN
a := x;
b := y;
z := 0;
WHILE b > 0 DO BEGIN
IF ODD b THEN z := z + a;
a := 2 * a;
b := b / 2
END
END;
PROCEDURE divide;
VAR w;
BEGIN
r := x;
q := 0;
w := y;
WHILE w <= r DO w := 2 * w;
WHILE w > y DO BEGIN
q := 2 * q;
w := w / 2;
IF w <= r THEN BEGIN
r := r - w;
q := q + 1
END
END
END;
PROCEDURE gcd;
VAR f, g;
BEGIN
f := x;
g := y;
WHILE f # g DO BEGIN
IF f < g THEN g := g - f;
IF g < f THEN f := f - g
END;
z := f
END;
BEGIN
x := m;
y := n;
CALL multiply;
print:=z;
putc:=10;
x := 25;
y := 3;
CALL divide;
print:=q;
print:=r;
putc:=10;
x := 84;
y := 36;
CALL gcd;
print:=z
END.
I have edited the tokeniser to recognise:
- any case for token words (i.e. BEGIN, begin or Begin etc.) but variables are still case sensitive
- "var" and "int" as an alternative
- "<>", "!=", "#" as alternatives
- "print" (lower case) is recognised at any level as the integer output.
- "putc" (lower case) is recognised at any level as the char output.
I rather like the upper case for keywords.
Here is the result from Wirth's program:
Begin PL/0: 595 8 1 12 End PL/0.
I need a final check of the code, add a execution list option before moving on to the Subleq translator.
AlanX
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.