| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717 |
- (* Renamed for readability. Semantics unchanged. Original identifiers: see docs/compiler/ + src/compiler/RENAME-MAP.md. *)
- IMPLEMENTATION MODULE Scanner;
- IMPORT Compiler, Files, Texts, ComLine, Loader, Doubles, Errors, SymTab, CodeGen;
- FROM SYSTEM IMPORT ADR, MOVE, CODE, TSIZE, BYTE, OVERFLOW, REALOVERFLOW;
- FROM STORAGE IMPORT ALLOCATE,MARK,RELEASE;
- VAR withSave: RecordPtr;
- tokLen: CARDINAL;
- CONST FREEMARKER = 3AE3H;
- CONST EOT = 032C; DEL = 177C;
- CONST LINEFEED = 012C; TAB = 011C; CR = 015C;
- VAR stackLimit [0316H]: ADDRESS;
- VAR buffer [0080H]: ARRAY [0..127] OF CHAR;
- VAR bufIndex[006CH]: CARDINAL;
- VAR filePos [006EH]: CARDINAL;
- VAR column [0070H]: CARDINAL;
- VAR flag [0072H]: CARDINAL;
- CONST EXPECTED = " expected, but ";
- (* $[+ remove procedure names *)
- PROCEDURE ScanErr(c: CARDINAL);
- BEGIN
- Errors.ReportError(c);
- END ScanErr;
- PROCEDURE ChangeEx(VAR f: ARRAY OF CHAR; e: Ext; x: BOOLEAN);
- VAR i: CARDINAL;
- BEGIN
- i := 0;
- WHILE (i < HIGH(f) - 3) AND (f[i] <> 0C) AND (f[i] <> '.') DO
- INC(i)
- END;
- IF x OR (f[i] <> '.') THEN
- f[i] := '.';
- MOVE(ADR(e), ADR(f[i+1]), 3);
- END;
- END ChangeEx;
- PROCEDURE EnterMod(m: ARRAY OF CHAR; k: CARDINAL): CARDINAL;
- VAR i: CARDINAL;
- ptr : POINTER TO SymTab.Symbol;
- BEGIN
- i := 0;
- WHILE (i < SymTab.moduleCount) AND (SymTab.moduleTable^[i].name <> m) DO
- INC(i)
- END;
- ptr := ADR(SymTab.moduleTable^[i]);
- IF i < SymTab.moduleCount THEN
- IF ptr^.word <> k THEN Errors.ReportErrorWithText(12, ptr^.name) END;
- ELSE
- IF i > 15 THEN ScanErr(84) END;
- ptr^.name := m;
- ptr^.word := k;
- INC(SymTab.moduleCount);
- END;
- RETURN i
- END EnterMod;
- PROCEDURE Allocate(VAR a:ADDRESS; n:CARDINAL); (* was in Z80 code *)
- BEGIN
- ALLOCATE(a, n);
- RETURN;
- (* padding to compensate for length difference *)
- n := n+n+n+n+n+n+n+n+n+n+n+n+n+n+n+n+n+n+n+n+n+n+n+n+n+n+n+n+n+n;
- RETURN; RETURN;
- END Allocate;
- PROCEDURE GetStack(VAR m: ADDRESS);
- BEGIN
- m := stackLimit - 60;
- END GetStack;
- PROCEDURE CheckStk(m: ADDRESS);
- BEGIN
- stackLimit := m + 60;
- m^ := FREEMARKER;
- END CheckStk;
- (* proc 22: find identifier in keyword list *)
- PROCEDURE FindIden(l: List; i: ADDRESS; c: BOOLEAN): RecordPtr;
- (* original was in Z80 code *)
- VAR current: T1;
- BEGIN
- current := l^.first;
- WHILE current <> NIL DO
- IF StrCmp(i, current^.link1, c) THEN
- RETURN ADDRESS(current)
- END;
- current := current^.link0;
- END;
- RETURN NIL;
- (* padding to compensate for different length *)
- c := NOT NOT NOT NOT NOT NOT NOT NOT NOT NOT NOT NOT NOT NOT NOT
- NOT NOT NOT NOT NOT NOT NOT NOT NOT NOT NOT c
- END FindIden;
- (* original was in Z80 code; the decompiled StringPtr-param form is rejected
- by v1.00 at the FindIden call site (pointer-type mismatch). ADDRESS
- params with a local byte-overlay generate identical indexed-byte code.
- Case handling: none (as decompiled — c unused). *)
- TYPE ByteVec = POINTER TO ARRAY [0..32767] OF CHAR;
- PROCEDURE StrCmp(a, b: ADDRESS; c: BOOLEAN):BOOLEAN;
- VAR x, y: ByteVec;
- BEGIN
- x := a; y := b;
- WHILE x^[0] = y^[0] DO
- IF x^[0] = 0C THEN RETURN TRUE END;
- x := ADR(x^[1]);
- y := ADR(y^[1]);
- END;
- RETURN FALSE;
- END StrCmp;
- (* StrLen: original was Z80 code *)
- PROCEDURE StrLen(VAR s: ARRAY OF CHAR): CARDINAL;
- VAR i: CARDINAL;
- BEGIN
- i := 0;
- WHILE (i < HIGH(s)) AND (s[i] # 0C) DO INC(i) END;
- IF i # 0 THEN RETURN i END;
- RETURN 1; (* never return a zero length *)
- END StrLen;
- PROCEDURE CopyStr(VAR d: ADDRESS; VAR s: ARRAY OF CHAR);
- VAR length: CARDINAL;
- BEGIN
- length := StrLen(s);
- Allocate(d, length+1);
- MOVE(ADR(s), d, length);
- END CopyStr;
- PROCEDURE NewNode(k:CARDINAL):ADDRESS;
- VAR ptr: Compiler.RecordPtr;
- BEGIN
- Allocate(ptr, 14);
- ptr^.word4 := k;
- RETURN ptr
- END NewNode;
- PROCEDURE NewSized(k:CARDINAL):ADDRESS;
- VAR ptr: Compiler.RecordPtr;
- BEGIN
- IF k <= 1 THEN Allocate(ptr, 14)
- ELSIF k <= 6 THEN Allocate(ptr, 10)
- ELSIF k <= 11 THEN Allocate(ptr, 12)
- ELSE Allocate(ptr, 16)
- END;
- ptr^.word4 := k;
- RETURN ptr
- END NewSized;
- PROCEDURE MakeIden(k: CARDINAL): ADDRESS;
- VAR ptr : Compiler.RecordPtr;
- BEGIN
- NeedID;
- IF ADDRESS(scopeCur) = SymTab.currentScope THEN Errors.ReportErrorWithText(1, tokBuf) END;
- ptr := NewNode(k);
- CopyStr(ptr^.word1, tokBuf);
- GetSym;
- RETURN ptr
- END MakeIden;
- PROCEDURE InsertSy(n: SymTab.T1);
- BEGIN
- IF FindIden(ADR(SymTab.currentScope^.link1), n^.link1, 9 IN scanOpt) # NIL THEN
- Errors.ReportErrorWithText(1, n^.link1^)
- END;
- n^.link0 := SymTab.currentScope^.link1;
- SymTab.currentScope^.link1 := n;
- END InsertSy;
- PROCEDURE DeclIden(k: CARDINAL): ADDRESS;
- VAR ptr: SymTab.T1;
- BEGIN
- ptr := MakeIden(k);
- ptr^.link0 := SymTab.currentScope^.link1;
- SymTab.currentScope^.link1 := ptr;
- RETURN ptr;
- END DeclIden;
- PROCEDURE OpenScop(a:ADDRESS; b: ADDRESS);
- BEGIN
- Allocate(SymTab.currentScope, 14);
- SymTab.currentScope^.w0 := a;
- SymTab.currentScope^.link1 := b;
- END OpenScop;
- PROCEDURE WritList;
- VAR PipeChar[034EH]: CHAR;
- BEGIN
- Texts.WriteLn(2);
- IF listing
- THEN Texts.WriteCard(2, CodeGen.nextEmitPos - codeSize, 4)
- ELSE Texts.SetCol(2, 4)
- END;
- Texts.WriteChar(2, PipeChar);
- Texts.WriteChar(2, ' ')
- END WritList;
- PROCEDURE EchoChar;
- BEGIN
- IF (ORD(curCh) + 1) MOD 256 > 32 THEN Texts.WriteChar(2, curCh); RETURN END;
- IF curCh = LINEFEED THEN column := 0; WritList; RETURN END;
- IF curCh = TAB THEN
- REPEAT Texts.WriteChar(2," "); INC(column) UNTIL column MOD 8 = 0;
- ELSIF (curCh < " ") AND (curCh # CR) THEN
- Texts.WriteChar(2, "^");
- Texts.WriteChar(2, CHR(ORD(curCh)+40H))
- END;
- END EchoChar;
- PROCEDURE Refill;
- VAR nbRead: CARDINAL;
- BEGIN
- nbRead := Files.ReadBytes(srcFile, ADR(buffer), 128);
- IF nbRead < 128 THEN buffer[nbRead] := EOT END;
- bufIndex := 0;
- NextCh
- END Refill;
- PROCEDURE InitScan;
- BEGIN
- curCh := ' ';
- column := 0;
- bufIndex := 128;
- IF 0 IN scanOpt THEN WritList END;
- Files.NoTrailer(srcFile)
- END InitScan;
- PROCEDURE OpenSrc;
- VAR nbRead: CARDINAL;
- BEGIN
- IF NOT Files.Open(srcFile, ComLine.inName) THEN HALT END;
- InitScan;
- Files.SetPos(srcFile, LONG((tokPos DIV 128) * 128));
- nbRead := Files.ReadBytes(srcFile, ADR(buffer), 128);
- bufIndex := tokPos MOD 128;
- filePos := tokPos;
- GetSym
- END OpenSrc;
- PROCEDURE NextCh; (* original was in Z80 code *)
- VAR ch: CHAR;
- BEGIN
- IF bufIndex = 128 THEN Refill
- ELSE
- ch := buffer[bufIndex];
- INC(bufIndex);
- IF ch = EOT THEN curCh := 377C ELSE curCh := ch END;
- INC(filePos);
- IF 0 IN scanOpt THEN
- IF ch >= ' ' THEN
- INC(column);
- IF flag # 0 THEN
- Texts.WriteChar(3, ch);
- RETURN; RETURN; (* padding *)
- END;
- END;
- EchoChar
- END;
- END;
- RETURN;
- (* padding to compensate for smaller length *)
- INC(ch); INC(ch); INC(ch); INC(ch); INC(ch); INC(ch);
- INC(ch); INC(ch); INC(ch); INC(ch); RETURN; RETURN; RETURN; RETURN;
- END NextCh;
- PROCEDURE GetSym;
- (* $[- keep procedure names *)
- (* proc 35 *)
- PROCEDURE ParseNum;
- VAR intPart: CARDINAL;
- VAR expVal: CARDINAL;
- VAR curDig: CARDINAL;
- VAR prevDig: CARDINAL;
- VAR limit: CARDINAL;
- VAR expAdj: INTEGER;
- VAR negExp: BOOLEAN;
- VAR isDec : BOOLEAN;
- VAR isOctal: BOOLEAN;
- VAR decVal: LONGINT;
- VAR decFull: LONGINT;
- VAR octVal: LONGINT;
- VAR hexVal: LONGINT;
-
- (* $[+ remove procedure names *)
-
- (* proc 36 *)
- PROCEDURE Power10(exp: CARDINAL): REAL;
- VAR i: CARDINAL;
- VAR r: REAL;
- BEGIN
- i := 0;
- r := 1.0;
- REPEAT
- IF ODD(exp) THEN
- CASE i OF
- | 0 : r := r * 1.0E01
- | 1 : r := r * 1.0E02
- | 2 : r := r * 1.0E04
- | 3 : r := r * 1.0E08
- | 4 : r := r * 1.0E16
- | 5 : r := r * 1.0E32
- ELSE RAISE REALOVERFLOW
- END;
- END;
- exp := exp DIV 2;
- INC(i);
- UNTIL exp = 0;
- RETURN r
- END Power10;
-
- PROCEDURE AccumDig;
- VAR digit: CARDINAL;
- BEGIN
- IF tokLen < 128 THEN tokBuf[tokLen] := curCh; INC(tokLen) END;
- NextCh;
- digit := ORD(curCh) - ORD('0');
- IF digit > 9 THEN
- IF digit >= 17 THEN digit := digit - 7 ELSE digit := 16 END;
- END; (* 043C *)
- curDig := digit
- END AccumDig;
-
- (* $[- keep procedure names *)
- BEGIN (* ParseNum *)
- intPart := 0;
- decVal := LONG(0);
- expAdj := 0;
- hexVal := decVal;
- octVal := decVal;
- decFull := decVal;
- tokLen:= 0;
- curDig := ORD(curCh) - ORD('0');
- prevDig := curDig;
- isOctal := TRUE;
- isDec := TRUE;
- REPEAT
- IF prevDig > 7 THEN
- isOctal := FALSE;
- IF prevDig > 9 THEN isDec := FALSE END;
- END;
- IF curDig <= 9 THEN
- decFull := decFull * LONG(10) + LONG(curDig);
- IF decFull < 3355443L THEN decVal := decFull ELSE INC(expAdj) END;
- IF curDig <= 7 THEN octVal := octVal * LONG(8) + LONG(curDig) END;
- END; (* 04b1 *)
- IF hexVal <= LONG(65535) THEN hexVal := hexVal * LONG(16) + LONG(curDig) END;
- prevDig := curDig;
- AccumDig;
- UNTIL curDig > 15;
- litType := Compiler.CardType;
- IF curCh = '.' THEN
- AccumDig;
- IF curCh = '.' THEN curCh := DEL; DEC(tokLen)
- ELSIF curCh = ')' THEN curCh := ']'; DEC(tokLen)
- ELSE
- IF NOT isDec THEN ScanErr(30) END;
- litType := Compiler.RealType;
- WHILE curDig <= 9 DO
- IF decVal < 3355443L THEN
- decVal := decVal * LONG(10) + LONG(curDig);
- DEC(expAdj)
- END; (* 0527 *)
- AccumDig;
- END; (* 052B *)
- IF curDig IN {13, 14} THEN
- IF curDig = 13 THEN litType := Compiler.LongrealType END;
- expVal := 0;
- AccumDig;
- negExp := (curCh = '-');
- IF negExp OR (curCh = '+') THEN AccumDig END;
- IF curDig > 9 THEN ScanErr(30) END;
- REPEAT
- IF expVal < 255 THEN expVal := expVal * 10 + curDig END;
- AccumDig;
- UNTIL curDig > 9;
- IF negExp
- THEN DEC(expAdj, expVal)
- ELSE INC(expAdj, expVal)
- END;
- END; (* 0577 *)
- IF litType = Compiler.RealType THEN
- IF decVal >= 16777216L
- THEN realVal := FLOAT((decVal + LONG(1)) DIV LONG(2)) * 2.0
- ELSE realVal := FLOAT(decVal)
- END;
- IF expAdj < 0 THEN realVal := realVal / Power10(-expAdj)
- ELSIF expAdj # 0 THEN realVal := realVal * Power10(expAdj)
- END;
- ELSE
- tokBuf[tokLen] := 0C;
- IF NOT Doubles.StrToDouble(tokBuf, lrealVal) THEN ScanErr(74) END;
- END;
- END;
- END; (* 05D4 *)
- IF litType^.word4 # 8 THEN
- IF curCh = 'L' THEN
- AccumDig;
- realVal := REAL(decFull);
- litType := Compiler.LongintType;
- ELSE
- limit := 65535;
- IF curCh = 'H' THEN AccumDig; decVal := hexVal
- ELSE
- IF prevDig IN {11, 12} THEN
- IF NOT isOctal THEN ScanErr(30) END;
- decVal := octVal;
- IF prevDig = 12 THEN litType := Compiler.CharType; limit := 255 END;
- ELSE
- IF NOT isDec OR (prevDig > 9) THEN ScanErr(30) END;
- decVal := decFull;
- END;
- END; (* 062e *)
- IF decVal > LONG(limit) THEN ScanErr(73) END;
- cardVal := CARD(decVal);
- END;
- END; (* 063f *)
- IF charClas^[ORD(curCh)] = 10 THEN ScanErr(30) END;
- EXCEPTION
- | OVERFLOW: ScanErr(73)
- | REALOVERFLOW:
- IF expAdj >= 0 THEN ScanErr(74) END;
- realVal := REAL(0L);
- END ParseNum;
-
- (* $[+ remove procedure names *)
- PROCEDURE SkipComm;
- VAR optIdx: CARDINAL;
- BEGIN
- REPEAT
- REPEAT
- IF curCh = CHR(255) THEN ScanErr(29) END;
- NextCh;
- IF curCh = '(' THEN
- REPEAT NextCh UNTIL curCh # '(';
- IF curCh = '*' THEN SkipComm END; (* recursive call *)
- END;
- IF curCh = '$' THEN
- NextCh;
- optIdx := CARDINAL(BITSET(curCh) * {0,1,2,3,4,6}) - ORD('L');
- IF optIdx <= 15 THEN
- NextCh;
- IF curCh = '-' THEN EXCL(scanOpt, optIdx)
- ELSIF curCh = '+' THEN INCL(scanOpt, optIdx)
- END;
- IF optIdx = 0 THEN Texts.WriteLn(2) END;
- END;
- END; (* 06c6 *)
- UNTIL curCh = '*';
- REPEAT NextCh UNTIL curCh # '*';
- UNTIL curCh = ')';
- END SkipComm;
- PROCEDURE ScanNext():BOOLEAN; (* original was in Z80 code *)
- VAR j: CARDINAL;
- VAR nextClass: CARDINAL;
- BEGIN
- isLit := FALSE;
- identKd := 7;
- WHILE curCh <= ' ' DO NextCh END;
- tokPos := filePos - 1;
- tokCol := column;
- IF curCh < CHR(128)
- THEN curSym := charClas^[ORD(curCh)]
- ELSE curSym := 0
- END;
- IF curSym = 10 THEN
- j := 0;
- REPEAT
- IF j # 128 THEN tokBuf[j] := curCh; INC(j) END;
- NextCh;
- nextClass := charClas^[ORD(curCh)];
- UNTIL (nextClass # 10) AND (nextClass # 11);
- tokBuf[j] := 0C;
- RETURN TRUE
- END; (* 0730 *)
- RETURN FALSE;
- (* padding to compensate for smaller code *)
- j := j+j+j+j+j+j+j+j+j+j+j+j+j+j+j+j+j+j+j+j+j+j+j+j+j+j+j+j
- END ScanNext;
- VAR tokDone: BOOLEAN;
- strLen: CARDINAL;
- ignCase: BOOLEAN;
- quote: CHAR;
- BEGIN
- REPEAT
- IF ScanNext() THEN
- ignCase := 9 IN scanOpt;
- curSym := keyHash(ADR(tokBuf), ignCase);
- IF curSym # 0 THEN
- identKd := 7;
- IF ((curSym = 14) OR (curSym = 39)) AND NOT (12 IN scanOpt) THEN
- Errors.AskContinue(2)
- END;
- RETURN
- END; (* 0797 *)
- scopeCur := ADDRESS(SymTab.currentScope);
- REPEAT
- curNode := FindIden(ADR(scopeCur^.link1), ADR(tokBuf), ignCase);
- IF curNode # NIL THEN
- litType := ADDRESS(curNode^.word2);
- identKd := curNode^.word4;
- follSet := curNode^.word3;
- RETURN
- END;
- scopeCur := scopeCur^.link0;
- UNTIL scopeCur = NIL;
- identKd := 0;
- RETURN
- END; (* 07BA *)
- tokDone := TRUE;
- CASE curSym OF
- | 0 : ScanErr(31 - ORD(curCh = CHR(255)) * 2)
- | 2 : NextCh;
- IF curCh = '=' THEN curSym := 27; NextCh
- ELSIF curCh = ')' THEN curSym := 7; NextCh
- END;
- | 3 : NextCh;
- IF curCh = '.' THEN curSym := 4; NextCh
- ELSIF curCh = ')' THEN curSym := 6; NextCh
- END;
- |11 : isLit := TRUE;
- identKd := 1;
- curSym := 0;
- ParseNum;
- tokBuf[tokLen] := 0C
- |12 : strLen := 0;
- isLit := TRUE;
- identKd := 1;
- curSym := 0;
- quote := curCh;
- NextCh;
- WHILE curCh # quote DO
- IF curCh = LINEFEED THEN ScanErr(28) END;
- IF curCh = CHR(255) THEN ScanErr(29) END;
- IF strLen < 128 THEN
- tokBuf[strLen] := curCh;
- INC(strLen);
- END;
- NextCh;
- END; (* 0839 *)
- tokBuf[strLen] := 0C;
- NextCh;
- litType := Compiler.charArrayDesc;
- IF strLen = 1 THEN
- litType := Compiler.CharType;
- cardVal := ORD(tokBuf[0]);
- END;
- ELSE
- NextCh;
- CASE curSym OF
- | 43: IF curCh = '*' THEN SkipComm; NextCh; tokDone := FALSE
- ELSIF curCh = '.' THEN curSym := 44; NextCh
- ELSIF curCh = ':' THEN curSym := 45; NextCh
- END;
- | 54: IF curCh = '=' THEN curSym := 56; NextCh
- ELSIF curCh = '>' THEN curSym := 53; NextCh
- END;
- | 55: IF curCh = '=' THEN curSym := 57; NextCh END;
- END;
- END;
- UNTIL tokDone;
- END GetSym;
- PROCEDURE AcceptSy(s: CARDINAL): BOOLEAN;
- BEGIN
- IF curSym = s THEN GetSym; RETURN TRUE END;
- RETURN FALSE
- END AcceptSy;
- PROCEDURE PushWith;
- BEGIN
- IF identKd = 6 THEN
- withSave^.word1 := ADDRESS(curNode^.high);
- withSave^.word0 := ADDRESS(SymTab.currentScope);
- SymTab.currentScope := ADDRESS(withSave);
- GetSym;
- ExpectSy(3);
- NeedID;
- IF scopeCur # ADDRESS(withSave) THEN Errors.ReportErrorWithText(3, tokBuf) END;
- SymTab.currentScope := SymTab.currentScope^.w0;
- END;
- END PushWith;
- PROCEDURE ExpectSy(s:CARDINAL);
- VAR expSet: BITSET;
- VAR base: CARDINAL;
- BEGIN
- IF curSym = s THEN GetSym; RETURN END;
- base := 0;
- expSet := {};
- IF s >= 51 THEN base := 51
- ELSIF s >= 40 THEN base := 40
- ELSIF s >= 27 THEN base := 27
- ELSIF s >= 13 THEN base := 13
- END;
- expSet := expSet + {s - base};
- Errors.ReportExpectedSet(expSet, base)
- END ExpectSy;
- PROCEDURE TestSet(s: BITSET);
- BEGIN
- IF NOT (curSym IN s) THEN Errors.ReportExpectedSet(s, 0) END;
- END TestSet;
- PROCEDURE TestR40(s: BITSET);
- BEGIN
- IF NOT ((curSym-40) IN s) THEN Errors.ReportExpectedSet(s, 40) END;
- END TestR40;
- PROCEDURE TestR13(s: BITSET);
- BEGIN
- IF NOT ((curSym-13) IN s) THEN Errors.ReportExpectedSet(s, 13) END;
- END TestR13;
- PROCEDURE NeedID;
- BEGIN
- IF (identKd = 7) OR isLit THEN
- Errors.ShowErrorPosition('A');
- Texts.WriteString(3, "Identifier");
- Texts.WriteString(3, EXPECTED);
- Errors.WriteFoundToken;
- Errors.AskEditOrQuit;
- END;
- END NeedID;
- PROCEDURE ExpectSt(VAR p: ARRAY OF CHAR);
- BEGIN
- NeedID;
- IF StrCmp(ADR(tokBuf), ADR(p), 9 IN scanOpt) THEN GetSym; RETURN END;
- Errors.ReportErrorWithText(9, p);
- END ExpectSt;
- PROCEDURE ExpectKd(k: CARDINAL);
- BEGIN
- IF identKd # k THEN
- NeedID;
- IF identKd = 0 THEN Errors.ReportErrorWithText(0, tokBuf) END;
- Errors.ShowErrorPosition('B');
- Errors.WriteKindName(k);
- Texts.WriteString(3, EXPECTED);
- Errors.WriteKindName(identKd);
- Texts.WriteString(3, " found");
- Errors.AskEditOrQuit;
- END;
- END ExpectKd;
- PROCEDURE Compile;
- (* Z80 proc 40 removed in Reloaded; v1.00 rejects SYSTEM.ADR on simple
- unstructured variables, so this open-array shim recovers the address.
- Proven on hardware: open VAR ARRAY OF WORD accepts any variable, and
- ADR(x) inside is legal (probe ZZ.DEF/MOD). *)
- PROCEDURE VarAddr(VAR x: ARRAY OF WORD): ADDRESS;
- BEGIN
- RETURN ADR(x);
- END VarAddr;
- VAR addr: ADDRESS;
- ptr [006EH]: CARDINAL;
- console [0072H]: BOOLEAN;
- jmpOpc [0074H]: CARDINAL;
- jmpAddr[0075H]: CARDINAL;
- (* $[- keep procedure names *)
- BEGIN
- jmpOpc := 0C3H;
- addr := VarAddr(scanOpt)-6;
- addr := ADDRESS(addr^) - 4;
- jmpAddr:= addr + CARDINAL(addr^) + 3;
- MARK(addr);
- ptr := 0;
- console := (ComLine.outName = "CON:");
- listing := FALSE;
- tokPos := 0;
- Allocate(withSave, 14);
- Compiler.OpenSourceAndOutput;
- IF srcFile <> NIL THEN
- Allocate(codeBuf, 4096);
- Loader.Call("COMPILE");
- IF Compiler.nativeCodeRequested THEN
- CheckStk(codeBuf + CodeGen.nextEmitPos);
- IF CodeGen.windowBase <> 0 THEN
- MOVE(codeBuf, codeBuf + CodeGen.windowBase, CodeGen.nextEmitPos - CodeGen.windowBase);
- Files.SetPos(codeFile, LONG(0));
- IF Files.ReadBytes(codeFile, codeBuf, CodeGen.windowBase) <> CodeGen.windowBase THEN
- RAISE Files.EndError
- END;
- END;
- Files.SetPos(codeFile, LONG(0));
- Loader.Call("GENZ80");
- END;
- END;
- Texts.CloseText(Texts.output);
- RELEASE(addr);
- EXCEPTION Loader.LoadError:
- Texts.WriteLn(3); (* console *)
- Texts.WriteString(3,"ERROR: CANNOT LOAD OVERLAY");
- Texts.WriteLn(3);
- Files.Delete(codeFile);
- RELEASE(addr)
- END Compile;
- (* $[+ remove procedure names *)
- END Scanner.
|