Plov020 : another course

After four months of seeming rest (not quite, rest assured) I picked up the Plov thread again. And it (again) was time for a change. The Palo/Alto scheme was too demanding. So it has been abandoned yet again. In favor of direct code generation. Here are the changes in Plov020 so far:

This means that part of what was added in Plov018 is redundant now. But that's progress.... We walk the line. But if it curves, I might as well skip the bend.

Plov020 : the major changes

First, the changes to the declarations: BitType, Regtype. The symbol table gained a field calles 'value'. And some new global variables: BigFlash, RamStart, EEPROM, FLASH, SRAM, VarPtr, loxFile, proFile, symFile.

TYPE	Identifier	= ARRAY [0..31] OF CHAR;
	SymbolType	= (ProgName, Proctype, Constype, Vartype, Keytype, BitType, Regtype, None);
	SymbolPtr	= POINTER TO SymbolNode;
	SymbolNode	= RECORD
			    Name	: Identifier;		(* name of symbol	*)
			    next	: SymbolPtr;		(* next in linked list	*)
			    type	: SymbolType;		(* TYPE			*)
			    addr,				(* address of symbol	*)
			    value	: CARDINAL		(* value (CONSTANT) or	*)
			  END;					(* position (BIT)	*)

VAR	token, op, CPU			: Identifier;
	BigFlash,
	getNextToken, DebugMode,
	InProcedure, weHaveLocals,
	pastEOL, Exhausted		: BOOLEAN;
	Locals, Symbols			: MemPools.MemPool;
	firstLocal, thisLocal,
	firstSymbol, thisSymbol		: SymbolPtr;
	currentType			: SymbolType;
	RamStart, EEPROM, FLASH, SRAM,
	VarPtr,
	line, Xpos, ErrCount,
	LOOPcount, IFcount,
	REPEATcount, WHILEcount,
	LOOPdepth, PROCdepth		: CARDINAL;
	lastCH				: CHAR;
	loxFile, proFile,
	inFile, outFile, symFile	: TextIO.File;
	buffer				: Arguments.ArgTable;
	EXITcount			: ARRAY [0..25] OF CARDINAL;
   
Some new error messages:
     36 : InOut.WriteString ("PROCESSOR expected; assuming ATmega128")	|
     37 : InOut.WriteString ("Invalid processor specified. Aborting.")	|
     38 : InOut.WriteString ("Hit premature end of PROCESSOR file.")	|
     39 : InOut.WriteString ("Error in PROCESSOR file.")		|
     40 : InOut.WriteString ("Duplicate identifier in PROCESSOR file.")
   
Two new procedures, for writing symbol tables to disk in a formatted way:
PROCEDURE DumpSymbols;

VAR	thisOne    		: SymbolPtr;
	n			: CARDINAL;

BEGIN
   thisOne := firstSymbol;
   TextIO.PutString (symFile, "Symbol table.");
   TextIO.PutLn (symFile);
   TextIO.PutLn (symFile);
   LOOP
      TextIO.PutString (symFile, thisOne^.Name);
      n := 4 - (Strings.Length (thisOne^.Name) DIV 8);
      REPEAT
	 TextIO.PutChar (symFile, 11C);
	 DEC (n)
      UNTIL n = 0;
      CASE  thisOne^.type  OF
        ProgName : TextIO.PutString (symFile, "Program name")			|
	Proctype : TextIO.PutString (symFile, "Procedure at address");
		   TextIO.PutChar   (symFile, 11C);
		   TextIO.PutCard   (symFile, thisOne^.addr, 8)		       	|
	Constype : TextIO.PutString (symFile, "Constant =");
		   TextIO.PutChar   (symFile, 11C);
		   TextIO.PutChar   (symFile, 11C);
		   TextIO.PutCard   (symFile, thisOne^.value, 8)		|
	Vartype	 : TextIO.PutString (symFile, "INTEGER at address");
		   TextIO.PutChar   (symFile, 11C);
		   TextIO.PutCard   (symFile, thisOne^.addr, 8)			|
	Keytype	 : TextIO.PutString (symFile, "Keyword")			|
	BitType	 : TextIO.PutString (symFile, "BIT at register address");
		   TextIO.PutChar   (symFile, 11C);
		   TextIO.PutCard   (symFile, thisOne^.addr, 8);
		   TextIO.PutString (symFile, " at position");
		   TextIO.PutChar   (symFile, 11C);
		   TextIO.PutCard   (symFile, thisOne^.value, 8)		|
	Regtype  : TextIO.PutString (symFile, "BYTE at address");
		   TextIO.PutChar   (symFile, 11C);
		   TextIO.PutCard   (symFile, thisOne^.addr, 8)
      ELSE
         TextIO.PutString (symFile, "Error in symbol table; ");
	 TextIO.PutString (symFile, thisOne^.Name);
	 TextIO.PutString (symFile, "is an unknown type. *****************************")
      END;
      TextIO.PutLn (symFile);
      IF  thisOne^.next = NIL  THEN
         EXIT
      ELSE
         thisOne := thisOne^.next
      END
   END;
   TextIO.PutLn (symFile)
END DumpSymbols;


PROCEDURE DumpLocals (proc	: SymbolPtr);

VAR	  thisOne    		: SymbolPtr;

BEGIN
   thisOne := firstLocal;
   TextIO.PutString (loxFile, "Procedure ");
   TextIO.PutString (loxFile, proc^.Name);
   TextIO.PutLn (loxFile);
   LOOP
      TextIO.PutString (loxFile, thisOne^.Name);
      TextIO.PutChar (loxFile, 11C);
      IF  thisOne^.next = NIL  THEN
         EXIT
      ELSE
         thisOne := thisOne^.next
      END
   END;
   TextIO.PutLn (loxFile)
END DumpLocals;
   
In VariableDeclaration, the address of the variable is added to the symbol table.
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;
      thisSymbol^.addr := VarPtr;
      INC (VarPtr, 2);
      CG ("VARIABLE	");		CG (token);		CG ("");
      GetSymbol
   UNTIL Strings.StrEq (token, "END");
   GetSymbol
END VariableDeclaration;
   
Read in the processor specific registers and bitfields, plus some numbers concerning size and location of memory areas.
PROCEDURE ReadProcessor (name	: Identifier) : BOOLEAN;

VAR	fname, word, BitName		: Identifier;
	current				: SymbolPtr;
	nr				: CARDINAL;
	ok				: BOOLEAN;

BEGIN
   fname := name;
   TextIO.OpenInput (proFile, fname);		(* Try to open local file	*)
   IF  TextIO.Done () = FALSE  THEN
      fname := '../';
      Strings.Append (fname, name);
      TextIO.OpenInput (proFile, fname);	(* One directory up then?	*)
      IF  TextIO.Done () = FALSE  THEN
	 fname := '/usr/local/AVR/';
	 Strings.Append (fname, name);
	 TextIO.OpenInput (proFile, fname);	(* In /usr/local/AVR then?	*)
	 IF  TextIO.Done () = FALSE  THEN
	    ErrorMessage (37);
	    RETURN FALSE
	 END
      END
   END;						(* Processor data file is open	*)
   REPEAT
      TextIO.GetString (proFile, word)
   UNTIL  Strings.StrEq (word, 'BEGIN');
   LOOP
      IF  TextIO.EOF (proFile) = TRUE  THEN  ErrorMessage (38);  RETURN FALSE  END;
      TextIO.GetString (proFile, word);
      IF     Strings.StrEq (word, 'END')	= TRUE  THEN  EXIT
      ELSIF  Strings.StrEq (word, 'FLASH')	= TRUE  THEN  TextIO.GetCard (proFile, FLASH)
      ELSIF  Strings.StrEq (word, 'EEPROM')	= TRUE  THEN  TextIO.GetCard (proFile, EEPROM)
      ELSIF  Strings.StrEq (word, 'SRAM')	= TRUE  THEN  TextIO.GetCard (proFile, SRAM)
      ELSIF  Strings.StrEq (word, 'RAMSTART')	= TRUE  THEN  TextIO.GetCard (proFile, RamStart)
      ELSIF  Strings.StrEq (word, 'COMPILER')	= TRUE  THEN
	 REPEAT  TextIO.GetString (proFile, word)  UNTIL Strings.StrEq (word, 'END')
      ELSIF  Strings.StrEq (word, 'PORTS')	= TRUE  THEN
	 currentType := Regtype;
	 LOOP
	    TextIO.GetString (proFile, word);
	    IF  Strings.StrEq (word, 'END') = TRUE  THEN  EXIT  END;
	    NumConv.Str2Num (nr, 16, word, ok);
	    TextIO.GetString (proFile, word);
	    IF  NOT ok  THEN  
	       ErrorMessage (39)
	    ELSE
	       ok := StoreSymbol (word);
	       IF  NOT ok  THEN  
		  ErrorMessage (40)
	       ELSE
		  thisSymbol^.addr := nr
	       END
	    END
	 END
      ELSIF  Strings.StrEq (word, 'BITS')  = TRUE  THEN
         currentType := BitType;
         LOOP
	    TextIO.GetString (proFile, word);
	    IF  Strings.StrEq (word, 'END') = TRUE  THEN  EXIT  END;
	    ok := FindSymbol (word);
	    current := thisSymbol;
	    nr := 7;
	    LOOP
	       TextIO.GetString (proFile, BitName);
	       IF  BitName [0] # '-'  THEN
		  ok := StoreSymbol (BitName);
		  thisSymbol^.value := nr;
		  thisSymbol^.addr := current^.addr;
	       END;
	       IF  nr = 0  THEN  EXIT  ELSE  DEC (nr)  END
	    END
	 END
      END
   END;
   VarPtr := RamStart;
   TextIO.Close (proFile);
   IF  FLASH > 4096  THEN  BigFlash := TRUE  ELSE  BigFlash := FALSE  END;
   RETURN TRUE
END ReadProcessor;
   
The files to be opened are composed here:
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);
   Fname := name;
   Strings.Append (Fname, '.symbols');
   TextIO.OpenOutput (symFile, Fname);
   Fname := name;
   Strings.Append (Fname, '.locals');
   TextIO.OpenOutput (loxFile, Fname)
END OpenOutputs;
   
And the shutdown procedure:
PROCEDURE ShutDown;

BEGIN
   DumpSymbols;
   TextIO.Close (inFile);
   TextIO.Close (outFile);
   TextIO.Close (symFile);
   TextIO.Close (loxFile);
   InOut.WriteLn;		(*	PrintNames;	*)
   MemPools.KillPool (Symbols);
   IF  ErrCount = 0  THEN
      InOut.WriteString ("No")
   ELSE
      InOut.WriteCard (ErrCount, 1)
   END;
   InOut.WriteString (" errors found.");
   InOut.WriteLn;
   InOut.WriteLn;
END ShutDown;
   
And that's just about it!

Plov020 : see it run

Of course, Plov020 runs. I ran some tests:

PROGRAM test26

PROCESSOR ATmega8515

CONSTANTS	m =  7
		n = 85
END

VARIABLES	x 
		y 
		z 
		q
		r
END


PROCEDURE MULTIPLY p q

BEGIN
  z := 0
  WHILE q MOD 2 = 1 DO 
    IF q = 1 THEN z := z + p END
    p := p SHL 1
    q := q SHR 1
  END
END MULTIPLY


PROCEDURE DIVIDE t n

LOCAL 	w	END

BEGIN
  t := x
  q := 0
  n := y
  WHILE n <= t DO n := n SHL 1 END
  WHILE n > y DO 
    q := q SHL 1
    n := n SHR 1
    IF n <= t THEN 
      t := t - n
      INC q
    END
  END
END DIVIDE


PROCEDURE Gcd

LOCAL	 f g	END

BEGIN
  f := x
  g := y
  WHILE f # g DO 
    IF f < g THEN 
      g := g - f
      q := f + g
    END
    IF g < f THEN
      f := f - g
      r := m . x
    END
  END
  z := f
END Gcd

IRQ 1 = Gcd

BEGIN
  MULTIPLY m n
  DIVIDE x y
  x := 84
  y := 36
  Gcd
END test26
   
This compiles without errors, to produce the files
jan@beryllium:~/modula/Plov$ ls -l test26*
-rw-r--r--  1 jan users   791 2009-02-09 21:59 test26
-rw-r--r--  1 jan users    70 2009-02-09 21:59 test26.locals
-rw-r--r--  1 jan users  2079 2009-02-09 21:59 test26.palo
-rw-r--r--  1 jan users 11257 2009-02-09 21:59 test26.symbols
jan@beryllium:~/modula/Plov$
   
Here is the locals file:
Procedure MULTIPLY
	p	q	
Procedure DIVIDE
	t	n	w	
Procedure Gcd
	f	g	
   
And the symbol table:
Symbol table.

test26			Program name
CONSTANTS		Keyword
BEGIN			Keyword
BIT			Keyword
BYTE			Keyword
DEC			Keyword
DO			Keyword
ELSE			Keyword
ELSIF			Keyword
END			Keyword
EXIT			Keyword
IF			Keyword
INC			Keyword
IOPORT			Keyword
IRQ			Keyword
LOCAL			Keyword
LOOP			Keyword
MOD			Keyword
OR			Keyword
PORTS			Keyword
PROCEDURE		Keyword
PROGRAM			Keyword
REPEAT			Keyword
RETURN			Keyword
THEN			Keyword
UNTIL			Keyword
VARIABLES		Keyword
WHILE			Keyword
TRUE			Constant =		       1
FALSE			Constant =		       0
OscCal			BYTE at address	       4
PINE			BYTE at address	       5
DDRE			BYTE at address	       6
PORTE			BYTE at address	       7
ACSR			BYTE at address	       8
UBRRL			BYTE at address	       9
UCSRB			BYTE at address	      10
UCSRA			BYTE at address	      11
UDR			BYTE at address	      12
SPCR			BYTE at address	      13
SPSR			BYTE at address	      14
SPDR			BYTE at address	      15
PIND			BYTE at address	      16
DDRD			BYTE at address	      17
PORTD			BYTE at address	      18
PINC			BYTE at address	      19
DDRC			BYTE at address	      20
PORTC			BYTE at address	      21
PINB			BYTE at address	      22
DDRB			BYTE at address	      23
PORTB			BYTE at address	      24
PINA			BYTE at address	      25
DDRA			BYTE at address	      26
PORTA			BYTE at address	      27
EECR			BYTE at address	      28
EEDR			BYTE at address	      29
EEARL			BYTE at address	      30
EEARH			BYTE at address	      31
UBRRH/UCSRC		BYTE at address	      32
WDTCR			BYTE at address	      33
ICR1L			BYTE at address	      36
ICR1H			BYTE at address	      37
OCR1BL			BYTE at address	      40
OCR1BH			BYTE at address	      41
OCR1AL			BYTE at address	      42
OCR1AH			BYTE at address	      43
TCNT1L			BYTE at address	      44
TCNT1H			BYTE at address	      45
TCCR1B			BYTE at address	      46
TCCR1A			BYTE at address	      47
SFIOR			BYTE at address	      48
OCR0			BYTE at address	      49
TCNT0			BYTE at address	      50
TCCR0			BYTE at address	      51
MCUCSR			BYTE at address	      52
MCUCR			BYTE at address	      53
EMCUCR			BYTE at address	      54
SPMCR			BYTE at address	      55
TIFR			BYTE at address	      56
TIMSK			BYTE at address	      57
GIFR			BYTE at address	      58
GICR			BYTE at address	      59
SPL			BYTE at address	      61
SPH			BYTE at address	      62
SREG			BYTE at address	      63
ACD			BIT at register address	       8 at position	       7
ACBG			BIT at register address	       8 at position	       6
ACO			BIT at register address	       8 at position	       5
ACI			BIT at register address	       8 at position	       4
ACIE			BIT at register address	       8 at position	       3
ACIC			BIT at register address	       8 at position	       2
ACIS1			BIT at register address	       8 at position	       1
ACIS0			BIT at register address	       8 at position	       0
RXCIE			BIT at register address	      10 at position	       7
TXCIE			BIT at register address	      10 at position	       6
UDRIE			BIT at register address	      10 at position	       5
RXEN			BIT at register address	      10 at position	       4
TXEN			BIT at register address	      10 at position	       3
UCSZ2			BIT at register address	      10 at position	       2
RXB8			BIT at register address	      10 at position	       1
TXB8			BIT at register address	      10 at position	       0
RXC			BIT at register address	      11 at position	       7
TXC			BIT at register address	      11 at position	       6
UDRE			BIT at register address	      11 at position	       5
FE			BIT at register address	      11 at position	       4
DOR			BIT at register address	      11 at position	       3
PE			BIT at register address	      11 at position	       2
U2X			BIT at register address	      11 at position	       1
MPCM			BIT at register address	      11 at position	       0
SPIE			BIT at register address	      13 at position	       7
SPE			BIT at register address	      13 at position	       6
DORD			BIT at register address	      13 at position	       5
MSTR			BIT at register address	      13 at position	       4
CPOL			BIT at register address	      13 at position	       3
CPHA			BIT at register address	      13 at position	       2
SPR1			BIT at register address	      13 at position	       1
SPR0			BIT at register address	      13 at position	       0
SPIF			BIT at register address	      14 at position	       7
WCOL			BIT at register address	      14 at position	       6
SPI2X			BIT at register address	      14 at position	       0
EERIE			BIT at register address	      28 at position	       3
EEMWE			BIT at register address	      28 at position	       2
EEWE			BIT at register address	      28 at position	       1
EERE			BIT at register address	      28 at position	       0
URSEL			BIT at register address	      28 at position	       7
UMSEL			BIT at register address	      28 at position	       6
UPM1			BIT at register address	      28 at position	       5
UPM0			BIT at register address	      28 at position	       4
USBS			BIT at register address	      28 at position	       3
UCSZ1			BIT at register address	      28 at position	       2
UCSZ0			BIT at register address	      28 at position	       1
UCPOL			BIT at register address	      28 at position	       0
WDCE			BIT at register address	      33 at position	       4
WDE			BIT at register address	      33 at position	       3
WDP2			BIT at register address	      33 at position	       2
WDP1			BIT at register address	      33 at position	       1
WDP0			BIT at register address	      33 at position	       0
ICNC1			BIT at register address	      46 at position	       7
ICES1			BIT at register address	      46 at position	       6
WGM13			BIT at register address	      46 at position	       4
WGM12			BIT at register address	      46 at position	       3
CS12			BIT at register address	      46 at position	       2
CS11			BIT at register address	      46 at position	       1
CS10			BIT at register address	      46 at position	       0
COM1A1			BIT at register address	      47 at position	       7
COM1A0			BIT at register address	      47 at position	       6
COM1B1			BIT at register address	      47 at position	       5
COM1B0			BIT at register address	      47 at position	       4
FOC1A			BIT at register address	      47 at position	       3
FOC1B			BIT at register address	      47 at position	       2
WGM11			BIT at register address	      47 at position	       1
WGM10			BIT at register address	      47 at position	       0
XMBK			BIT at register address	      48 at position	       6
XMM2			BIT at register address	      48 at position	       5
XMM1			BIT at register address	      48 at position	       4
XMM0			BIT at register address	      48 at position	       3
PUD			BIT at register address	      48 at position	       2
PSR10			BIT at register address	      48 at position	       0
FOC0			BIT at register address	      51 at position	       7
WGM00			BIT at register address	      51 at position	       6
COM01			BIT at register address	      51 at position	       5
COM00			BIT at register address	      51 at position	       4
WGM01			BIT at register address	      51 at position	       3
CS02			BIT at register address	      51 at position	       2
CS01			BIT at register address	      51 at position	       1
CS00			BIT at register address	      51 at position	       0
SM2			BIT at register address	      52 at position	       5
WRDF			BIT at register address	      52 at position	       3
BORF			BIT at register address	      52 at position	       2
EXTRF			BIT at register address	      52 at position	       1
PORF			BIT at register address	      52 at position	       0
SRE			BIT at register address	      53 at position	       7
SRW10			BIT at register address	      53 at position	       6
SE			BIT at register address	      53 at position	       5
SM1			BIT at register address	      53 at position	       4
ISC11			BIT at register address	      53 at position	       3
ISC10			BIT at register address	      53 at position	       2
ISC01			BIT at register address	      53 at position	       1
ISC00			BIT at register address	      53 at position	       0
SM0			BIT at register address	      54 at position	       7
SRL2			BIT at register address	      54 at position	       6
SRL1			BIT at register address	      54 at position	       5
SRL0			BIT at register address	      54 at position	       4
SRW01			BIT at register address	      54 at position	       3
SRW00			BIT at register address	      54 at position	       2
SRW11			BIT at register address	      54 at position	       1
ISC2			BIT at register address	      54 at position	       0
SPMIE			BIT at register address	      55 at position	       7
RWWSB			BIT at register address	      55 at position	       6
RWWSRE			BIT at register address	      55 at position	       4
BLBSET			BIT at register address	      55 at position	       3
PGWRT			BIT at register address	      55 at position	       2
PGERS			BIT at register address	      55 at position	       1
SPMEN			BIT at register address	      55 at position	       0
TOV1			BIT at register address	      56 at position	       7
OCF1A			BIT at register address	      56 at position	       6
OCF1B			BIT at register address	      56 at position	       5
ICF1			BIT at register address	      56 at position	       3
TOV0			BIT at register address	      56 at position	       1
OCF0			BIT at register address	      56 at position	       0
TOIE1			BIT at register address	      57 at position	       7
OCIE1A			BIT at register address	      57 at position	       6
OCIE1B			BIT at register address	      57 at position	       5
TICIE1			BIT at register address	      57 at position	       3
TOIE0			BIT at register address	      57 at position	       1
OCIE0			BIT at register address	      57 at position	       0
INTF1			BIT at register address	      58 at position	       7
INTF0			BIT at register address	      58 at position	       6
INTF2			BIT at register address	      58 at position	       5
INT1			BIT at register address	      59 at position	       7
INT0			BIT at register address	      59 at position	       6
INT2			BIT at register address	      59 at position	       5
IVSEL			BIT at register address	      59 at position	       1
IVCE			BIT at register address	      59 at position	       0
I			BIT at register address	      63 at position	       7
T			BIT at register address	      63 at position	       6
H			BIT at register address	      63 at position	       5
S			BIT at register address	      63 at position	       4
V			BIT at register address	      63 at position	       3
N			BIT at register address	      63 at position	       2
Z			BIT at register address	      63 at position	       1
C			BIT at register address	      63 at position	       0
m			Constant =		       7
n			Constant =		      85
x			INTEGER at address	      96
y			INTEGER at address	      98
z			INTEGER at address	     100
q			INTEGER at address	     102
r			INTEGER at address	     104
MULTIPLY		Procedure at address	       0
DIVIDE			Procedure at address	       0
Gcd			Procedure at address	       0
   
Not bad, isn't it?

Page created on 9 February 2009 and

Page equipped with FroogleBuster technology