Plov016 : some small changes
Progress is steady. Small steps, as Professor Wirth proclaims. The refinements of today are:
Plov016 : The PROGRAM loop
This is the old PROGRAM loop. You see the triangle. That's not good enough anymore. IOf the first word is not 'PROGRAM' the rest of the source is skipped. Now what we want.
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 *)
Skip2LF
END
ELSE
ErrorMessage (18) (* 'PROGRAM' expected *)
END
END Program;
So I changed the source into this:
PROCEDURE Program;
BEGIN
GetSymbol;
IF NOT Strings.StrEq (token, "PROGRAM") THEN
ErrorMessage (18) (* 'PROGRAM' expected *)
END;
GetSymbol;
IF NOT isIdentifier (token) THEN
ErrorMessage (5); (* Illegal identifier *)
Skip2LF
END;
WITH firstSymbol^ DO
Name := token;
type := Progtype
END;
CG ("# PROGRAM "); CG (token); CG (""); CG ("");
Block;
IF NOT Strings.StrEq (token, firstSymbol^.Name) THEN
ErrorMessage (3)
END;
CG ("# Done #"); CG ("")
END Program;
The triangulation is gone. A flat indentationline. And it shows in the error listing. If there is an error in
the first line, errors in subsequent lines are still found. It gets tempting to make a real messy source, full
of typos, and increase the ErrorMax constant to 20 or so and see how far it gets.
Plov016 : Comparison
Below is the improved version of 'Comparison'. The lines in RED have been added.
PROCEDURE Comparison;
BEGIN
CASE token [0] OF
'=' : op := 'DIFFERENT' |
'<' : CASE token [1] OF
0C : op := 'GREQ' |
'>' : op := 'EQUAL' |
'=' : op := 'GREATER'
ELSE
ErrorMessage (13); (* Illegal comparator *)
op := 'Error'
END |
'>' : CASE token [1] OF
0C : op := 'LEQ' |
'=' : op := 'LESS'
ELSE
ErrorMessage (13); (* Illegal comparator *)
op := 'Error'
END |
'#' : op := 'EQUAL'
ELSE
ErrorMessage (13); (* Illegal comparator *)
op := 'Error'
END;
END Comparison;
If an error is found, it is flagged in the source listing but it is also flagged in the PALO file. Without the
lines in red, the global 'op' value would still contain the value of the previous test.
Plov016 : TermOperator
This procedure checks wwhether the current token is a valid operator for Factor. I added new operators I found essential for Plov. Look at it. This is how difficult it is to add new operators...
PROCEDURE TermOperator () : BOOLEAN; VAR oper : CHAR; BEGIN oper := token [0]; IF (oper = '*') OR (oper = '.') THEN RETURN TRUESuppose you want to have a 'BITWISE AND' or 'BITWISE OR' this may give you a clue of how to get it done.ELSIF Strings.StrEq (token, "SHL") THEN RETURN TRUE ELSIF Strings.StrEq (token, "SHR") THEN RETURN TRUE ELSIF Strings.StrEq (token, "DIV") THEN RETURN TRUE ELSIF Strings.StrEq (token, "MOD") 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;
Plov016 : Term
In 'Term', the factors are operated upon. Term uses 'TermOperator' to see if an op is valid or not.
PROCEDURE Term; VAR Operator : CHAR; op : Identifier; BEGIN Factor; GetSymbol; WHILE TermOperator () = TRUE DOPreliminary tests have shown it works.IF Strings.StrEq (token, "SHL") THEN op := "LEFTSHIFT" ELSIF Strings.StrEq (token, "SHR") THEN op := "RIGHTSHIFT" ELSIF Strings.StrEq (token, "DIV") THEN op := "DIVIDE" ELSIF Strings.StrEq (token, "MOD") THEN op := "MODULO" ELSE CASE token [0] OF '.', '*' : op := 'MULTIPLY' | ':', '/' : op := 'DIVIDE' ELSEErrorMessage (25); op := "Error" END END; GetSymbol; Factor; CG (op); CG (""); GetSymbol; END END Term;
Plov016 : testing
| Plov | PALO |
|---|---|
PROGRAM test28
CONSTANTS aa = 12 END
VARIABLES a aaa b bab END
BEGIN
a := aaa SHL aa
bab := 1 SHR a
b := aa MOD 3
aaa := aaa + 1
a := aa DIV b
END test28
|
# PROGRAM test28
VARIABLE a
VARIABLE aaa
VARIABLE b
VARIABLE bab
LABEL MAINLOOP
ADDRESS a
FETCH aaa
STORE 12
LEFTSHIFT
SAVE
ADDRESS bab
STORE 1
FETCH a
RIGHTSHIFT
SAVE
ADDRESS b
STORE 12
STORE 3
MODULO
SAVE
ADDRESS aaa
FETCH aaa
STORE 1
ADD
SAVE
ADDRESS a
STORE 12
FETCH b
DIVIDE
SAVE
LABEL EXITMAINLOOP
# Done #
|
Looks good. Now lets make a messy source....
| Plov | Listing |
|---|---|
PROGAM test29
CONSTANTS zz = 12 END
VARIABLES a b c d e f g h i j k END
PROCEDURE gobble a
b
c
BEGIN
IF a @ b THEN
c := d
e := f . g
i := 1
ELSIF a MOD b THEN
d := c
g := f . i
k := j % d
ELSIF b > a THEN
h := 2
k := i - 1
ELSE
d := 0
END
END goble
BEGIN
gobble 1
2 k
END test2
|
PROGAM
@@ -- PROGRAM expected in line 1
test29
CONSTANTS zz = 12 END
VARIABLES a b c d e f g h i j k END
PROCEDURE gobble a
b
c
BEGIN
IF a @
@@ -- Illegal comparator : @ in line 12
b THEN
c := d
e := f . g
i := 1
ELSIF a MOD b THEN
@@ -- Illegal comparator : THEN in line 17
d := c
g
@@ -- THEN expected in line 18
@@ -- END expected in line 18
:= f . i
@@ -- Undefined symbol or keyword in line 19
k := j %
@@ -- Wrong operator in Factor in line 19
d
ELSIF
@@ -- END expected in line 20
b
@@ -- Procedure names do not match in line 20
>
@@ -- BEGIN expected in line 20
a THEN
@@ -- Missing assigment operator in line 21
h := 2
k := i - 1
ELSE
@@ -- END expected in line 24
d
@@ -- Program names do not match. in line 24
13 errors found.
|
Rather much meaningless errors here. Still some work to do in this section. Have you noticed the function parameters in the declaration (and call) of gobble? They were on seperate lines... Not intended but not a surprise either.
Let's have a look at the PALO output. Just for fun. Let's put some smile on that face!
| Plov | PALO |
|---|---|
PROGAM
@@ -- PROGRAM expected in line 1
test29
CONSTANTS zz = 12 END
VARIABLES a b c d e f g h i j k END
PROCEDURE gobble a
b
c
BEGIN
IF a @
@@ -- Illegal comparator : @ in line 12
b THEN
c := d
e := f . g
i := 1
ELSIF a MOD b THEN
@@ -- Illegal comparator : THEN in line 17
d := c
g
@@ -- THEN expected in line 18
@@ -- END expected in line 18
:= f . i
@@ -- Undefined symbol or keyword in line 19
k := j %
@@ -- Wrong operator in Factor in line 19
d
ELSIF
@@ -- END expected in line 20
b
@@ -- Procedure names do not match in line 20
>
@@ -- BEGIN expected in line 20
a THEN
@@ -- Missing assigment operator in line 21
h := 2
k := i - 1
ELSE
@@ -- END expected in line 24
d
@@ -- Program names do not match. in line 24
13 errors found.
|
# PROGRAM test29 VARIABLE a VARIABLE b VARIABLE c VARIABLE d VARIABLE e VARIABLE f VARIABLE g VARIABLE h VARIABLE i VARIABLE j VARIABLE k # PROCEDURE DECLARATION OF gobble LABEL gobble PARAMETER a PARAMETER b PARAMETER c FETCH LOCAL a FETCH LOCAL b IF |
Page created on 20 September 2008 and
Page equipped with FroogleBuster technology