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.
Preliminary trials were very assuring.

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 TRUE
   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;
   
Suppose you want to have a 'BITWISE AND' or 'BITWISE OR' this may give you a clue of how to get it done.

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  DO
      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'
	 ELSE
	   ErrorMessage (25);
	   op := "Error"
	 END
      END;
      GetSymbol;
      Factor;
      CG (op);		CG ("");
      GetSymbol;
   END
END Term;
   
Preliminary tests have shown it works.

Plov016 : testing

The new operators

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 Error GOTO IF-00

ADDRESS LOCAL c
FETCH d
SAVE

ADDRESS e
FETCH f
FETCH g
MULTIPLY
SAVE

ADDRESS i
STORE	1
SAVE

GOTO XIF-0
LABEL IF-00
FETCH LOCAL a
FETCH LOCAL b
MODULO
FETCH d
FETCH LOCAL c
DIVIDE
IF Error GOTO IF-01
LABEL IF-01
LABEL XIF-0


ADDRESS k
FETCH j
FETCH d
Error
SAVE

RELEASE 3
# END OF PROCEDURE gobble



ADDRESS a

ADDRESS k
FETCH i
STORE	1
SUBTRACT
SAVE

# Done #
      

Page created on 20 September 2008 and

Page equipped with FroogleBuster technology