|
|
@@ -63,7 +63,7 @@ FROM Runtime IMPORT RT_Build, RT_Size, RT_Byte, RT_Entry, LoadBias ;
|
|
|
encodings (the entry JMP, every CALL and JMP) must NOT get it: both
|
|
|
operands shift together and the +0100h cancels. *)
|
|
|
|
|
|
-FROM CompilerShared IMPORT MaxCode, CodeMax, EMemOvf, ECompOvf,
|
|
|
+FROM CompilerShared IMPORT MaxCode, CodeMax, EUnknown, EMemOvf, ECompOvf,
|
|
|
EFileNF, EInclNest, OK,
|
|
|
PatchRec, cbuf, pc, imgReady, patches, nPatch,
|
|
|
srcPos, abortFac, errNum, txerrPos, Err ;
|
|
|
@@ -74,6 +74,9 @@ FROM CompilerSource IMPORT CurCh, GetCh, PeekAhead, Upper, SetSourcePath, Expand
|
|
|
FROM CompilerUtil IMPORT Digit, Alpha, AlphaNum, IsHexCh, W16, DropCh,
|
|
|
DropB, DropC, BitAnd, BitOr, BitNot, NameEq,
|
|
|
CopyStr, NumToName ;
|
|
|
+FROM CompilerSymbols IMPORT MaxName, SymEntry, symtab, symTop, lexnest, wrd,
|
|
|
+ NewSym, Search, DupTest, HideLocals,
|
|
|
+ CopyWord, SaveWord ;
|
|
|
|
|
|
(* ---------------------------------------------------------------- *)
|
|
|
(* constants *)
|
|
|
@@ -81,7 +84,6 @@ FROM CompilerUtil IMPORT Digit, Alpha, AlphaNum, IsHexCh, W16, DropCh,
|
|
|
|
|
|
CONST
|
|
|
MaxLine = 128 ;
|
|
|
- MaxName = 63 ;
|
|
|
|
|
|
(* Size of the entry jump at image offset 0: E9 lo hi. The jump's
|
|
|
displacement is relative to the END of the jump, so every offset in the
|
|
|
@@ -99,7 +101,6 @@ CONST
|
|
|
moved. *)
|
|
|
DataStart = 0A000H ; (* image offset of the first global (memory 0A100h) *)
|
|
|
|
|
|
- MaxSym = 3000 ;
|
|
|
MaxPend = 400 ;
|
|
|
MaxFields = 2000 ; (* record fields, in a table of their own: a
|
|
|
field is scoped to its record, not global *)
|
|
|
@@ -193,7 +194,7 @@ CONST
|
|
|
|
|
|
(* TP3 error numbers *)
|
|
|
ENoSemi = 1 ; EPointExp = 10 ; ESimpType = 30 ;
|
|
|
- EUnknown = 41 ; EConstRange = 45 ; ENoLib = 102 ; ETypeErr = 56 ;
|
|
|
+ EConstRange = 45 ; ENoLib = 102 ; ETypeErr = 56 ;
|
|
|
EIoHere = 66 ; (* I/O not allowed here - TPSRC8 prderrtp *)
|
|
|
|
|
|
AposC = 39 ; (* ORD ("'") - avoids quote-in-quote *)
|
|
|
@@ -203,36 +204,6 @@ CONST
|
|
|
(* ---------------------------------------------------------------- *)
|
|
|
|
|
|
TYPE
|
|
|
- SymEntry =
|
|
|
- RECORD
|
|
|
- name : ARRAY [0..MaxName] OF CHAR ;
|
|
|
- tag : CARDINAL ;
|
|
|
- cls : CARDINAL ;
|
|
|
- size : CARDINAL ;
|
|
|
- elem : CARDINAL ;
|
|
|
- off : CARDINAL ;
|
|
|
- lval : LONGINT ;
|
|
|
- lo, hi : LONGINT ; (* an ORDINAL type's bounds: an enumeration
|
|
|
- (0..n-1) or a subrange. Needed so
|
|
|
- `set of T' can size its base. *)
|
|
|
- fldFirst, fldLast : CARDINAL ; (* a RECORD type's field range in the
|
|
|
- field table (0,0 when not a record) *)
|
|
|
- arrIdx : CARDINAL ; (* an ARRAY type's shape in ArrRec (0 = no) *)
|
|
|
- parmFirst, parmCount : CARDINAL ; (* a PROCEDURE/FUNCTION's parameters:
|
|
|
- symtab indices, in declaration order *)
|
|
|
- isKbd : BOOLEAN ; (* the predefined KBD file: reads are console *)
|
|
|
- isPort : BOOLEAN ; (* the predefined PORT byte array *)
|
|
|
- isVar : BOOLEAN ; (* a VAR parameter: the slot holds an address *)
|
|
|
- level : CARDINAL ;
|
|
|
- local : BOOLEAN ;
|
|
|
- parent : CARDINAL ; (* lexical parent procedure, 0 at top level *)
|
|
|
- staticOff : CARDINAL ; (* nested proc's hidden static-link local *)
|
|
|
- resvar : CARDINAL ;
|
|
|
- goPos : CARDINAL ;
|
|
|
- defnd : BOOLEAN ;
|
|
|
- fwd : BOOLEAN ;
|
|
|
- END ;
|
|
|
-
|
|
|
PendRec =
|
|
|
RECORD
|
|
|
kind : CARDINAL ; (* 0 goto, 1 call *)
|
|
|
@@ -290,11 +261,7 @@ TYPE
|
|
|
ecls : CARDINAL ; (* element CLASS, for a subscripted value *)
|
|
|
fldFirst, fldLast : CARDINAL ; (* leaf record metadata *)
|
|
|
elemType : CARDINAL ;
|
|
|
- elemLo, elemHi : LONGINT ;
|
|
|
- fieldPtrElem : CARDINAL ;
|
|
|
- variantBase, armRunning, armMax, savePosVar : CARDINAL ;
|
|
|
- moreFields : BOOLEAN ;
|
|
|
- tagName : ARRAY [0..MaxName] OF CHAR ; (* pointer target / named element type *)
|
|
|
+ elemLo, elemHi : LONGINT ; (* leaf element subrange bounds *)
|
|
|
END ;
|
|
|
|
|
|
(* ---------------------------------------------------------------- *)
|
|
|
@@ -313,8 +280,6 @@ VAR
|
|
|
constBlob : ARRAY [0..511] OF CHAR ; (* bytes of a set/array typed constant
|
|
|
while it is being built *)
|
|
|
|
|
|
- wrd : ARRAY [0..MaxName] OF CHAR ;
|
|
|
-
|
|
|
(* String-literal pool.
|
|
|
|
|
|
TP3 does not put a literal in the data segment at all: it emits the
|
|
|
@@ -331,9 +296,6 @@ VAR
|
|
|
strCnt : CARDINAL ; (* literals collected so far *)
|
|
|
rdStrX : CARDINAL ; (* pool index of the literal RdConst just read *)
|
|
|
|
|
|
- symtab : ARRAY [0..MaxSym - 1] OF SymEntry ;
|
|
|
- symTop : CARDINAL ;
|
|
|
-
|
|
|
pend : ARRAY [0..MaxPend - 1] OF PendRec ;
|
|
|
nPend : CARDINAL ;
|
|
|
|
|
|
@@ -452,7 +414,6 @@ VAR
|
|
|
on the stack, limit in CX; exit code 16 if the
|
|
|
result would be too long *)
|
|
|
|
|
|
- lexnest : CARDINAL ;
|
|
|
curProc : CARDINAL ; (* symbol of the procedure body being compiled *)
|
|
|
curStaticOff : CARDINAL ; (* its hidden static-link slot, 0 if none *)
|
|
|
curIsFunc : BOOLEAN ;
|
|
|
@@ -951,145 +912,6 @@ END EmRet ;
|
|
|
(* symbol table *)
|
|
|
(* ---------------------------------------------------------------- *)
|
|
|
|
|
|
-PROCEDURE CopyWord (name : ARRAY OF CHAR) ;
|
|
|
-(* stash current word into global wrd (uppercased) *)
|
|
|
-VAR i : CARDINAL ;
|
|
|
-BEGIN
|
|
|
- i := 0 ;
|
|
|
- LOOP
|
|
|
- IF i > HIGH (name) THEN
|
|
|
- wrd [i] := 0C ;
|
|
|
- RETURN
|
|
|
- END ;
|
|
|
- IF i > MaxName THEN
|
|
|
- wrd [MaxName] := 0C ;
|
|
|
- RETURN
|
|
|
- END ;
|
|
|
- IF name [i] = 0C THEN
|
|
|
- wrd [i] := 0C ;
|
|
|
- RETURN
|
|
|
- END ;
|
|
|
- wrd [i] := Upper (name [i]) ;
|
|
|
- INC (i)
|
|
|
- END
|
|
|
-END CopyWord ;
|
|
|
-
|
|
|
-PROCEDURE SaveWord (VAR dst : ARRAY OF CHAR) ;
|
|
|
-(* copy wrd into dst *)
|
|
|
-VAR i : CARDINAL ;
|
|
|
-BEGIN
|
|
|
- i := 0 ;
|
|
|
- LOOP
|
|
|
- IF i > HIGH (dst) THEN
|
|
|
- dst [HIGH (dst)] := 0C ;
|
|
|
- RETURN
|
|
|
- END ;
|
|
|
- IF i > MaxName THEN
|
|
|
- dst [MaxName] := 0C ;
|
|
|
- RETURN
|
|
|
- END ;
|
|
|
- dst [i] := wrd [i] ;
|
|
|
- IF wrd [i] = 0C THEN
|
|
|
- RETURN
|
|
|
- END ;
|
|
|
- INC (i)
|
|
|
- END
|
|
|
-END SaveWord ;
|
|
|
-
|
|
|
-PROCEDURE NewSym (name : ARRAY OF CHAR ; tag : CARDINAL ;
|
|
|
- cls, size, elem, off : CARDINAL ; v : LONGINT ;
|
|
|
- local : BOOLEAN) : CARDINAL ;
|
|
|
-VAR e : SymEntry ;
|
|
|
-BEGIN
|
|
|
- IF symTop >= MaxSym THEN
|
|
|
- Err (ECompOvf) ;
|
|
|
- RETURN 0
|
|
|
- END ;
|
|
|
- CopyWord (name) ;
|
|
|
- CopyStr (e.name, wrd) ;
|
|
|
- e.tag := tag ;
|
|
|
- e.cls := cls ;
|
|
|
- e.size := size ;
|
|
|
- e.elem := elem ;
|
|
|
- e.off := off ;
|
|
|
- e.lval := v ;
|
|
|
- e.lo := 0 ;
|
|
|
- e.hi := 0 ;
|
|
|
- e.fldFirst := 0 ;
|
|
|
- e.fldLast := 0 ;
|
|
|
- e.arrIdx := 0 ;
|
|
|
- e.parmFirst := 0 ;
|
|
|
- e.parmCount := 0 ;
|
|
|
- e.isKbd := FALSE ;
|
|
|
- e.isPort := FALSE ;
|
|
|
- e.isVar := FALSE ;
|
|
|
- e.level := lexnest ;
|
|
|
- e.local := local ;
|
|
|
- e.parent := 0 ;
|
|
|
- e.staticOff := 0 ;
|
|
|
- e.resvar := 0 ;
|
|
|
- e.goPos := 0 ;
|
|
|
- e.defnd := FALSE ;
|
|
|
- e.fwd := FALSE ;
|
|
|
- symtab [symTop] := e ;
|
|
|
- INC (symTop) ;
|
|
|
- RETURN symTop - 1
|
|
|
-END NewSym ;
|
|
|
-
|
|
|
-PROCEDURE Search (nm : ARRAY OF CHAR ; VAR idx : CARDINAL) : BOOLEAN ;
|
|
|
-(* find nm among symbols visible at the current lexical level *)
|
|
|
-VAR p : CARDINAL ;
|
|
|
-BEGIN
|
|
|
- CopyWord (nm) ;
|
|
|
- p := symTop ;
|
|
|
- WHILE p > 0 DO
|
|
|
- DEC (p) ;
|
|
|
- IF symtab [p].level <= lexnest THEN
|
|
|
- IF NameEq (symtab [p].name, wrd) THEN
|
|
|
- idx := p ;
|
|
|
- RETURN TRUE
|
|
|
- END
|
|
|
- END
|
|
|
- END ;
|
|
|
- RETURN FALSE
|
|
|
-END Search ;
|
|
|
-
|
|
|
-PROCEDURE DupTest (nm : ARRAY OF CHAR) ;
|
|
|
-(* A name may be declared twice only in the SAME scope. This used to reject
|
|
|
- any name Search could see, so a parameter could not shadow a global - legal
|
|
|
- ISO Pascal, and CALC.INC's `procedure IBMCh(var Ch: Char)' does exactly
|
|
|
- that (`Ch' is a global). Same-level duplicates stay errors: two parameters
|
|
|
- in one list, two locals, or two globals. *)
|
|
|
-VAR i : CARDINAL ;
|
|
|
-BEGIN
|
|
|
- IF Search (nm, i) THEN
|
|
|
- IF symtab [i].level = lexnest THEN
|
|
|
- Err (EUnknown)
|
|
|
- END
|
|
|
- END
|
|
|
-END DupTest ;
|
|
|
-
|
|
|
-PROCEDURE HideLocals (from : CARDINAL) ;
|
|
|
-(* Make every symbol from index `from' up invisible to everything outside the
|
|
|
- procedure that declared it.
|
|
|
- Search accepts a symbol when its level is <= lexnest, and every procedure
|
|
|
- body is compiled at the same depth (lexnest 1), so a finished procedure's
|
|
|
- parameters stayed visible to the NEXT procedure: a second `a : integer'
|
|
|
- was a duplicate (err 41) and an unqualified `a' inside procedure two read
|
|
|
- procedure one's argument. Level 0FFFFH fails `level <= lexnest' at every
|
|
|
- depth a later procedure can be at, and by the time this runs the body that
|
|
|
- could still legitimately see them is finished.
|
|
|
- The symbols are relabelled, not popped: symtab[old].resvar holds an INDEX,
|
|
|
- and a function's result variable is one of the entries being hidden. *)
|
|
|
-VAR p : CARDINAL ;
|
|
|
-BEGIN
|
|
|
- p := from ;
|
|
|
- WHILE p < symTop DO
|
|
|
- symtab [p].level := 0FFFFH ;
|
|
|
- INC (p)
|
|
|
- END
|
|
|
-END HideLocals ;
|
|
|
-
|
|
|
(* ---------------------------------------------------------------- *)
|
|
|
(* lexer *)
|
|
|
(* ---------------------------------------------------------------- *)
|