Plov006 : get some code generated
After some idle time I had gained enough mental rest again to do some more work on PLOV. I decided to spend one higher version number on it: Plov006 was born. It's main addition: code generation. in PALO format. Here is the source:
MODULE Plov006;
(* Plov is the PL/0 compiler as modified by Verhoeven *)
(* Ver Comment : Date *)
(* ----- ----------------------------------------------------- ------------ *)
(* 0.01 First version: read symbols and store them in a list 01 Oct 2007 *)
(* 0.02 Introduce a limited symbol processor; aborted 02 Oct 2007 *)
(* 0.03 Introduce a recursive descent parser 06 Oct 2007 *)
(* 0.04 Fine tune the parser 18 Oct 2007 *)
(* 0.05 Adapt it for file IO and command line 26 Nov 2007 *)
(* 0.06 Try some code generation *)
IMPORT ASCII, InOut, MemPools, NumConv, Strings, SYSTEM, TextIO, Arguments;
TYPE Identifier = ARRAY [0..31] OF CHAR;
Opcode = ARRAY [0..7] OF CHAR;
SymbolType = (Progtype, Proctype, Constype, Vartype, Keytype);
SymbolPtr = POINTER TO SymbolNode;
SymbolNode = RECORD
Name : Identifier;
previous,
next : SymbolPtr;
type : SymbolType;
value,
address : CARDINAL
END;
VAR token, op : Identifier;
InProcedure,
LineEnd,
Exhausted : BOOLEAN;
Symbols : MemPools.MemPool;
firstSymbol,
lastSymbol,
thisSymbol : SymbolPtr;
currentType : SymbolType;
LOOPcount, IFcount,
LabelCount,
LOOPdepth, PROCdepth,
currentValue : CARDINAL;
inFile, outFile : TextIO.File;
buffer : Arguments.ArgTable;
EXITcount : ARRAY [0..25] OF CARDINAL;
PROCEDURE ErrorMessage (n : CARDINAL);
BEGIN
CASE n OF
0 : InOut.WriteString ("Error filling Symbol table") |
1 : InOut.WriteString ("Invalid digit in : ");
InOut.WriteString (token) |
2 : InOut.WriteString ("Invalid letter in : ");
InOut.WriteString (token) |
3 : InOut.WriteString ("Program names do not match.") |
4 : InOut.WriteString ("BEGIN expected") |
5 : InOut.WriteString ("Illegal identifier name : ");
InOut.WriteString (token) |
6 : InOut.WriteString ("Duplicate identifier : ");
InOut.WriteString (token) |
7 : InOut.WriteString ("'=' expected") |
8 : InOut.WriteString ("END expected") |
9 : InOut.WriteString ("Undefined symbol : ");
InOut.WriteString (token) |
10 : InOut.WriteString ("Error in StatementSequence") |
11 : InOut.WriteString ("EXIT without LOOP") |
12 : InOut.WriteString ("THEN expected") |
13 : InOut.WriteString ("Illegal comparator : ");
InOut.WriteString (token) |
14 : InOut.WriteString ("Illegal operator in factor : ");
InOut.WriteString (token) |
15 : InOut.WriteString ("Error in factor : ");
InOut.WriteString (token) |
16 : InOut.WriteString ("Missing right parenthesis") |
17 : InOut.WriteString ("Missing assigment operator") |
18 : InOut.WriteString ("PROGRAM expected") |
19 : InOut.WriteString ("Procedure names do not match.") |
20 : InOut.WriteString ("Error converting numer.") |
33 : InOut.WriteString ("Syntax : Plov infile") |
34 : InOut.WriteString ("Cannot open file '");
InOut.WriteString (buffer^[1]^); InOut.Write ("'")
ELSE
InOut.WriteString ("Unknown error detected.")
END;
InOut.WriteLn;
InOut.WriteBf
END ErrorMessage;
PROCEDURE StoreSymbol (str : Identifier) : BOOLEAN;
VAR thisOne, nextOne : SymbolPtr;
BEGIN
thisOne := firstSymbol;
LOOP
IF Strings.StrEq (thisOne^.Name, str) THEN RETURN FALSE END;
IF thisOne^.next = NIL THEN EXIT END;
thisOne := thisOne^.next
END;
MemPools.PoolAllocate (Symbols, nextOne, SYSTEM.TSIZE (SymbolNode));
thisOne^.next := nextOne;
WITH nextOne^ DO
Name := str;
type := currentType;
next := NIL;
previous := thisOne
END;
lastSymbol := nextOne;
thisSymbol := nextOne;
RETURN TRUE
END StoreSymbol;
PROCEDURE FindSymbol (str : Identifier) : BOOLEAN;
VAR thisOne, nextOne : SymbolPtr;
BEGIN
thisOne := firstSymbol;
LOOP
IF Strings.StrEq (thisOne^.Name, str) THEN
thisSymbol := thisOne;
RETURN TRUE
END;
IF thisOne^.next = NIL THEN EXIT END;
thisOne := thisOne^.next
END;
RETURN FALSE
END FindSymbol;
PROCEDURE InsertLabel;
VAR ok : BOOLEAN;
string : Identifier;
BEGIN
NumConv.Num2Str (LabelCount, 10, string, ok);
IF NOT ok THEN ErrorMessage (20) END;
CG ("LABEL-");
CG (string); CG ("");
INC (LabelCount)
END InsertLabel;
PROCEDURE CG (string : ARRAY OF CHAR);
BEGIN
IF Strings.Length (string) = 0 THEN
TextIO.PutLn (outFile)
ELSE
TextIO.PutString (outFile, string)
END
END CG;
PROCEDURE PrintNames;
VAR thisOne : SymbolPtr;
BEGIN
thisOne := firstSymbol;
InOut.WriteLn;
LOOP
InOut.WriteString (thisOne^.Name); InOut.Write (11C);
CASE thisOne^.type OF
Progtype : InOut.WriteString ("Program type") |
Proctype : InOut.WriteString ("Procedure type") |
Constype : InOut.WriteString ("Constant type = ");
InOut.WriteCard (thisOne^.value, 5) |
Vartype : InOut.WriteString ("Variable type") |
Keytype : InOut.WriteString ("Keyword type")
END;
InOut.WriteLn;
IF thisOne^.next = NIL THEN
EXIT
ELSE
thisOne := thisOne^.next
END
END
END PrintNames;
PROCEDURE ReadString (str : Identifier);
VAR n, m : CARDINAL;
BEGIN
TextIO.GetString (inFile, str)
END ReadString;
PROCEDURE GetSymbol;
BEGIN
IF TextIO.EOF (inFile) = FALSE THEN
TextIO.GetString (inFile, token)
ELSE
InOut.WriteString ("EOF!!! ");
END;
InOut.WriteString (token); InOut.Write (11C); InOut.WriteBf
END GetSymbol;
PROCEDURE isDigit (chr : CHAR) : BOOLEAN;
BEGIN
IF (chr >= '0') AND (chr <= '9') THEN
RETURN TRUE
END;
RETURN FALSE
END isDigit;
PROCEDURE isAlpha (chr : CHAR) : BOOLEAN;
BEGIN
chr := CAP (chr);
IF (chr >= 'A') AND (chr <= 'Z') THEN
RETURN TRUE
END;
RETURN FALSE
END isAlpha;
PROCEDURE isAlphaNum (chr : CHAR) : BOOLEAN;
BEGIN
RETURN isAlpha (chr) OR isDigit (chr)
END isAlphaNum;
PROCEDURE isNumber (str : Identifier) : BOOLEAN;
VAR i : CARDINAL;
BEGIN
i := 0;
REPEAT
IF isDigit (str [i]) = FALSE THEN RETURN FALSE END;
INC (i)
UNTIL (str [i] = 0C) OR (i > HIGH (str));
RETURN TRUE
END isNumber;
PROCEDURE isIdentifier (str : Identifier) : BOOLEAN;
VAR i : CARDINAL;
BEGIN
IF NOT isAlpha (str [0]) THEN RETURN FALSE END;
IF Strings.Length (str) = 1 THEN RETURN TRUE END;
i := 1;
REPEAT
IF NOT isAlphaNum (str [i]) THEN RETURN FALSE END;
INC (i)
UNTIL (str [i] = 0C) OR (i > HIGH (str));
RETURN TRUE
END isIdentifier;
PROCEDURE Program;
BEGIN
GetSymbol;
IF Strings.StrEq (token, "PROGRAM") THEN
GetSymbol;
IF isIdentifier (token) THEN
WITH firstSymbol^ DO
Name := token;
type := Progtype
END;
CG ("# PROGRAM "); CG (token); CG (""); CG ("");
Block;
IF Strings.StrEq (token, firstSymbol^.Name) = FALSE THEN
ErrorMessage (3)
END;
CG ("# Done #"); CG ("");
ELSE
ErrorMessage (5) (* Illegal identifier *)
END
ELSE
ErrorMessage (18) (* 'PROGRAM' expected *)
END
END Program;
PROCEDURE Block;
BEGIN
GetSymbol;
IF Strings.StrEq (token, "CONSTANTS") THEN ConstantDeclaration; END;
IF Strings.StrEq (token, "VARIABLES") THEN
VariableDeclaration;
CG ("")
END;
WHILE Strings.StrEq (token, "PROCEDURE") DO
ProcedureDeclaration;
CG ("")
END;
BlockBody;
END Block;
PROCEDURE BlockBody;
BEGIN
IF Strings.StrEq (token, "BEGIN") THEN
IF PROCdepth = 0 THEN
CG ("LABEL MAINLOOP"); CG ("")
END;
GetSymbol;
StatementSequence
ELSE
ErrorMessage (4) (* BEGIN expected *)
END;
IF Strings.StrEq (token, "END") THEN
IF PROCdepth = 0 THEN
CG ("LABEL EXITMAINLOOP"); CG ("")
END;
GetSymbol;
RETURN
ELSE
ErrorMessage (8); (* END expected *)
GetSymbol
END
END BlockBody;
PROCEDURE StatementSequence;
BEGIN
LOOP
CG ("");
IF FindSymbol (token) = TRUE THEN
IF (thisSymbol^.type = Vartype) THEN Assignment
ELSIF thisSymbol^.type = Proctype THEN Procedurecall
ELSIF Strings.StrEq (token, "IF") THEN isIF
ELSIF Strings.StrEq (token, "LOOP") THEN isLOOP
ELSIF Strings.StrEq (token, "RETURN") THEN isRETURN
ELSIF Strings.StrEq (token, "EXIT") THEN isEXIT
ELSIF Strings.StrEq (token, "END") THEN
RETURN
ELSE
ErrorMessage (10); (* Error in StatementSequence *)
END
ELSE
ErrorMessage (9); (* Undefined symbol *)
END;
END;
END StatementSequence;
PROCEDURE ConstantDeclaration;
VAR Val : CARDINAL;
ok : BOOLEAN;
BEGIN
GetSymbol;
REPEAT
currentType := Constype;
IF isIdentifier (token) THEN
IF StoreSymbol (token) = TRUE THEN
GetSymbol;
IF token [0] = '=' THEN
GetSymbol;
NumConv.Str2Num (Val, 10, token, ok);
IF ok THEN
WITH thisSymbol^ DO
value := Val;
type := Constype
END;
ELSE
ErrorMessage (1) (* Invalid digit *)
END
ELSE
ErrorMessage (7); (* '=' expected *)
END
ELSE
ErrorMessage (6); (* Duplicate identifier *)
END
ELSE
ErrorMessage (5); (* Illegal Identifier *)
END;
GetSymbol
UNTIL Strings.StrEq (token, "END");
GetSymbol
END ConstantDeclaration;
PROCEDURE VariableDeclaration;
BEGIN
GetSymbol;
REPEAT
currentType := Vartype;
IF isIdentifier (token) THEN
IF StoreSymbol (token) = FALSE THEN
ErrorMessage (6) (* Duplicate identifier *)
END
ELSE
ErrorMessage (5); (* Illegal Identifier *)
END;
CG ("VARIABLE "); CG (token); CG ("");
GetSymbol
UNTIL Strings.StrEq (token, "END");
GetSymbol
END VariableDeclaration;
PROCEDURE ProcedureDeclaration;
VAR thisP : SymbolPtr;
name : Identifier;
BEGIN
GetSymbol;
currentType := Proctype;
IF isIdentifier (token) THEN
name := token;
CG ("LABEL ");
CG (name); CG ("");
IF StoreSymbol (token) = TRUE THEN
thisP := thisSymbol;
INC (PROCdepth);
GetSymbol;
BlockBody;
DEC (PROCdepth);
IF Strings.StrEq (thisP^.Name, token) = FALSE THEN
ErrorMessage (19) (* Names do not match *)
END;
GetSymbol
ELSE
ErrorMessage (6) (* Duplicate identifier *)
END
ELSE
ErrorMessage (5) (* Illegal identifier *)
END;
CG ("LABEL EXIT");
CG (name); CG (""); CG ("");
END ProcedureDeclaration;
PROCEDURE Procedurecall;
BEGIN
CG ("CALL "); CG (token); CG ("");
GetSymbol
END Procedurecall;
PROCEDURE isLOOP;
VAR LC : CARDINAL;
BEGIN
INC (LOOPcount);
LC := LOOPcount;
CG ("LABEL LOOP-"); TextIO.PutCard (outFile, LC, 1);
CG ("");
INC (LOOPdepth);
EXITcount [LOOPdepth] := LOOPcount;
GetSymbol;
StatementSequence;
IF Strings.StrEq (token, "END") THEN
DEC (LOOPdepth);
CG ("JUMP TO LOOP-"); TextIO.PutCard (outFile, LC, 1);
CG ("")
ELSE
ErrorMessage (8) (* END expected *)
END;
CG ("LABEL XLOOP-"); TextIO.PutCard (outFile, LC, 1);
CG ("");
GetSymbol
END isLOOP;
PROCEDURE isEXIT;
BEGIN
IF LOOPdepth = 0 THEN
ErrorMessage (11) (* EXIT without LOOP *)
ELSE
CG ("JUMP TO XLOOP-"); TextIO.PutCard (outFile, EXITcount [LOOPdepth], 1);
CG ("");
DEC (LOOPdepth)
END;
GetSymbol
END isEXIT;
PROCEDURE isRETURN;
BEGIN
IF PROCdepth = 0 THEN
ErrorMessage (19) (* RETURN without PROCEDURE *)
END;
CG ("RETURN"); CG ("");
LOOPdepth := 0;
GetSymbol
END isRETURN;
PROCEDURE isIF;
BEGIN
Condition;
IF Strings.StrEq (token, "THEN") THEN
GetSymbol;
StatementSequence;
WHILE Strings.StrEq (token, "ELSIF") DO
InsertLabel;
Condition;
IF Strings.StrEq (token, "THEN") THEN
InsertLabel;
GetSymbol;
StatementSequence
ELSE
ErrorMessage (12) (* THEN expected *)
END
END;
IF Strings.StrEq (token, "ELSE") THEN
(* InsertLabel; *)
GetSymbol;
StatementSequence
END;
IF Strings.StrEq (token, "END") = FALSE THEN
ErrorMessage (8) (* END expected *)
END;
InsertLabel;
GetSymbol
ELSE
ErrorMessage (12) (* THEN expected *)
END
END isIF;
PROCEDURE Condition;
VAR ok : BOOLEAN;
str : Identifier;
op : Identifier;
PROCEDURE Comparison;
BEGIN
CASE token [0] OF
'=' : op := 'EQUAL' |
'<' : CASE token [1] OF
0C : op := 'LESS THAN' |
'>' : op := 'NOT EQUAL' |
'=' : op := 'LESS OR EQUAL'
ELSE
ErrorMessage (13) (* Illegal comparator *)
END |
'>' : CASE token [1] OF
0C : op := 'GREATER' |
'=' : op := 'GREATER OR EQUAL'
ELSE
ErrorMessage (13) (* Illegal comparator *)
END |
'#' : op := 'NOT EQUAL'
ELSE
ErrorMessage (13) (* Illegal comparator *)
END;
END Comparison;
BEGIN
IF Strings.StrEq (token, "ODD") THEN
Expression
ELSE
GetSymbol; Expression;
Comparison;
GetSymbol; Expression;
CG ("IF NOT "); CG (op); CG (" JUMP TO LABEL-");
NumConv.Num2Str (LabelCount, 10, str, ok);
CG (str);
CG ("")
END
END Condition;
PROCEDURE Assignment;
BEGIN
CG ("STORE ADDRESS OF "); CG (token); CG ("");
GetSymbol;
IF Strings.StrEq (token, ':=') THEN
GetSymbol;
Expression
ELSE
ErrorMessage (17); (* Missing ':=' *)
END;
CG ("SAVE RESULT"); CG ("")
END Assignment;
PROCEDURE Expression;
VAR op : CHAR;
BEGIN
Term;
op := token [0];
WHILE (token [0] = '+') OR (token [0] = '-') DO
GetSymbol;
Term;
IF op = '+' THEN
CG ("ADD");
CG ("")
ELSE
CG ("SUBTRACT");
CG ("")
END;
END
END Expression;
PROCEDURE TermOperator () : BOOLEAN;
VAR oper : CHAR;
BEGIN
oper := token [0];
IF (oper = 'x') OR (oper = '*') OR (oper = '.') THEN RETURN TRUE
ELSIF (oper = ':') OR (oper = '/') THEN RETURN TRUE
ELSIF (oper = '%') OR Strings.StrEq (token, 'MOD') THEN RETURN TRUE
ELSE
RETURN FALSE
END
END TermOperator;
PROCEDURE Term;
VAR Operator : CHAR;
op : Identifier;
BEGIN
Factor;
GetSymbol;
WHILE TermOperator () = TRUE DO
CASE token [0] OF
'.', 'x', '*' : op := 'MULTIPLY' |
':', '/' : op := 'DIVIDE'
ELSE
op := 'MODULO'
END;
GetSymbol;
Factor;
CG (op); CG ("");
GetSymbol
END
END Term;
PROCEDURE Factor;
BEGIN
IF FindSymbol (token) = TRUE THEN (* token is CONST or VAR *)
IF (thisSymbol^.type = Constype) THEN
CG ("STORE "); (* push value of CONST *)
TextIO.PutCard (outFile, thisSymbol^.value, 1);
CG ("")
END;
IF (thisSymbol^.type = Vartype) THEN
CG ("FETCH VALUE OF ");
CG (thisSymbol^.Name); CG (""); (* fetch value at addr of VAR *)
END
ELSIF isNumber (token) THEN
CG ("STORE "); CG (token); (* Literal value *)
CG ("")
ELSIF token [0] = '(' THEN
GetSymbol;
Expression;
IF token [0] # ')' THEN ErrorMessage (16) END
ELSE
ErrorMessage (15) (* Error in Factor *)
END
END Factor;
PROCEDURE OpenOutputs (name : Identifier);
VAR i : CARDINAL;
Fname : Identifier;
BEGIN
i := Strings.pos ('.', name);
IF i <= HIGH (name) THEN name [i] := 0C END;
Fname := name;
Strings.Append (Fname, '.palo');
TextIO.OpenOutput (outFile, Fname);
END OpenOutputs;
PROCEDURE Init;
VAR count : SHORTCARD;
FileName : Identifier;
BEGIN
Arguments.GetArgs (count, buffer);
IF count = 1 THEN
ErrorMessage (33);
HALT
END;
Strings.Assign (FileName, buffer^[1]^);
TextIO.OpenInput (inFile, FileName);
IF NOT TextIO.Done () THEN
ErrorMessage (34);
HALT
END;
OpenOutputs (FileName);
MemPools.NewPool (Symbols);
MemPools.PoolAllocate (Symbols, firstSymbol, SYSTEM.TSIZE (SymbolNode));
WITH firstSymbol^ DO
Name := "|";
next := NIL;
previous := NIL
END;
currentType := Keytype;
IF StoreSymbol ("PROGRAM") = FALSE THEN ErrorMessage (0) END;
IF StoreSymbol ("LOOP") = FALSE THEN ErrorMessage (0) END;
IF StoreSymbol ("EXIT") = FALSE THEN ErrorMessage (0) END;
IF StoreSymbol ("BEGIN") = FALSE THEN ErrorMessage (0) END;
IF StoreSymbol ("END") = FALSE THEN ErrorMessage (0) END;
IF StoreSymbol ("IF") = FALSE THEN ErrorMessage (0) END;
IF StoreSymbol ("THEN") = FALSE THEN ErrorMessage (0) END;
IF StoreSymbol ("ELSIF") = FALSE THEN ErrorMessage (0) END;
IF StoreSymbol ("ELSE") = FALSE THEN ErrorMessage (0) END;
IF StoreSymbol ("ODD") = FALSE THEN ErrorMessage (0) END;
IF StoreSymbol ("OR") = FALSE THEN ErrorMessage (0) END;
IF StoreSymbol ("AND") = FALSE THEN ErrorMessage (0) END;
IF StoreSymbol ("NOT") = FALSE THEN ErrorMessage (0) END;
IF StoreSymbol ("MOD") = FALSE THEN ErrorMessage (0) END;
IF StoreSymbol ("IRQ") = FALSE THEN ErrorMessage (0) END;
IF StoreSymbol ("STATIC") = FALSE THEN ErrorMessage (0) END;
IF StoreSymbol ("RETURN") = FALSE THEN ErrorMessage (0) END;
IF StoreSymbol ("PROCEDURE") = FALSE THEN ErrorMessage (0) END;
IF StoreSymbol ("CONSTANTS") = FALSE THEN ErrorMessage (0) END;
IF StoreSymbol ("VARIABLES") = FALSE THEN ErrorMessage (0) END;
currentType := Constype;
IF StoreSymbol ("TRUE") = FALSE THEN ErrorMessage (0) ELSE thisSymbol^.value := 1 END;
IF StoreSymbol ("FALSE") = FALSE THEN ErrorMessage (0) ELSE thisSymbol^.value := 0 END;
currentType := Progtype;
LOOPdepth := 0;
PROCdepth := 0;
Exhausted := FALSE;
LabelCount := 0
END Init;
PROCEDURE ShutDown;
BEGIN
TextIO.Close (inFile);
TextIO.Close (outFile);
InOut.WriteLn; InOut.WriteLn; PrintNames;
MemPools.KillPool (Symbols)
END ShutDown;
BEGIN
Init;
Program;
ShutDown
END Plov006.
Plov006 : results
Above you see the pudding. But there is no proof of it, so I did some eating too. Let's start with the source to be compiled: test17.
PROGRAM test17
CONSTANTS pi = 314159625
ee = 271828182
END
VARIABLES temp
x
Fahr
Kelvin
result
END
PROCEDURE Blow
BEGIN
temp := temp + 273
LOOP
Fahr := 32 + temp x 5 : 4
IF Fahr < 0 THEN EXIT END
x := x + 1
END
IF result > 0 THEN RETURN END
RETURN
END Blow
BEGIN
Kelvin := temp + 273
LOOP
Kelvin := Kelvin + ee
LOOP
Fahr := ee + x
IF Fahr > 12 THEN EXIT END
Fahr := Fahr - 1
END
IF Kelvin = 10000 THEN EXIT END
Kelvin := ee
END
IF Kelvin = 300 THEN Kelvin := 10 END
Fahr := 32 + temp x 5 : 4
result := ( Fahr - 32 ) . x / 5
END test17
If we compile this, the file 'test17.palo' is generated with the following contents. Left is the generated
PALO code and on the right is the PLOV source.
| PLOV | PALO |
|---|---|
| PROGRAM test17 | # PROGRAM test17 |
| CONSTANTS pi = 314159625 | |
| ee = 271828182 | |
| END | |
| VARIABLES temp | VARIABLE temp |
| x | VARIABLE x |
| Fahr | VARIABLE Fahr |
| Kelvin | VARIABLE Kelvin |
| result | VARIABLE result |
| END | |
| PROCEDURE Blow | LABEL Blow |
| BEGIN | |
| temp := temp + 273 |
STORE ADDRESS OF temp FETCH VALUE OF temp STORE 273 ADD SAVE RESULT |
| LOOP | LABEL LOOP-1 |
| Fahr := 32 + temp x 5 : 4 |
STORE ADDRESS OF Fahr STORE 32 FETCH VALUE OF temp STORE 5 MULTIPLY STORE 4 DIVIDE ADD SAVE RESULT |
| IF Fahr < 0 THEN EXIT END |
FETCH VALUE OF Fahr STORE 0 IF NOT LESS THAN JUMP TO LABEL-0 JUMP TO XLOOP-1 LABEL-0 |
| x := x + 1 |
STORE ADDRESS OF x FETCH VALUE OF x STORE 1 ADD SAVE RESULT |
| END |
JUMP TO LOOP-1 LABEL XLOOP-1 |
| IF result > 0 THEN RETURN END |
FETCH VALUE OF result STORE 0 IF NOT GREATER JUMP TO LABEL-1 RETURN LABEL-1 |
| RETURN | RETURN |
| END Blow | LABEL EXITBlow |
| BEGIN | LABEL MAINLOOP |
| Kelvin := temp + 273 |
STORE ADDRESS OF Kelvin FETCH VALUE OF temp STORE 273 ADD SAVE RESULT |
| LOOP | LABEL LOOP-2 |
| Kelvin := Kelvin + ee |
STORE ADDRESS OF Kelvin FETCH VALUE OF Kelvin STORE 271828182 ADD SAVE RESULT |
| LOOP | LABEL LOOP-3 |
| Fahr := ee + x |
STORE ADDRESS OF Fahr STORE 271828182 FETCH VALUE OF x ADD SAVE RESULT |
| IF Fahr > 12 THEN EXIT END |
FETCH VALUE OF Fahr STORE 12 IF NOT GREATER JUMP TO LABEL-2 JUMP TO XLOOP-3 LABEL-2 |
| Fahr := Fahr - 1 |
STORE ADDRESS OF Fahr FETCH VALUE OF Fahr STORE 1 SUBTRACT SAVE RESULT |
| END |
JUMP TO LOOP-3 LABEL XLOOP-3 |
| IF Kelvin = 10000 THEN EXIT END |
FETCH VALUE OF Kelvin STORE 10000 IF NOT EQUAL JUMP TO LABEL-3 LABEL-3 |
| Kelvin := ee |
STORE ADDRESS OF Kelvin STORE 271828182 SAVE RESULT |
| END |
JUMP TO LOOP-2 LABEL XLOOP-2 |
| IF Kelvin = 300 THEN Kelvin := 10 END |
FETCH VALUE OF Kelvin STORE 300 IF NOT EQUAL JUMP TO LABEL-4
STORE ADDRESS OF Kelvin LABEL-4 |
| Fahr := 32 + temp x 5 : 4 |
STORE ADDRESS OF Fahr STORE 32 FETCH VALUE OF temp STORE 5 MULTIPLY STORE 4 DIVIDE ADD SAVE RESULT |
| result := ( Fahr - 32 ) . x / 5 |
STORE ADDRESS OF result FETCH VALUE OF Fahr STORE 32 SUBTRACT FETCH VALUE OF x MULTIPLY STORE 5 DIVIDE SAVE RESULT |
| END test17 |
LABEL EXITMAINLOOP # Done # |
Plov006 has converted a modula-like language (PLOV) into a stack oriented meta language (PALO). The general
idea behind the Plov compiler is to make a PALO file that can be converted to ANY target processor with the
ALTO backend compiler. The ALTO compiler will be fed 100% errorfree code so it can be easily made and it's
backend for various processors only needs to be made once.
If my next project is about a C compiler (heaven forbid) it just needs to provide a PALO file again and it
will be processed by the same ALTO compiler that was made before.
Page created on 21 august 2008 and
Page equipped with FroogleBuster technology