Post Reply 
HP-42S Compiler for Niklaus Wirth's PL/0 Language
01-14-2024, 04:01 PM
Post: #1
HP-42S Compiler for Niklaus Wirth's PL/0 Language
Introduction

Recently I stumbled upon the book Compilerbau by Niklaus Wirth.
A small language PL/0 is used to illustrate how to write an interpreter and a compiler.
For the compiler a stack-based machine is assumed.
Thus I wondered if an HP-calculator could be used as target.

There's a PL/0 Language Tools project but it appears to be abandoned.
The last commit on the GitHub repository was made 7 years ago.
It is still based on Python 2 which is now dead.

The Language PL/0

It is a simplified variant of Pascal with the following EBNF:
Code:
program =       block "." .
block =         ["CONST" ident "=" number {"," ident "=" number} ";"] 
                ["VAR" ident {"," ident} ";"]
                {"PROCEDURE" ident ";" block ";"} statement.
statement =     [ident ":=" expression | "CALL" ident |
                "?" ident | "!" expression |
                "BEGIN" statement {";" statement} "END" |
                "IF" condition "THEN" statement |
                "WHILE" condition "DO" statement] .
condition =     "ODD" expression |
                expression ("=" | "#" | "<" | "<=" | ">" | ">=") expression .
expression =    ["+" | "-"] term {("+" | "-") term} .
term =          factor {("*" | "/") factor} .
factor =        ident | number | "(" expression ")" .

Installation and Setup

Download Project

Download the ZIP-file and unzip it.

unzip pl0-compiler.zip

It should contain the following files:
Code:
Archive:  pl0-compiler.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
     3427  01-14-2024 14:50   pl0_lexer.py
    12754  01-14-2024 14:52   pl0_parser.py
     4393  01-14-2024 12:04   pl0_node_visitor.py
     5141  01-14-2024 14:48   pl0_interpreter.py
     6240  01-14-2024 14:52   pl0_compiler.py
     5860  01-14-2024 14:50   pl0_hp42s.py
      347  01-14-2024 13:53   examples/combination.pl0
      153  01-14-2024 11:05   examples/constants.pl0
      328  01-14-2024 11:05   examples/fibonacci.pl0
      232  01-14-2024 12:51   examples/gcd.pl0
      133  01-14-2024 15:07   examples/multiply.pl0
      265  01-14-2024 13:42   examples/permutation.pl0
      234  01-14-2024 11:05   examples/scope.pl0
      232  01-14-2024 11:05   examples/square.pl0
---------                     -------
    39739                     14 files

Setup the Virtual Environment

python3 -m venv venv
source venv/bin/activate
pip install --upgrade pip setuptools wheel
pip install ply


Programs

Some example programs can be found in the examples directory.

Fibonacci

Code:
# This program calculates the first K values of the fibonacci sequence.

CONST K = 20;

VAR m, n, k, count;

BEGIN
    m := 1;
    n := 1;
    k := 1;
    count := 0;
    
    WHILE count <= K DO
    BEGIN
        ! k;
        
        k := n;
        n := m + n;
        m := k;
        
        count := count + 1
    END
END.

Compile to HP-42S

The program pl0_hp42s.py is based on pl0_compiler.py and creates commands for the HP-42S:

python pl0_hp42s.py examples/fibonacci.pl0

Code:
GTO 00     # main
# Register 01: m
# Register 02: n
# Register 03: k
# Register 04: count
LBL 00     # main
1
STO 01     # m
1
STO 02     # n
1
STO 03     # k
0
STO 04     # count
LBL 01     # while loop
20
RCL 04     # count
X>Y?
GTO 02     # end while loop if true
RCL 03     # k
PROMPT
RCL 02     # n
STO 03     # k
RCL 01     # m
RCL 02     # n
+
STO 02     # n
RCL 03     # k
STO 01     # m
RCL 04     # count
1
+
STO 04     # count
GTO 01     # loop again
LBL 02     # end while loop
END        # main

Caveat

Input Output

For input and output use ? and !:

?n; ?k; CALL perm; !p


Syntax

The syntax for comparisons is slightly changed.
Instead of = for equal use ==.
Instead of # for not equal use !=.

Integer Division

It is assumed that the machine uses only integers.
Therefore division results in integers.
However I find it more useful to use the ordinary division on an HP-42S.
It is easy to include the IP command if that is needed.
Or then replace ÷ by BASE÷ in the code:
Code:
            elif term[0] == "DIVIDE":
                print("÷")

Recursion

Due to the limited size of the return stack of the HP-42S I assume that recursion doesn't really work.

Scope of Variables

The same variable name can be used local to a procedure but these are still mapped to global registers.
Cf. examples/scope.pl0


.zip  pl0-compiler.zip (Size: 14.87 KB / Downloads: 11)
Find all posts by this user
Quote this message in a reply
Post Reply 


Messages In This Thread
HP-42S Compiler for Niklaus Wirth's PL/0 Language - Thomas Klemm - 01-14-2024 04:01 PM



User(s) browsing this thread: 1 Guest(s)