home *** CD-ROM | disk | FTP | other *** search
- (***************************************************************************
-
- $RCSfile: OCS.mod $
- Description: Implements the lexical scanner and error reporting
-
- Created by: fjc (Frank Copeland)
- $Revision: 4.10 $
- $Author: fjc $
- $Date: 1994/09/03 14:35:10 $
-
- Copyright © 1990-1993, ETH Zuerich
- Copyright © 1993-1994, Frank Copeland
- This module forms part of the OC program
- See OC.doc for conditions of use and distribution
-
- Log entries are at the end of the file.
-
- ***************************************************************************)
-
- MODULE OCS;
-
- (*
- ** $C= CaseChk $I= IndexChk $L= LongAdr $N= NilChk
- ** $P- PortableCode $R= RangeChk $S= StackChk $T= TypeChk
- ** $V= OvflChk $Z= ZeroVars
- *)
-
- IMPORT Files, IO := StdIO, Str := Strings, OCRev, OCG, SYS := SYSTEM;
-
- (* --- Exported objects ------------------------------------------------- *)
-
- (* Symbols *)
-
- CONST
- null * = 0; times * = 1; slash * = 2; div * = 3; mod * = 4;
- and * = 5; plus * = 6; minus * = 7; or * = 8; eql * = 9;
- neq * = 10; lss * = 11; leq * = 12; gtr * = 13; geq * = 14; in * = 15;
- is * = 16; arrow * = 17; period * = 18; comma * = 19; colon * = 20;
- upto * = 21; rparen * = 22; rbrak * = 23; rbrace * = 24; of * = 25;
- then * = 26; do * = 27; to * = 28; lparen * = 29; lbrak * = 30;
- lbrace * = 31; not * = 32; becomes * = 33; number * = 34; nil * = 35;
- string * = 36; ident * = 37; semicolon * = 38; bar * = 39; end * = 40;
- else * = 41; elsif * = 42; until * = 43; if * = 44; case * = 45;
- while * = 46; repeat * = 47; loop * = 48; with * = 49; exit * = 50;
- return * = 51; array * = 52; record * = 53; pointer * = 54;
- cpointer * = 55; bpointer * = 56; begin * = 57; const * = 58;
- type * = 59; var * = 60; procedure * = 61; import * = 62;
- module * = 63; libcall * = 64; eof * = 65; by * = 66; for * = 67;
-
- CONST
- maxStrLen = 256;
-
- (* name, numtyp, intval, realval, lrlval are implicit results of Get () *)
-
- VAR
- numtyp * : INTEGER; (* 1 = char, 2 = integer, 3 = real, 4 = longreal *)
- intval * : LONGINT;
- realval * : REAL;
- lrlval * : LONGREAL;
- scanerr * : BOOLEAN;
- name * : ARRAY maxStrLen OF CHAR;
-
- (* compiler switches *)
-
- allowGlobalSwitches *, portableCode *, copyDynArray *, typeCheck *,
- overflowCheck *, indexCheck *, rangeCheck *, caseCheck *, zeroVars *,
- longVars *, nilCheck *, returnCheck *, garbageCollect *, stackCheck*,
- saveAllRegs*, saveRegs*
- (*createObj * *)
- : BOOLEAN;
-
- binErrFile * : BOOLEAN;
-
- (* --- Local objects ---------------------------------------------------- *)
-
- CONST
- KW = 43; (* size of hash table *)
- maxDig = 32;
- DigitString = "0123456789ABCDEF";
-
- (* Default compiler switches *)
-
- DefPortableCode = TRUE; DefCopyDynArray = TRUE; DefTypeCheck = TRUE;
- DefOverflowCheck = TRUE; DefIndexCheck = TRUE; DefRangeCheck = TRUE;
- DefCaseCheck = TRUE; DefZeroVars = FALSE; DefLongVars = FALSE;
- DefNilCheck = TRUE; DefReturnCheck = TRUE; DefGarbageCollect = TRUE;
- DefStackCheck = TRUE; DefSaveAllRegs = FALSE; DefSaveRegs = FALSE;
- (*DefCreateObj = TRUE;*)
-
- VAR
- R : Files.Rider;
- W : Files.Rider;
- ch : CHAR; (* current character *)
- lastpos : LONGINT; (* error position in file *)
- i : INTEGER;
- keyTab : ARRAY KW OF
- RECORD
- symb, alt, alt2 : INTEGER;
- id : ARRAY 12 OF CHAR;
- END; (* Ptr *)
- errorFile : Files.File;
- Digit : ARRAY 17 OF CHAR;
- line, col : INTEGER;
- bumpLine : BOOLEAN;
- filename : ARRAY 32 OF CHAR;
-
-
- (*------------------------------------*)
- (* $D- disable copying of open arrays *)
- PROCEDURE WriteStr (s : ARRAY OF CHAR);
-
- BEGIN (* WriteStr *)
- Files.WriteBytes (W, s, SYS.STRLEN (s));
- END WriteStr;
-
- (*------------------------------------*)
- PROCEDURE WriteInt (i : LONGINT);
-
- (*------------------------------------*)
- PROCEDURE WriteDigit (i : LONGINT);
-
- BEGIN (* WriteDigit *)
- IF i > 0 THEN
- WriteDigit (i DIV 10);
- Files.Write (W, Digit [i MOD 10]);
- END; (* IF *)
- END WriteDigit;
-
- BEGIN (* WriteInt *)
- IF i = 0 THEN
- Files.Write (W, "0");
- ELSE
- IF i < 0 THEN
- Files.Write (W, "-");
- END; (* IF *)
- WriteDigit (ABS (i));
- END; (* ELSE *)
- END WriteInt;
-
- (*------------------------------------*)
- PROCEDURE Mark * (n : INTEGER);
-
- (* CONST name = "Mark"; *)
-
- VAR pos : LONGINT;
-
- BEGIN (* Mark *)
- scanerr := TRUE; pos := Files.Pos (R);
-
- (*
- IF OCG.Trace THEN
- OCG.WriteStr ("Mark: line "); OCG.WriteInt (line);
- OCG.WriteStr (", col "); OCG.WriteInt (col);
- OCG.WriteStr (": err = "); OCG.WriteInt (n);
- OCG.WriteStr ("\n");
- lastpos := pos
- ELSIF OCG.Verbose OR (lastpos # pos) THEN
- *)
- IF pos > (lastpos + 4) THEN
- IF binErrFile THEN
- IF errorFile # NIL THEN
- Files.WriteBytes (W, line, 2);
- Files.WriteBytes (W, col, 2);
- Files.WriteBytes (W, n, 2);
- END
- ELSE
- IF errorFile # NIL THEN
- WriteStr (" line "); WriteInt (line);
- WriteStr (", col "); WriteInt (col);
- WriteStr (": err = "); WriteInt (n);
- Files.Write (W, 0AX);
- END
- END;
- lastpos := pos
- END
- (* END *)
- END Mark;
-
- (*------------------------------------*)
- PROCEDURE GetCh ();
-
- BEGIN (* GetCh *)
- IF bumpLine THEN
- INC (line); col := 0; bumpLine := FALSE;
- (*IF OCG.Trace THEN
- IF ~OCG.Verbose THEN IO.WriteInt (line); IO.Write (0DX) END
- ELSIF OCG.Verbose OR ((line MOD 10) = 0) THEN*)
- IF ~OCG.Verbose & ((line MOD 10) = 0) THEN
- IO.WriteInt (line); IO.Write (0DX)
- END
- END;
-
- Files.Read (R, ch);
-
- IF ch = 0AX THEN bumpLine := TRUE
- ELSIF ch = 09X THEN INC (col, 8)
- ELSE INC (col)
- END;
-
- IF (*OCG.Trace &*) OCG.Verbose THEN
- IO.WriteF2 ("%ld:%ld\r", LONG (line), LONG (col))
- END
- END GetCh;
-
- (*------------------------------------*)
- PROCEDURE Hval (ch : CHAR) : INTEGER;
-
- VAR d : INTEGER;
-
- BEGIN (* Hval *)
- d := ORD (ch) - 30H; (* d >= 0 *)
- IF d >= 10 THEN
- IF (d >= 17) & (d < 23) THEN
- DEC (d, 7);
- ELSE
- d := 0;
- Mark (2);
- END; (* ELSE *)
- END; (* IF *)
- RETURN d
- END Hval;
-
- (*------------------------------------*)
- PROCEDURE String (VAR sym : INTEGER; startCh : CHAR);
-
- VAR i, j, val : INTEGER;
-
- BEGIN (* String *)
- i := 0;
- LOOP
- GetCh ();
- IF ch = startCh THEN EXIT
- ELSIF ch < " " THEN Mark (3); EXIT
- END;
-
- IF ~portableCode THEN (* process escaped chars in string or char *)
- IF ch = 5CX THEN
- GetCh (); IF ch < " " THEN Mark (3); EXIT END;
- CASE ch OF
- "b" : ch := 08X | (* BS *)
- "e" : ch := 1BX | (* ESC *)
- "f" : ch := 0CX | (* FF *)
- "n" : ch := 0AX | (* LF *)
- "0", "o" : ch := 00X | (* NUL*)
- "r" : ch := 0DX | (* CR *)
- "t" : ch := 09X | (* HT *)
- "v" : ch := 0BX | (* VT *)
- "x" : (* hexadecimal value *)
- GetCh (); IF ch < " " THEN Mark (3); EXIT END;
- val := Hval (ch) * 16;
- GetCh (); IF ch < " " THEN Mark (3); EXIT END;
- val := val + Hval (ch);
- ch := CHR (val);
- |
- ELSE (* insert following character = do nothing *)
- END;
- END;
- END; (* IF *)
-
- IF i < maxStrLen - 1 THEN
- name [i] := ch;
- INC (i)
- ELSE
- Mark (212); i := 0
- END;
- END; (* LOOP *)
- GetCh ();
- sym := string;
- name [i] := 0X;
- intval := i
- END String;
-
- (*------------------------------------*)
- PROCEDURE Identifier (VAR sym : INTEGER);
-
- VAR i, k : INTEGER;
-
- BEGIN (* Identifier *)
- i := 0; k := 0;
- REPEAT
- IF i < (maxStrLen - 1) THEN
- name [i] := ch; INC (i);
- (*$V- ignore overflows*)
- INC (k, ORD (ch));
- (*$V+*)
- END; (* IF *)
- GetCh ();
- UNTIL (ch < "0") OR (ch > "9") & (CAP (ch) < "A") OR (CAP (ch) > "Z");
-
- name [i] := 0X;
- (*$V- ignore overflows*)
- k := (k + i) MOD KW; (* hash function *)
- (*$V=*)
-
- IF (keyTab [k].symb # 0) & (keyTab [k].id = name) THEN
- sym := keyTab [k].symb;
- ELSE
- i := k; k := keyTab [i].alt;
- IF (keyTab [k].symb # 0) & (keyTab [k].id = name) THEN
- sym := keyTab [k].symb;
- ELSE
- k := keyTab [i].alt2;
- IF (keyTab [k].symb # 0) & (keyTab [k].id = name) THEN
- sym := keyTab [k].symb;
- ELSE
- sym := ident;
- END
- END
- END
- END Identifier;
-
- (*------------------------------------*)
- PROCEDURE TenL (e : INTEGER) : LONGREAL;
-
- VAR result : LONGREAL;
-
- BEGIN (* TenL *)
- result := 1.0;
- WHILE e > 0 DO result := result * 10.0; DEC (e) END;
- RETURN result
- END TenL;
-
- (*------------------------------------*)
- PROCEDURE Ten (e : INTEGER) : REAL;
-
- VAR result : REAL;
-
- BEGIN (* Ten *)
- result := 1.0;
- WHILE e > 0 DO result := result * 10.0; DEC (e) END;
- RETURN result
- END Ten;
-
- (*------------------------------------*)
- PROCEDURE Number;
-
- VAR
- i, j, h, d, e, n : INTEGER;
- x, f : REAL;
- y, g : LONGREAL;
- lastCh : CHAR;
- neg : BOOLEAN;
- dig : ARRAY maxDig OF CHAR;
-
- (*------------------------------------*)
- PROCEDURE ReadScaleFactor ();
-
- BEGIN (* ReadScaleFactor *)
- GetCh ();
- IF ch = "-" THEN
- neg := TRUE;
- GetCh ();
- ELSE
- neg := FALSE;
- IF ch = "+" THEN GetCh () END;
- END; (* ELSE *)
- IF ("0" <= ch) & (ch <= "9") THEN
- REPEAT
- e := e * 10 + ORD (ch) - 30H;
- GetCh ();
- UNTIL (ch < "0") OR ("9" < ch);
- ELSE
- Mark (2);
- END; (* ELSE *)
- END ReadScaleFactor;
-
- BEGIN (* Number *)
- i := 0;
- REPEAT
- dig [i] := ch; INC (i); GetCh ();
- UNTIL (ch < "0") OR ("9" < ch) & (CAP (ch) < "A") OR ("Z" < CAP (ch));
- lastCh := ch; j := 0;
- WHILE (j < i - 1) & (dig [j] = "0") DO INC (j) END;
- IF ch = "." THEN
- GetCh ();
- IF ch = "." THEN lastCh := 0X; ch := 7FX; END;
- END; (* IF *)
- IF lastCh = "." THEN (* decimal point *)
- h := i;
- WHILE ("0" <= ch) & (ch <= "9") DO (* read fraction *)
- IF i < maxDig THEN dig [i] := ch; INC (i) END;
- GetCh ();
- END; (* WHILE *)
- IF ch = "D" THEN (* LONGREAL *)
- y := 0; g := 1; e := 0;
- WHILE j < h DO y := y * 10 + (ORD (dig [j]) - 30H); INC (j) END;
- WHILE j < i DO
- g := g / 10; y := (ORD (dig [j]) - 30H) * g + y; INC (j)
- END;
- ReadScaleFactor ();
- IF neg THEN
- IF e <= OCG.MaxLExp THEN y := y / TenL (e) ELSE y := 0 END;
- ELSIF e > 0 THEN
- IF e <= OCG.MaxLExp THEN y := TenL (e) * y
- ELSE y := 0; Mark (203)
- END
- END; (* ELSE *)
- numtyp := 4; lrlval := y;
- ELSE
- x := 0; f := 1; e := 0;
- WHILE j < h DO x := x * 10 + (ORD (dig [j]) - 30H); INC (j) END;
- WHILE j < i DO
- f := f / 10; x := (ORD (dig [j]) - 30H) * f + x; INC (j)
- END;
- IF ch = "E" THEN ReadScaleFactor() END;
- IF neg THEN
- IF e <= OCG.MaxExp THEN x := x / Ten (e) ELSE x := 0 END;
- ELSE
- IF e <= OCG.MaxExp THEN x := Ten (e) * x
- ELSE x := 0; Mark (203)
- END;
- END; (* ELSE *)
- numtyp := 3; realval := x;
- END; (* ELSE *)
- ELSE (* Integer *)
- lastCh := dig [i - 1]; intval := 0;
- IF lastCh = "H" THEN (* hex number *)
- IF j < (i - 1) THEN
- DEC (i); intval := Hval (dig [j]); INC (j);
- IF i - j <= 7 THEN
- IF (i - j = 7) & (intval >= 8) THEN DEC (intval, 16) END;
- WHILE j < i DO
- intval := Hval (dig [j]) + intval * 10H; INC (j)
- END;
- ELSE
- Mark (203)
- END; (* ELSE *)
- END; (* IF *)
- ELSIF lastCh = "X" THEN (* character code in hex *)
- DEC (i);
- WHILE j < i DO
- intval := Hval (dig [j]) + intval * 10H; INC (j);
- IF intval > OCG.MaxChar THEN Mark (203); intval := 0 END;
- END; (* WHILE *)
- ELSE (* decimal *)
- WHILE j < i DO
- d := ORD (dig [j]) - 30H;
- IF d < 10 THEN
- IF intval <= (MAX (LONGINT) - d) DIV 10 THEN
- intval := intval * 10 + d;
- ELSE
- Mark (203); intval := 0;
- END;
- ELSE
- Mark (2); intval := 0;
- END; (* ELSE *)
- INC (j);
- END; (* WHILE *)
- END; (* ELSE *)
- IF lastCh = "X" THEN numtyp := 1 ELSE numtyp := 2 END;
- END; (* ELSE *)
- END Number;
-
- (*------------------------------------*)
- PROCEDURE Get * (VAR sym : INTEGER);
-
- VAR
- s : INTEGER;
-
- (*------------------------------------*)
- PROCEDURE Comment (); (* do not read after end of file *)
-
- VAR swCh : CHAR; sw : BOOLEAN; cline, ccol : INTEGER;
-
- BEGIN (* Comment *)
- cline := line; ccol := col;
- GetCh ();
- LOOP
- LOOP
- WHILE ch = "(" DO
- GetCh ();
- IF ch = "*" THEN Comment (); END;
- END; (* WHILE *)
- WHILE ch = "$" DO
- GetCh ();
- IF ch # "*" THEN
- swCh := ch; GetCh ();
- IF ch = "=" THEN
- IF (swCh = "P") OR (swCh = "G") THEN
- IF allowGlobalSwitches THEN
- IF swCh = "P" THEN portableCode := DefPortableCode
- ELSIF swCh = "G" THEN garbageCollect := DefGarbageCollect
- END
- ELSE
- IO.WriteStr (" !! Invalid location for global compiler switch\n")
- END
- ELSE
- CASE swCh OF
- "D" : copyDynArray := DefCopyDynArray
- |
- "T" : typeCheck := DefTypeCheck
- |
- "V" : overflowCheck := DefOverflowCheck
- |
- "I" : indexCheck := DefIndexCheck
- |
- "R" : rangeCheck := DefRangeCheck
- |
- "C" : caseCheck := DefCaseCheck
- |
- "L" : longVars := DefLongVars
- |
- "N" : nilCheck := DefNilCheck
- |
- "r" : returnCheck := DefReturnCheck
- |
- "S" : stackCheck := DefStackCheck
- |
- "Z" : zeroVars := DefZeroVars
- |
- "A" : saveAllRegs := DefSaveAllRegs
- |
- "s" : saveRegs := DefSaveRegs
- |
- ELSE
- IO.WriteStr (" !! Unrecognised compiler switch\n")
- END; (* CASE swCh *)
- END; (* ELSE *)
- ELSIF (ch = "+") OR (ch = "-") THEN
- sw := (ch = "+");
- IF (swCh = "P") OR (swCh = "G") THEN
- IF allowGlobalSwitches THEN
- IF swCh = "P" THEN portableCode := sw
- ELSIF swCh = "G" THEN garbageCollect := sw
- END
- ELSE
- IO.WriteStr (" !! Invalid location for global compiler switch\n")
- END
- ELSE
- CASE swCh OF
- "D" : copyDynArray := sw
- |
- "T" : typeCheck := sw
- |
- "V" : overflowCheck := sw
- |
- "I" : indexCheck := sw
- |
- "R" : rangeCheck := sw
- |
- "C" : caseCheck := sw
- |
- "L" : longVars := sw
- |
- "N" : nilCheck := sw
- |
- "r" : returnCheck := sw
- |
- "S" : stackCheck := sw
- |
- "Z" : zeroVars := sw
- |
- "A" : saveAllRegs := sw
- |
- "s" : saveRegs := sw
- |
- ELSE
- IO.WriteStr (" !! Unrecognised compiler switch\n")
- END; (* CASE swCh *)
- END; (* ELSE *)
- END; (* IF *)
- END; (* IF *)
- END; (* WHILE *)
- IF ch = "*" THEN GetCh (); EXIT; END;
- IF ch = 0X THEN EXIT; END;
- GetCh ();
- END; (* LOOP *)
- IF ch = ")" THEN GetCh (); EXIT; END;
- IF ch = 0X THEN line := cline; col := ccol; Mark (5); EXIT; END;
- END; (* LOOP *)
- END Comment;
-
- BEGIN (* Get *)
- LOOP (* ignore control characters (and spaces) *)
- IF ch <= " " THEN
- IF ch = 0X THEN
- ch := " "; EXIT;
- ELSE
- GetCh ();
- END; (* ELSE *)
- ELSIF ch > 7FX THEN
- GetCh ();
- ELSE
- EXIT;
- END; (* ELSE *)
- END; (* LOOP *)
- CASE ch OF (* " " <= ch <= 7FX *)
- " " : s := eof; ch := 0X;
- |
- 5CX, "!", "$", "%", "?", "@", "_", "`" : s := null; GetCh ();
- |
- 22X, "'" : String (s, ch);
- |
- "#" : s := neq; GetCh ();
- |
- "&" : s := and; GetCh ();
- |
- "(" :
- GetCh ();
- IF ch = "*" THEN Comment (); Get (s) ELSE s := lparen; END;
- |
- ")" : s := rparen; GetCh ();
- |
- "*" : s := times; GetCh ();
- |
- "+" : s := plus; GetCh ();
- |
- "," : s := comma; GetCh ();
- |
- "-" : s := minus; GetCh ();
- |
- "." :
- GetCh ();
- IF ch = "." THEN GetCh (); s := upto; ELSE s := period; END;
- |
- "/" : s := slash; GetCh ();
- |
- "0" .. "9" : Number (); s := number;
- |
- ":" :
- GetCh ();
- IF ch = "=" THEN GetCh (); s := becomes ELSE s := colon END;
- |
- ";" : s := semicolon; GetCh ();
- |
- "<" :
- GetCh ();
- IF ch = "=" THEN GetCh (); s := leq; ELSE s := lss; END;
- |
- "=" : s := eql; GetCh ();
- |
- ">" :
- GetCh ();
- IF ch = "=" THEN GetCh (); s := geq; ELSE s := gtr; END;
- |
- "A" .. "Z" : Identifier (s);
- |
- "[" : s := lbrak; GetCh ();
- |
- "]" : s := rbrak; GetCh ();
- |
- "^" : s := arrow; GetCh ();
- |
- "a" .. "z" : Identifier (s);
- |
- "{" : s := lbrace; GetCh ();
- |
- "}" : s := rbrace; GetCh ();
- |
- "|" : s := bar; GetCh ();
- |
- "~" : s := not; GetCh ();
- |
- 7FX : s := upto; GetCh ();
- |
- ELSE
- Mark (1001); Mark (ORD (ch))
- END; (* CASE ch *)
- sym := s;
- END Get;
-
- (*------------------------------------*)
- PROCEDURE Init * (source : Files.File);
-
- BEGIN (* Init *)
- ch := " "; scanerr := FALSE; lastpos := -1;
- Files.Set (R, source, 0);
- line := 1; col := 0; bumpLine := FALSE;
- END Init;
-
- (*------------------------------------*)
- (* $D- disable copying of open arrays *)
- PROCEDURE StartModule * (name : ARRAY OF CHAR);
-
- VAR res : LONGINT; tag : ARRAY 5 OF CHAR;
-
- BEGIN (* StartModule *)
- COPY (name, filename); Str.Append (filename, ".err");
- Files.Delete (filename, res);
- errorFile := Files.New (filename);
- IF errorFile = NIL THEN
- IO.WriteF1 (" !! Could not open error file %s\n", SYS.ADR (filename));
- HALT (20)
- END;
- Files.Set (W, errorFile, 0);
- IF binErrFile THEN
- (* Output error file tag 'OAER' *)
- tag := "OAER"; Files.WriteBytes (W, tag, 4)
- ELSE
- WriteStr (OCRev.vers); WriteStr (" : compilation error listing\n");
- WriteStr ("---------------------------------------------------------------------------\n\n");
- WriteStr ("Module: "); WriteStr (name); Files.Write (W, 0AX);
- END;
-
- allowGlobalSwitches := TRUE; portableCode := DefPortableCode;
- copyDynArray := DefCopyDynArray; typeCheck := DefTypeCheck;
- overflowCheck := DefOverflowCheck; indexCheck := DefIndexCheck;
- rangeCheck := DefRangeCheck; caseCheck := DefCaseCheck;
- zeroVars := DefZeroVars; longVars := DefLongVars; nilCheck := DefNilCheck;
- returnCheck := DefReturnCheck; garbageCollect := DefGarbageCollect;
- stackCheck := DefStackCheck; saveAllRegs := DefSaveAllRegs;
- saveRegs := DefSaveRegs;
- (*createObj := DefCreateObj;*)
- END StartModule;
-
- (*------------------------------------*)
- PROCEDURE ResetProcSwitches * ();
-
- BEGIN (* ResetProcSwitches *)
- copyDynArray := DefCopyDynArray; returnCheck := DefReturnCheck;
- saveAllRegs := DefSaveAllRegs; saveRegs := DefSaveRegs
- END ResetProcSwitches;
-
- (*------------------------------------*)
- PROCEDURE EndModule * ();
-
- BEGIN (* EndModule *)
- IF scanerr THEN
- IO.WriteF1 (" >> Error file : %s\n", SYS.ADR (filename));
- Files.Register (errorFile)
- ELSE Files.Purge (errorFile)
- END;
- errorFile := NIL; filename := "";
- Files.Set (R, NIL, 0); Files.Set (W, NIL, 0);
- END EndModule;
-
- (*------------------------------------*)
- (* $D- disable copying of open arrays *)
- PROCEDURE EnterKW (sym : INTEGER; name : ARRAY OF CHAR);
-
- VAR j, k : INTEGER;
-
- BEGIN (* EnterKW *)
- (*$V- ignore overflows*)
- j := 0; k := 0;
- REPEAT
- INC (k, ORD (name [j]));
- INC (j);
- UNTIL name [j] = 0X;
- k := (k + j) MOD KW; (* hash function *)
- (*$V=*)
-
- IF keyTab [k].symb # 0 THEN
- j := k;
- REPEAT INC (k) UNTIL keyTab [k].symb = 0;
- IF keyTab [j].alt = 0 THEN
- keyTab [j].alt := k
- ELSIF keyTab [j].alt2 = 0 THEN
- keyTab [j].alt2 := k
- ELSE
- IO.WriteStr (" !! Invalid keyword table\n");
- HALT (20)
- END; (* ELSE *)
- END; (* IF *)
-
- keyTab [k].symb := sym; COPY (name, keyTab [k].id)
- END EnterKW;
-
- (*------------------------------------*)
- PROCEDURE* CloseErrorFile ();
-
- BEGIN (* CloseErrorFile *)
- IF errorFile # NIL THEN Files.Purge (errorFile); errorFile := NIL END;
- END CloseErrorFile;
-
- BEGIN (* OCS *)
- Digit := DigitString; errorFile := NIL; filename := "";
- SYS.SETCLEANUP (CloseErrorFile);
-
- EnterKW (do, "DO"); EnterKW (if, "IF"); EnterKW (in, "IN");
- EnterKW (is, "IS"); EnterKW (of, "OF"); EnterKW (or, "OR");
- EnterKW (end, "END"); EnterKW (mod, "MOD"); EnterKW (nil, "NIL");
- EnterKW (var, "VAR"); EnterKW (else, "ELSE"); EnterKW (exit, "EXIT");
- EnterKW (then, "THEN"); EnterKW (with, "WITH"); EnterKW (array, "ARRAY");
- EnterKW (begin, "BEGIN"); EnterKW (const, "CONST");
- EnterKW (elsif, "ELSIF"); EnterKW (until, "UNTIL");
- EnterKW (while, "WHILE"); EnterKW (record, "RECORD");
- EnterKW (repeat, "REPEAT"); EnterKW (return, "RETURN");
- EnterKW (procedure, "PROCEDURE"); EnterKW (to, "TO");
- EnterKW (div, "DIV"); EnterKW (loop, "LOOP"); EnterKW (type, "TYPE");
- EnterKW (import, "IMPORT"); EnterKW (module, "MODULE");
- EnterKW (pointer, "POINTER"); EnterKW (case, "CASE");
- EnterKW (cpointer, "CPOINTER"); EnterKW (bpointer, "BPOINTER");
- EnterKW (libcall, "LIBCALL"); EnterKW (by, "BY");
- EnterKW (for, "FOR");
-
- binErrFile := TRUE
- END OCS.
-
- (***************************************************************************
-
- $Log: OCS.mod $
- Revision 4.10 1994/09/03 14:35:10 fjc
- - Imports version string from OCRev instead of OCV.
-
- Revision 4.9 1994/08/02 00:42:11 fjc
- - Exported stackCheck.
- - Changed to write 'OAER' tag to error file.
-
- Revision 4.8 1994/07/26 18:28:34 fjc
- - Make stackCheck a global switch.
-
- Revision 4.7 1994/07/25 00:44:05 fjc
- - Changed GetCh().
-
- Revision 4.6 1994/07/23 15:52:11 fjc
- - Renamed newCheck to nilCheck.
-
- Revision 4.5 1994/07/22 14:00:09 fjc
- - Changed to stop reporting multiple errors at the same
- location.
- - Implemented saveAllRegs compiler switch.
-
- Revision 4.4 1994/07/10 12:47:03 fjc
- - Changed to use new SETCLEANUP format.
- - Commented out tracing code.
- - Added $G and $S compiler switches.
- - Changed $Z to be a global compiler switch.
-
- Revision 4.3 1994/06/17 18:01:12 fjc
- - Implemented binary error files.
-
- Revision 4.2 1994/06/10 13:08:45 fjc
- - Fixed infinite loop bug in String() when processing
- escaped characters.
- - Removed support for multi-line strings, this is now
- handled in Compiler.Factor() by concatenating strings.
-
- Revision 4.1 1994/06/01 09:33:44 fjc
- - Bumped version number
-
- ***************************************************************************)
-
-