Close

PLZero Compiler

A project log for Simple Compiler

A very simple compiler for minimalist home brew CPUs

agpcooperagp.cooper 07/13/2017 at 16:120 Comments

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:

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