This is the Pascal source of a public domain Pascal compiler and

interpreter. The entire code is documented in the book:

	Pascal Implementation

	by Steven Pemberton and Martin Daniels

	published by Ellis Horwood, Chichester, UK,

(also available in Japanese).

It was distributed by John Wiley in other countries, but now that

Prentice Hall has taken over Ellis Horwood, that may have changed.



Steven Pemberton is contactable by email as steven@cwi.nl.



The code here is slightly different from that in the book, but the

line numbers have been kept the same.  The changes were to allow

modern Pascal compilers to compile the source (there were some slight

laxities in the original code).



The type marktype is added for the parameters of the routines mark and

release:

    76c76

    < 

    ---

    >      marktype= ^integer;



The type setty (which represents set types) is added for the new type

compatibility rules of ISO Pascal:

    95c95

    < 

    ---

    >      setty = set of setlow..sethigh;

    100c100

    <                          pset: (pval: set of setlow..sethigh);

    ---

    >                          pset: (pval: setty);



Missing variant parts:

    123c123

    <                                   declared: (fconst: ctp));

    ---

    >                                   declared: (fconst: ctp); standard: ());

    145a146

    >                      types: ();

    149,150c150

    <                      proc,

    <                      func:  (case pfdeckind: declkind of

    ---

    >                      proc, func:  (case pfdeckind: declkind of

    154,155c154,155

    <                                            actual: (forwdecl, extern:

    <                                                     boolean)))

    ---

    >                                            actual: (forwdecl, extern: boolean);

    >                                            formal: ()))



Pcom has the files prr and prd as standard identifiers. You have to

declare them for other compilers:

    193d192

    < 

    194a194

    >     prr: text; (* comment this out when compiling with pcom *)

    299d298

    < 



Other compilers don't have the routines mark and release. Their

effective semantics are null; you just waste heap:

    300a300,301

    >   procedure mark(var p: marktype); begin end;

    >   procedure release(p: marktype); begin end;

    302d302

    < 



Output the line number with error messages, so that if the listing

option has been switched off, you still know which line is in error:

    307c307

    <       begin write(output,' ****  ':15);

    ---

    >       begin write(output,linecount:6,' ****  ':9);



Accept tabs as white-space as well:

    398c398

    <     repeat while (ch = ' ') and not eol do nextch;

    ---

    >     repeat while ((ch = ' ') or (ch = '	')) and not eol do nextch;



Jumping from the then part of an if into the else part is not allowed;

fix cases like 1..10 in another way:

    429c429

    <           if (ch = '.') or (ch = 'e') then

    ---

    >           if ((ch = '.') and (input^ <> '.')) or (ch = 'e') then

    434c434

    <                       nextch; if ch = '.' then begin ch := ':'; goto 3 end;

    ---

    >                       nextch; (*if ch = '.' then begin ch := ':'; goto 3 end;*)



Fix modern type mismatches:

    668c668

    <   procedure align(fsp: stp; var flc: integer);

    ---

    >   procedure align(fsp: stp; var flc: addrrange);



An identifier misspelled after the 8th character:

    872c872

    <           if sy = stringconstsy then

    ---

    >           if sy = stringconst then



Unused variables, and new type names:

    1529,1531c1529,1531

    <       var oldlev: 0..maxlevel; lsy: symbol; lcp,lcp1: ctp; lsp: stp;

    <           forw: boolean; oldtop: disprange; parcnt: integer;

    <           llc,lcm: addrrange; lbname: integer; markp: ^integer;

    ---

    >       var oldlev: 0..maxlevel; lcp,lcp1: ctp; lsp: stp;

    >           forw: boolean; oldtop: disprange;

    >           llc,lcm: addrrange; lbname: integer; markp: marktype;

    1535c1535

    <           llc: addrrange; count,lsize: integer;

    ---

    >           llc,lsize: addrrange; count: integer;

    1819c1819

    <           i, entname, segsize: integer;

    ---

    >           entname, segsize: integer;

    2087c2087

    <         var lattr: attr; lcp: ctp; lsize,lmin,lmax: integer;

    ---

    >         var lattr: attr; lcp: ctp; lsize: addrrange; lmin,lmax: integer;

    2248c2248

    <             var lcp:ctp; llev:levrange; laddr:addrrange;

    ---

    >             var llev:levrange; laddr:addrrange;

    2306c2306

    <                 lcp:ctp; llev:levrange; laddr,len:addrrange;

    ---

    >                 llev:levrange; laddr,len:addrrange;

    2456,2457c2456,2457

    <             var lsp,lsp1: stp; varts,lmin,lmax: integer;

    <                 lsize,lsz: addrrange; lval: valu;

    ---

    >             var lsp,lsp1: stp; varts: integer;

    >                 lsize: addrrange; lval: valu;

    2750c2750

    <                     cstpart: set of 0..47; lsp: stp;

    ---

    >                     cstpart: setty; lsp: stp;



Unix pc can't cope with this line:

    2926c2926

    <             (*/*)     rdiv: begin

    ---

    >             (* / *)   rdiv: begin



More unused variables:

    3318c3318

    <           var lattr: attr; lsp: stp;  lsy: symbol;

    ---

    >           var lattr: attr;  lsy: symbol;

    3642c3642

    <     var sp: stp;

    ---

    > 



Produce code as default:

    3800c3800

    <     prtables := false; list := true; prcode := false; debug := true;

    ---

    >     prtables := false; list := true; prcode := true; debug := true;



Unused variable:

    3868c3868

    <       var i: integer; ch: char;

    ---

    >       var i: integer;



Other compilers need to rewrite prr before using it:

    3995,3996c3995,3996

    <   (*compile:*)

    <   (**********)

    ---

    >   (*compile:*) rewrite(prr); (*comment this out when compiling with pcom *)

    >   (**********)



Differences in the interpreter are minimal: a set type has been added:



    45a46

    >       settype     = set of 0..58;

    63c64

    <                                 sett       :(vs :set of 0..47);

    ---

    >                                 sett       :(vs :settype);

    225c226

    <       var name :alfa;  b :boolean;  r :real;  s :set of 0..58;

    ---

    >       var name :alfa;  b :boolean;  r :real;  s :settype;



End of differences

