home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-08-08 | 54.9 KB | 1,837 lines |
- (***************************************************************************
-
- $RCSfile: OCT.mod $
- Description: Symbol table handler
-
- Created by: fjc (Frank Copeland)
- $Revision: 4.9 $
- $Author: fjc $
- $Date: 1994/07/26 18:30:02 $
-
- 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 OCT;
-
- (*
- ** $C= CaseChk $I= IndexChk $L= LongAdr $N= NilChk
- ** $P- PortableCode $R= RangeChk $S= StackChk $T= TypeChk
- ** $V= OvflChk $Z= ZeroVars
- *)
-
- IMPORT
- E := Exec, Str := Strings, DU := DosUtil, IO := StdIO, F := Files, OCG,
- OCS, SYS := SYSTEM;
-
-
- (* --- Exported declarations -------------------------------------------- *)
-
- CONST
- maxImps = 32;
-
- (* structure forms *)
- Undef * = 0; Byte * = 1; Bool * = 2; Char * = 3; SInt * = 4; Int * = 5;
- LInt * = 6; Real * = 7; LReal * = 8; BSet * = 9; WSet * = 10; Set * = 11;
- String * = 12; NilTyp * = 13; NoTyp * = 14; PtrTyp * = 15; CPtrTyp * = 16;
- BPtrTyp * = 17; Word * = 18; Longword * = 19; TagTyp * = 20;
- Pointer * = 21; CPointer * = 22; BPointer * = 23; ProcTyp * = 24;
- Array * = 25; DynArr * = 26; Record * = 27;
-
- (* standard procedure codes *)
- pGC * = 0; pRC * = 1;
-
- pABS * = 2; pCAP * = 3; pCHR * = 4; pENTIER * = 5; pHALT * = 6;
- pLONG * = 7; pMAX * = 8; pMIN * = 9; pNEW * = 10; pODD * = 11;
- pORD * = 12; pSHORT * = 13;
-
- pASH * = 24; pASSERT * = 25; pCOPY * = 26; pDEC * = 27; pEXCL * = 28;
- pINC * = 29; pINCL * = 30; pLEN * = 31;
-
- (* module SYSTEM procedure codes *)
- pADR * = 14; pARGLEN * = 15; pARGS * = 16; pDISPOSE * = 17;
- pREG * = 18; pSIZE * = 19; pSTRLEN * = 20; pTAG * = 21; pSIZETAG * = 22;
- pSETCLEANUP * = 23;
-
- pAND * = 32; pBIND * = 33; pBIT * = 34; pGET * = 35; pGETREG * = 36;
- pLSH * = 37; pOR * = 38; pPUT * = 39; pPUTREG * = 40;
- pSETREG * = pPUTREG; pREGISTER * = 41; pROT * = 42; pVAL * = 43;
- pXOR * = 44; pGETNAME * = 45; pNEWTAG * = 46;
-
- pINLINE * = 47; pMOVE * = 48; pSYSNEW * = 49;
-
- LastProc * = pSYSNEW;
- TwoPar * = pASH;
-
- (* String lengths *)
-
- NameLen * = 255;
- PathLen = 256;
- SymbolLen = NameLen * 2 + 1;
-
- (* Variable offsets for OberonSys *)
-
- initialSP * = 0;
- argLen * = initialSP + 4;
- args * = argLen + 4;
- returnCode * = args + 4;
- cleanupProc * = returnCode + 4;
- memList * = cleanupProc + 4;
- mathBase * = memList + 4;
- lmathBase * = mathBase + 4;
- oldTrapCode * = lmathBase + 4;
- oldTrapData * = oldTrapCode + 4;
- untraced * = oldTrapData + 4;
- GCVars * = untraced + 4;
-
- (* Values for visible field of ObjDesc *)
-
- Exp * = -1;
- NotExp * = 0;
- RdOnly * = 1;
-
- TYPE
- Name = ARRAY NameLen + 1 OF CHAR;
- Symbol * = POINTER TO ARRAY (*SymbolLen*) OF CHAR;
-
- Object * = POINTER TO ObjDesc;
- Module * = POINTER TO ModDesc;
- Struct * = POINTER TO StrDesc;
-
- ObjDesc * = RECORD
- left *, right *, link * : Object;
- typ * : Struct;
- a0 *, a1 * : LONGINT;
- a2 * : INTEGER;
- mode * : SHORTINT;
- visible * : SHORTINT;
- name * : LONGINT;
- symbol * : Symbol;
- END; (* ObjDesc *)
-
- ModDesc * = RECORD (ObjDesc)
- varSym *, constSym *, gcSym * : Symbol;
- END; (* ModDesc *)
-
- StrDesc * = RECORD
- form *, n *, mno *, ref * : INTEGER;
- size *, adr * : LONGINT;
- BaseTyp * : Struct;
- link *, strobj * : Object;
- symbol * : Symbol;
- END; (* StrDesc *)
-
- Desc * = POINTER TO DescRec;
- DescRec = RECORD
- next : Desc;
- mode *, lev * : INTEGER;
- a0 *, a1 * : LONGINT;
- a2 * : INTEGER;
- END; (* DescRec *)
-
- Item * = RECORD
- mode *, lev * : INTEGER;
- a0 *, a1 * : LONGINT;
- a2 * : INTEGER;
- typ * : Struct;
- obj * : Object;
- symbol * : Symbol;
- wordIndex *, rdOnly * : BOOLEAN;
- desc * : Desc
- END; (* Item *)
-
- VAR
- topScope * : Object;
-
- undftyp *, bytetyp *, booltyp *, chartyp *, sinttyp *, inttyp *,
- linttyp *, realtyp *, lrltyp *, settyp *, stringtyp *, niltyp *, notyp *,
- ptrtyp *, cptrtyp *, bptrtyp *, bsettyp *, wsettyp *, wordtyp *,
- lwordtyp *, tagtyp *
- : Struct;
-
- nofGmod * : INTEGER; (* nof imports *)
- GlbMod * : ARRAY maxImps OF Module;
-
- ModuleName * : Name;
-
- VarSymbol *, ConstSymbol *, InitSymbol *, GCSymbol *, OberonSysINIT *,
- OberonSysCLEANUP *, OberonSysVAR *, OberonSysNEW *, OberonSysSYSNEW *,
- OberonSysDISPOSE *, OberonSysGC *, OberonSysMUL *, OberonSysDIV *,
- OberonSysMOD *, OberonSysMOVE *, OberonSysPtr *, OberonSysSETCLEANUP *,
- OberonSysREGISTER *, OberonSysSTACKCHK *
- : Symbol;
-
- DestPath * : ARRAY NameLen OF CHAR;
-
-
- (* --- Local declarations ----------------------------------------------- *)
-
-
- CONST
- (* object modes *)
- Var = OCG.Var; VarX = OCG.VarX; VarR = OCG.VarR; Ind = OCG.Ind;
- IndX = OCG.IndX; IndR = OCG.IndR; Con = OCG.Con; Reg = OCG.Reg;
- RegI = OCG.RegI; RegX = OCG.RegX; Fld = OCG.Fld; Typ = OCG.Typ;
- LProc = OCG.LProc; XProc = OCG.XProc; SProc = OCG.SProc;
- LibCall = OCG.LibCall; TProc = OCG.TProc; FProc = OCG.FProc;
- Mod = OCG.Mod; Head = OCG.Head; VarArg = OCG.VarArg;
-
- SFtag = 53594D07H; (* "SYM" + version # *)
- MinSFtag = 53594D07H; (* Earliest version that can be read. *)
- firstStr = 32; maxStr = 512;
- maxUDP = 128; maxMod = 24; maxParLev = 6; maxPaths = 10;
- NotYetExp = 0;
-
- (* terminal symbols for symbol file elements *)
- eUndef = 0; eCon = 1; eTypE = 2; eTyp = 3; eVar = 4; eXProc = 5;
- eLibCall = 6; ePointer = 7; eProcTyp = 8; eArray = 9; eDynArr = 10;
- eRecord = 11; eParList = 12; eValPar = 13; eVarPar = 14; eValRegPar = 15;
- eVarRegPar = 16; eFldList = 17; eFld = 18; eHPtr = 19; eHProc = 20;
- eFixup = 21; eMod = 22; eBPointer = 23; eCPointer = 24; eMod0 = 25;
- eTProcE = 26; eTProc = 27; eVarArg = 28; eFProc = 29;
-
- (* name buffer size *)
-
- BufSize = 16384;
- MaxBuffers = 16;
- HashTableSize = 251;
-
- TYPE
-
- NameBufPtr = POINTER TO ARRAY BufSize OF CHAR;
-
- VAR
- universe, syslink : Object;
- strno, udpinx : INTEGER; (* for export *)
- nofExp : SHORTINT;
- SR : F.Rider;
- undPtr : ARRAY maxUDP OF Struct;
- searchPath : ARRAY maxPaths + 1 OF E.STRPTR;
- pathx : INTEGER;
- nameBuf : ARRAY MaxBuffers OF NameBufPtr;
- nameX, nameOrg, nameSize : LONGINT;
- nameTab, backupTab : ARRAY HashTableSize OF LONGINT;
- ObjectList : Object;
- StructList : Struct;
- DescList : Desc;
-
- (* These are assumed to have all fields zeroed by the loader. *)
- emptyObj : ObjDesc;
- emptyStr : StrDesc;
- emptyDesc : DescRec;
-
- (* CONST mname = "OCT"; *)
-
-
- (* --- Procedure declarations ------------------------------------------- *)
-
-
- (*------------------------------------*)
- PROCEDURE AllocObj * () : Object;
-
- (* CONST name = "AllocObj"; *)
-
- VAR newObj : Object;
-
- BEGIN (* AllocObj *)
- (*OCG.TraceIn (mname, name);*)
- IF ObjectList = NIL THEN
- NEW (newObj)
- ELSE
- newObj := ObjectList; ObjectList := ObjectList.link
- END;
- newObj^ := emptyObj;
- (*OCG.TraceOut (mname, name);*)
- RETURN newObj
- END AllocObj;
-
- (*------------------------------------*)
- PROCEDURE FreeObj * (obj : Object);
-
- (* CONST name = "FreeObj"; *)
-
- BEGIN (* FreeObj *)
- (*OCG.TraceIn (mname, name);*)
- IF obj # NIL THEN
- FreeObj (obj.left); FreeObj (obj.right);
- obj^ := emptyObj;
- obj.link := ObjectList; ObjectList := obj
- END
- (*;OCG.TraceOut (mname, name);*)
- END FreeObj;
-
- (*------------------------------------*)
- PROCEDURE AllocStruct * () : Struct;
-
- (* CONST name = "AllocStruct"; *)
-
- VAR newStr : Struct;
-
- BEGIN (* AllocStruct *)
- (*OCG.TraceIn (mname, name);*)
- IF StructList = NIL THEN
- NEW (newStr)
- ELSE
- newStr := StructList; StructList := StructList.BaseTyp;
- newStr.BaseTyp := NIL
- END;
- (*;OCG.TraceOut (mname, name);*)
- RETURN newStr
- END AllocStruct;
-
- (*------------------------------------*)
- PROCEDURE FreeStruct (str : Struct);
-
- (* CONST name = "FreeStruct"; *)
-
- BEGIN (* FreeStruct *)
- (*OCG.TraceIn (mname, name);*)
- IF str # NIL THEN
- FreeObj (str.link); str^ := emptyStr;
- str.BaseTyp := StructList; StructList := str
- END
- (*;OCG.TraceOut (mname, name);*)
- END FreeStruct;
-
- (*------------------------------------*)
- PROCEDURE AllocDesc * () : Desc;
-
- VAR newDesc : Desc;
-
- (* CONST name = "AllocDesc"; *)
-
- BEGIN (* AllocDesc *)
- (*OCG.TraceIn (mname, name);*)
- IF DescList = NIL THEN NEW (newDesc)
- ELSE newDesc := DescList; DescList := DescList.next; newDesc.next := NIL
- END;
- (*;OCG.TraceOut (mname, name);*)
- RETURN newDesc
- END AllocDesc;
-
- (*------------------------------------*)
- PROCEDURE FreeDesc * (VAR desc : Desc);
-
- (* CONST name = "FreeDesc"; *)
-
- BEGIN (* FreeDesc *)
- (*OCG.TraceIn (mname, name);*)
- IF desc # NIL THEN
- desc^ := emptyDesc; desc.next := DescList; DescList := desc;
- desc := NIL
- END
- (*;OCG.TraceOut (mname, name);*)
- END FreeDesc;
-
- (*------------------------------------*)
- PROCEDURE Init * ();
-
- (* CONST name = "Init"; *)
-
- BEGIN (* Init *)
- (* OCG.TraceIn (mname, name); *)
- topScope := universe; strno := 0; udpinx := 0; nofGmod := 0;
- ModuleName := ""; COPY ("", VarSymbol^); COPY ("", ConstSymbol^);
- COPY ("", InitSymbol^); COPY ("", GCSymbol^)
- (* ;OCG.TraceOut (mname, name); *)
- END Init;
-
- (*------------------------------------*)
- PROCEDURE Close * ();
-
- (* CONST name = "Close"; *)
-
- VAR i : INTEGER;
-
- BEGIN (* Close *)
- (* OCG.TraceIn (mname, name); *)
- F.Set (SR, NIL, 0);
- i := 0; WHILE i < maxImps DO GlbMod [i] := NIL; INC (i) END;
- (* Restore original hash table for reserved names... *)
- nameTab := backupTab; nameX := nameOrg;
- (* ... Assuming that only one name buffer is required *)
- nameSize := BufSize;
- i := 1; WHILE i < MaxBuffers DO nameBuf [i] := NIL; INC (i) END
- (* ;OCG.TraceOut (mname, name); *)
- END Close;
-
- (*------------------------------------*)
- PROCEDURE^ Join
- (module, object : LONGINT; seperator : CHAR; VAR name : ARRAY OF CHAR);
- PROCEDURE^ InsertName * (n : ARRAY OF CHAR) : LONGINT;
-
- PROCEDURE StartModule * ();
-
- (* CONST name = "StartModule"; *)
-
- VAR mn : LONGINT;
-
- BEGIN (* StartModule *)
- (* OCG.TraceIn (mname, name); *)
- mn := InsertName (ModuleName);
- Join (mn, InsertName ("VAR"), "%", VarSymbol^);
- Join (mn, InsertName ("CONST"), "%", ConstSymbol^);
- Join (mn, InsertName ("GC"), "%", GCSymbol^);
- (* ;OCG.TraceOut (mname, name); *)
- END StartModule;
-
- (*------------------------------------*)
- PROCEDURE EndModule * ();
-
- BEGIN (* EndModule *)
- END EndModule;
-
- (*------------------------------------*)
- PROCEDURE CheckBuf (size : LONGINT);
-
- (* CONST name = "CheckBuf"; *)
-
- VAR newBuf : NameBufPtr; newX : LONGINT;
-
- BEGIN (* CheckBuf *)
- (*OCG.TraceIn (mname, name);*)
- newX := nameX + size + 4;
- IF newX >= nameSize THEN
- IF newX >= BufSize * MaxBuffers THEN
- OCS.Mark (310); nameX := 0
- ELSE
- IF ((newX-1) MOD BufSize) < (size+4) THEN nameX := nameSize END;
- NEW (newBuf);
- INC (nameSize, BufSize);
- nameBuf [(nameSize - 1) DIV BufSize] := newBuf
- END
- END
- (*;OCG.TraceOut (mname, name);*)
- END CheckBuf;
-
- (*------------------------------------*)
- (* $D- disable copying of open arrays *)
- PROCEDURE InsertName * (n : ARRAY OF CHAR) : LONGINT;
-
- (* CONST name = "InsertName"; *)
-
- VAR i, j, k, len, bufX : INTEGER; x, x1 : LONGINT; ch : CHAR;
- buf : NameBufPtr;
-
- BEGIN (* InsertName *)
- (*OCG.TraceIn (mname, name);*)
- k := 0; len := 0; ch := n [0];
- WHILE ch # 0X DO
- (*$V- ignore overflows*)
- INC (k, ORD (ch));
- (*$V=*)
- INC (len); ch := n [len]
- END;
- k := (k + len) MOD HashTableSize;
- x := nameTab [k];
- LOOP
- IF x = 0 THEN
- CheckBuf (len);
- buf := nameBuf [nameX DIV BufSize];
- bufX := SHORT (nameX MOD BufSize);
- buf [bufX] := CHR (nameTab [k] DIV 10000H); INC (bufX);
- buf [bufX] := CHR (nameTab [k] DIV 100H); INC (bufX);
- buf [bufX] := CHR (nameTab [k]); INC (bufX);
- i := 0;
- WHILE i <= len DO buf [bufX] := n [i]; INC (bufX); INC (i) END;
- x := nameX + 3; nameTab [k] := x; nameX := nameX + len + 4;
- (*;OCG.TraceOut (mname, name);*)
- RETURN x
- ELSE
- buf := nameBuf [x DIV BufSize];
- bufX := SHORT (x MOD BufSize);
- x1 :=
- (LONG (ORD (buf [bufX - 3])) * 10000H)
- + (LONG (ORD (buf [bufX - 2])) * 100H)
- + LONG (ORD (buf [bufX - 1]));
- i := bufX; j := 0;
- LOOP
- IF buf [i] # n [j] THEN
- x := x1; EXIT
- ELSIF n [j] = 0X THEN
- (*;OCG.TraceOut (mname, name);*)
- RETURN x
- ELSE
- INC (i); INC (j)
- END
- END
- END; (* ELSE *)
- END; (* LOOP *)
- END InsertName;
-
- (*------------------------------------*)
- PROCEDURE NameLength (name : LONGINT) : INTEGER;
-
- (* CONST pname = "NameLength"; *)
-
- VAR buf : NameBufPtr; len, bufX : INTEGER;
-
- BEGIN (* NameLength *)
- (*OCG.TraceIn (mname, pname);*)
- buf := nameBuf [name DIV BufSize];
- bufX := SHORT (name MOD BufSize);
- len := 0;
- WHILE buf [bufX] # 0X DO INC (len); INC (bufX) END;
- (*;OCG.TraceOut (mname, pname);*)
- RETURN len
- END NameLength;
-
- (*------------------------------------*)
- PROCEDURE GetName * (adr : LONGINT; VAR name : ARRAY OF CHAR);
-
- (* CONST pname = "GetName"; *)
-
- VAR buf : NameBufPtr; i, bufX : INTEGER; ch : CHAR;
-
- BEGIN (* GetName *)
- (*OCG.TraceIn (mname, pname);*)
- buf := nameBuf [adr DIV BufSize];
- bufX := SHORT (adr MOD BufSize);
- i := 0;
- REPEAT
- ch := buf [bufX]; name [i] := ch;
- INC (i); INC (bufX)
- UNTIL ch = 0X;
- (*;OCG.TraceOut (mname, pname);*)
- END GetName;
-
- (*------------------------------------*)
- (*$D-*)
- PROCEDURE FindObj (obj : Object; name : ARRAY OF CHAR) : Object;
-
- VAR
- buf : NameBufPtr; n1, n2 : LONGINT; bufX, i : INTEGER; ch1, ch2 : CHAR;
-
- BEGIN (* FindObj *)
- n1 := InsertName (name);
- WHILE (obj # NIL) & (obj.name # n1) DO
- n2 := obj.name; i := 0;
- buf := nameBuf [n2 DIV BufSize]; bufX := SHORT (n2 MOD BufSize);
- REPEAT
- ch1 := name [i]; INC (i);
- ch2 := buf [bufX]; INC (bufX)
- UNTIL ch1 # ch2;
- IF ch1 < ch2 THEN obj := obj.left
- ELSE obj := obj.right
- END
- END;
- RETURN obj
- END FindObj;
-
- (*------------------------------------*)
- PROCEDURE FindImport * (mod : Object; VAR res : Object);
-
- (* CONST name = "FindImport"; *)
-
- VAR obj : Object;
-
- BEGIN (* FindImport *)
- (* OCG.TraceIn (mname, name); *)
- obj := FindObj (mod.link, OCS.name);
- IF (obj # NIL) & (obj.mode = Typ) & (obj.visible = NotExp) THEN
- obj := NIL
- END;
- res := obj
- (* ;OCG.TraceOut (mname, name); *)
- END FindImport;
-
- (*------------------------------------*)
- PROCEDURE Find * (VAR res : Object; VAR level : INTEGER);
-
- (* CONST name = "Find"; *)
-
- VAR obj, head : Object;
-
- BEGIN (* Find *)
- (* OCG.TraceIn (mname, name); *)
- head := topScope;
- LOOP
- obj := FindObj (head.link, OCS.name);
- IF obj # NIL THEN level := SHORT (head.a0); EXIT END;
- head := head.left;
- IF head = NIL THEN level := 0; EXIT END;
- END;
- res := obj;
- (* ;OCG.TraceOut (mname, name); *)
- END Find;
-
- (*------------------------------------*)
- PROCEDURE FindField * (typ : Struct; VAR res : Object);
-
- (* CONST name = "FindField"; *)
-
- VAR obj : Object; typ1 : Struct; n : LONGINT;
-
- BEGIN (* FindField *)
- (* OCG.TraceIn (mname, name); *)
- (* typ.form = Record *)
- typ1 := typ; n := InsertName (OCS.name);
- LOOP
- obj := typ1.link;
- WHILE (obj # NIL) & (obj.name # n) DO obj := obj.left END;
- IF obj # NIL THEN EXIT END;
- typ1 := typ1.BaseTyp;
- IF typ1 = NIL THEN EXIT END
- END;
- IF (obj # NIL) & (obj.mode = LibCall) & (typ1 # typ) THEN obj := NIL END;
- res := obj;
- (* ;OCG.TraceOut (mname, name); *)
- END FindField;
-
- (*------------------------------------*)
- PROCEDURE SuperCall * (pno : LONGINT; typ : Struct; VAR proc : Object);
-
- (* CONST name = "SuperCall"; *)
-
- VAR obj : Object;
-
- BEGIN (* SuperCall *)
- (* OCG.TraceIn (mname, name); *)
- obj := NIL;
- IF (typ # NIL) & (typ.form = Pointer) THEN typ := typ.BaseTyp END;
- IF (typ # NIL) & (typ # undftyp) THEN
- LOOP
- typ := typ.BaseTyp;
- IF typ = NIL THEN EXIT END;
- obj := typ.link;
- WHILE (obj # NIL) & ((obj.mode # TProc) OR (obj.a0 # pno)) DO
- obj := obj.left
- END;
- IF obj # NIL THEN EXIT END
- END
- END;
- proc := obj
- (* ;OCG.TraceOut (mname, name); *)
- END SuperCall;
-
- (*------------------------------------*)
- PROCEDURE NextProc * (typ : Struct) : LONGINT;
-
- (* CONST name = "NextProc"; *)
-
- VAR pno : LONGINT; obj : Object;
-
- BEGIN (* NextProc *)
- (* OCG.TraceIn (mname, name); *)
- (* typ.form = Record *)
- pno := 0;
- REPEAT
- obj := typ.link;
- WHILE obj # NIL DO
- IF (obj.mode = TProc) & (obj.a0 > pno) THEN pno := obj.a0 END;
- obj := obj.left
- END;
- typ := typ.BaseTyp;
- UNTIL typ = NIL;
- (* ;OCG.TraceOut (mname, name); *)
- RETURN pno + 1
- END NextProc;
-
- (*------------------------------------*)
- PROCEDURE InsertObj
- ( VAR name : ARRAY OF CHAR; root : Object; mode : SHORTINT;
- VAR res : Object ) : BOOLEAN;
-
- (* CONST pname = "InsertObj"; *)
-
- VAR
- obj, prev : Object; mod : Module; result : BOOLEAN;
- buf : NameBufPtr; n1, n2 : LONGINT; bufX, i : INTEGER; ch1, ch2 : CHAR;
-
- BEGIN (* InsertObj *)
- (* OCG.TraceIn (mname, pname); *)
-
- prev := root; obj := root.link; n1 := InsertName (name);
- WHILE (obj # NIL) & (obj.name # n1) DO
- prev := obj; n2 := obj.name; i := 0;
- buf := nameBuf [n2 DIV BufSize]; bufX := SHORT (n2 MOD BufSize);
- REPEAT
- ch1 := name [i]; INC (i);
- ch2 := buf [bufX]; INC (bufX)
- UNTIL ch1 # ch2;
- IF ch1 < ch2 THEN obj := obj.left
- ELSE obj := obj.right
- END
- END;
- IF obj = NIL THEN
- IF mode = Mod THEN NEW (mod); obj := mod
- ELSE obj := AllocObj ()
- END;
- obj.name := n1; obj.mode := mode;
- IF prev = root THEN
- root.link := obj
- ELSE
- IF ch1 < ch2 THEN prev.left := obj
- ELSE prev.right := obj
- END
- END;
- result := TRUE
- ELSE
- result := FALSE
- END;
- res := obj;
- (* ;OCG.TraceOut (mname, pname); *)
- RETURN result
- END InsertObj;
-
- (*------------------------------------*)
- PROCEDURE Insert *
- ( VAR name : ARRAY OF CHAR; VAR res : Object; mode : SHORTINT );
-
- (* CONST pname = "Insert"; *)
-
- BEGIN (* Insert *)
- (* OCG.TraceIn (mname, pname); *)
- IF ~InsertObj (name, topScope, mode, res) THEN
- IF res.mode # Undef THEN OCS.Mark (1) END;
- res.mode := mode
- END
- (* ;OCG.TraceOut (mname, pname); *)
- END Insert;
-
- (*------------------------------------*)
- PROCEDURE OpenScope * (level : INTEGER);
-
- (* CONST name = "OpenScope"; *)
-
- VAR head : Object;
-
- BEGIN (* OpenScope *)
- (* OCG.TraceIn (mname, name); *)
- head := AllocObj ();
- head.mode := Head; head.a0 := level; head.left := topScope;
- topScope := head;
- (* ;OCG.TraceOut (mname, name); *)
- END OpenScope;
-
- (*------------------------------------*)
- PROCEDURE CloseScope * ();
-
- (* CONST name = "CloseScope"; *)
-
- VAR oldHead : Object;
-
- BEGIN (* CloseScope *)
- (* OCG.TraceIn (mname, name); *)
- oldHead := topScope; topScope := topScope.left;
- oldHead^ := emptyObj; oldHead.link := ObjectList; ObjectList := oldHead;
- (* ;OCG.TraceOut (mname, name); *)
- END CloseScope;
-
-
- (*--- SYMBOLS ---------------------------------*)
-
-
- (*------------------------------------*)
- PROCEDURE Join
- (name1, name2 : LONGINT; seperator : CHAR; VAR name : ARRAY OF CHAR);
-
- (* CONST pname = "Join"; *)
-
- VAR src, dst : INTEGER; buf : NameBufPtr; ch : CHAR;
-
- BEGIN (* Join *)
- (*OCG.TraceIn (mname, pname);*)
- dst := 0;
-
- buf := nameBuf [name1 DIV BufSize];
- src := SHORT (name1 MOD BufSize);
- ch := buf [src];
- WHILE ch # 0X DO
- name [dst] := ch; INC (src); INC (dst); ch := buf [src]
- END; (* WHILE *)
-
- name [dst] := seperator; INC (dst);
-
- buf := nameBuf [name2 DIV BufSize];
- src := SHORT (name2 MOD BufSize);
- ch := buf [src];
- WHILE ch # 0X DO
- name [dst] := ch; INC (src); INC (dst); ch := buf [src]
- END; (* WHILE *)
-
- name [dst] := 0X
- (*;OCG.TraceOut (mname, pname);*)
- END Join;
-
- (*------------------------------------*)
- PROCEDURE MakeSymbol (
- moduleName, name : LONGINT; seperator : CHAR; VAR symbol : Symbol);
-
- (* CONST pname = "MakeSymbol"; *)
-
- BEGIN (* MakeSymbol *)
- (* OCG.TraceIn (mname, pname); *)
- NEW (symbol, NameLength (moduleName) + NameLength (name) + 4);
- Join (moduleName, name, seperator, symbol^)
- (* ;OCG.TraceOut (mname, pname); *)
- END MakeSymbol;
-
- (*------------------------------------*)
- PROCEDURE MakeInitProcSymbol (
- module, key : LONGINT; VAR symbol : Symbol);
-
- (* CONST name = "MakeInitProcSymbol"; *)
-
- VAR
- keyPart : ARRAY 9 OF CHAR;
- temp : ARRAY 40 OF CHAR;
-
- (*
- (*------------------------------------*)
- PROCEDURE ConvertKey ();
-
- CONST Digits = "0123456789ABCDEF";
-
- VAR HexDigit : ARRAY 17 OF CHAR; i : INTEGER;
-
- BEGIN (* ConvertKey *)
- HexDigit := Digits;
- i := 7;
- WHILE i >= 0 DO
- keyPart [i] := HexDigit [key MOD 16];
- key := key DIV 16;
- DEC (i)
- END; (* WHILE *)
- keyPart [8] := 0X
- END ConvertKey;
- *)
-
- BEGIN (* MakeInitProcSymbol *)
- (* OCG.TraceIn (mname, name); *)
- Join (module, InsertName ("INIT"), "%", temp);
- (* ConvertKey (); *)
- Str.IntToString (key, 16, 8, "0", keyPart);
- IF symbol = NIL THEN
- NEW (symbol, Str.Length (temp) + Str.Length (keyPart) + 4)
- END;
- COPY (temp, symbol^); Str.Append (symbol^, keyPart)
- (* ;OCG.TraceOut (mname, name); *)
- END MakeInitProcSymbol;
-
- (*------------------------------------*)
- PROCEDURE MakeProcSymbol * (obj : Object);
-
- (* CONST name = "MakeProcSymbol"; *)
-
- VAR pnoPart : ARRAY 6 OF CHAR; mn : LONGINT;
-
- BEGIN (* MakeProcSymbol *)
- (* OCG.TraceIn (mname, name); *)
- IF obj.a0 = 0 THEN
- mn := InsertName (ModuleName);
- NEW (obj.symbol, NameLength (mn) + NameLength (obj.name) + 4);
- Join (mn, obj.name, ".", obj.symbol^)
- ELSE
- Str.IntToString (obj.a0, 10, 0, "0", pnoPart);
- NEW (obj.symbol, Str.Length (pnoPart) + Str.Length (ModuleName) + 4);
- COPY (ModuleName, obj.symbol^);
- Str.Append (obj.symbol^, "%"); Str.Append (obj.symbol^, pnoPart)
- END
- (* ;OCG.TraceOut (mname, name); *)
- END MakeProcSymbol;
-
- (*------------------------------------*)
- PROCEDURE MakeImportedTypeSymbol
- (module, adr : LONGINT; VAR symbol : Symbol);
-
- (* CONST name = "MakeImportedTypeSymbol"; *)
-
- VAR sym : Symbol; tnoPart : ARRAY 6 OF CHAR;
-
- BEGIN (* MakeImportedTypeSymbol *)
- (* OCG.TraceIn (mname, name); *)
- Str.IntToString (adr, 10, 0, "0", tnoPart);
- NEW (sym, NameLength (module) + Str.Length (tnoPart) + 8);
- Join (module, InsertName ("TYPE_"), "%", sym^);
- Str.Append (sym^, tnoPart); symbol := sym
- (* ;OCG.TraceOut (mname, name); *)
- END MakeImportedTypeSymbol;
-
- (*------------------------------------*)
- PROCEDURE MakeTypeSymbol * (typ : Struct);
-
- (* CONST name = "MakeTypeSymbol"; *)
-
- VAR tnoPart : ARRAY 6 OF CHAR; sym : Symbol;
-
- BEGIN (* MakeTypeSymbol *)
- (* OCG.TraceIn (mname, name); *)
- Str.IntToString (typ.adr, 10, 0, "0", tnoPart);
- NEW (sym, Str.Length (tnoPart) + Str.Length (ModuleName) + 8);
- COPY (ModuleName, sym^); Str.Append (sym^, "%TYPE_");
- Str.Append (sym^, tnoPart); typ.symbol := sym
- (* ;OCG.TraceOut (mname, name); *)
- END MakeTypeSymbol;
-
- (*------------------------------------*)
- PROCEDURE MakeTProcSymbol * (typSym : Symbol; proc : Object);
-
- (* CONST name = "MakeTProcSymbol"; *)
-
- VAR pnoPart : ARRAY 6 OF CHAR; sym : Symbol;
-
- BEGIN (* MakeTProcSymbol *)
- (* OCG.TraceIn (mname, name); *)
- IF typSym # NIL THEN
- Str.IntToString (proc.a0, 10, 0, "0", pnoPart);
- NEW (sym, Str.Length (pnoPart) + Str.Length (typSym^) + 4);
- COPY (typSym^, sym^); Str.Append (sym^, ".");
- Str.Append (sym^, pnoPart);
- proc.symbol := sym
- END
- (* ;OCG.TraceOut (mname, name); *)
- END MakeTProcSymbol;
-
- (*--- IMPORT ---------------------------------*)
-
- (*------------------------------------*)
- PROCEDURE AddPath * (newPath : E.STRPTR);
-
- BEGIN (* AddPath *)
- IF pathx >= maxPaths THEN
- OCS.Mark (922)
- ELSE
- searchPath [pathx] := newPath; INC (pathx); searchPath [pathx] := NIL
- END; (* ELSE *)
- END AddPath;
-
- (*------------------------------------*)
- PROCEDURE ReadInt(VAR i: LONGINT);
- (*
- Reads integers written in a compacted form. Taken from J. Templ.
- SPARC-Oberon. User's Guide and Implementation. Computersysteme ETH
- Zürich, Technical Report No. 133, June 1990.
- *)
-
- VAR n: LONGINT; s: INTEGER; x: CHAR;
-
- BEGIN
- s := 0; n := 0; F.Read(SR, x);
- WHILE ORD(x) >= 128 DO
- INC(n, ASH(ORD(x) - 128, s)); INC(s, 7); F.Read(SR, x)
- END;
- i := n + ASH(ORD(x) MOD 64 - ORD(x) DIV 64 * 64, s)
- END ReadInt;
-
- (*------------------------------------*)
- PROCEDURE ReadLInt (VAR k : LONGINT);
-
- BEGIN (* ReadLInt *)
- F.ReadBytes (SR, k, 4);
- END ReadLInt;
-
- (*------------------------------------*)
- PROCEDURE ReadId (VAR id : ARRAY OF CHAR);
-
- VAR i : INTEGER; ch : CHAR;
-
- BEGIN (* ReadId *)
- i := 0;
- REPEAT
- F.Read (SR, ch); id [i] := ch; INC (i)
- UNTIL ch = 0X;
- END ReadId;
-
- (*------------------------------------*)
- PROCEDURE Import * (VAR name, FileName : ARRAY OF CHAR);
-
- (* CONST pname = "Import"; *)
-
- VAR
- i, m, s, nofLmod, strno, parlev, fldlev : INTEGER;
- k, l, modname : LONGINT;
- obj : Object;
- modobj : Module;
- class : SHORTINT;
- SymFile : F.File;
- LocMod : ARRAY maxMod OF Module;
- struct : ARRAY maxStr OF Struct;
- lastpar, lastfld : ARRAY maxParLev OF Object;
- pathName : ARRAY 256 OF CHAR;
-
- link : Object;
- typ : Struct;
- a0, a1 : LONGINT;
- a2 : INTEGER;
- mode : SHORTINT;
- visible : SHORTINT;
- symbol : Symbol;
- objName : ARRAY NameLen+1 OF CHAR;
-
- (*------------------------------------*)
- PROCEDURE reversedList (p : Object) : Object;
-
- VAR q, r : Object;
-
- BEGIN (* reversedList *)
- q := NIL;
- WHILE p # NIL DO r := p.link; p.link := q; q := p; p := r END;
- RETURN q
- END reversedList;
-
- BEGIN (* Import *)
- (* OCG.TraceIn (mname, pname); *)
- nofLmod := 0; strno := firstStr; parlev := -1; fldlev := -1;
- IF FileName = "SYSTEM.Sym" THEN
- Insert (name, obj, Mod); obj.link := syslink;
- obj.a0 := 0; obj.typ := notyp
- ELSE
- IF DU.Search (searchPath, FileName, pathName) THEN
- SymFile := F.Old (pathName)
- ELSE
- SymFile := NIL
- END;
- IF SymFile # NIL THEN
- IO.WriteF1 (" << %s", SYS.ADR(pathName));
- F.Set (SR, SymFile, 0); ReadLInt (k);
- IF k = SFtag THEN
- struct [Undef] := undftyp; struct [Byte] := bytetyp;
- struct [Bool] := booltyp; struct [Char] := chartyp;
- struct [SInt] := sinttyp; struct [Int] := inttyp;
- struct [LInt] := linttyp; struct [Real] := realtyp;
- struct [LReal] := lrltyp; struct [Set] := settyp;
- struct [String] := stringtyp; struct [NilTyp] := niltyp;
- struct [NoTyp] := notyp; struct [BSet] := bsettyp;
- struct [WSet] := wsettyp; struct [PtrTyp] := ptrtyp;
- struct [CPtrTyp] := cptrtyp; struct [BPtrTyp] := bptrtyp;
- struct [Word] := wordtyp; struct [Longword] := lwordtyp;
- struct [TagTyp] := tagtyp;
- LOOP (* read next item from symbol file *)
- F.Read (SR, class); IF SR.eof THEN EXIT END;
- link := NIL; typ := NIL; a0 := 0; a1 := 0; a2 := 0;
- mode := Undef; visible := NotExp; symbol := NIL;
- objName := "";
- CASE class OF
- eUndef : OCS.Mark (151);
- |
- eCon .. eXProc, eFProc : (* object *)
- m := 0; ReadInt (l); s := SHORT (l); typ := struct [s];
- CASE class OF
- eCon :
- mode := Con;
- CASE typ.form OF
- Byte, Char, BSet, Bool, SInt, Int, WSet,
- Word, LInt, Real, LReal, Set, Longword :
- ReadInt (a0);
- |
- (*LReal : ReadInt (a0); ReadInt (a1);
- |*)
- String :
- ReadInt (a0); ReadInt (a1);
- IF a1 <= 2 THEN
- ReadInt (l); a2 := SHORT (l); symbol := NIL
- ELSE
- symbol := LocMod[0].constSym
- END
- |
- NilTyp : (* NIL *)
- |
- CPtrTyp, BPtrTyp, CPointer, BPointer, ProcTyp :
- (* This is all VERY dodgy, but ... *)
- ReadInt (a0)
- |
- ELSE
- OCS.Mark (1002); OCS.Mark (typ.form)
- END; (* CASE obj.typ.form *)
- |
- eTypE, eTyp :
- mode := Typ; ReadInt (l); m := SHORT (l);
- IF class = eTypE THEN visible := Exp
- ELSE visible := NotExp
- END
- |
- eVar :
- mode := Var; ReadInt (a0); F.Read (SR, visible)
- |
- eXProc :
- mode := XProc;
- link := reversedList (lastpar [parlev]); DEC (parlev)
- |
- eFProc :
- mode := FProc;
- link := reversedList (lastpar [parlev]); DEC (parlev);
- ReadId (objName); NEW (symbol, Str.Length (objName) + 1);
- COPY (objName, symbol^)
- |
- ELSE
- OCS.Mark (1003); OCS.Mark (class)
- END; (* CASE class *)
- ReadId (objName);
- IF InsertObj (objName, LocMod [m], mode, obj) THEN
- obj.link := link; obj.typ := typ; obj.a0 := a0;
- obj.a1 := a1; obj.a2 := a2; obj.visible := visible;
- obj.symbol := symbol;
- IF class = eXProc THEN
- MakeSymbol (LocMod [m].name, obj.name, ".", obj.symbol);
- ELSIF mode = Typ THEN
- IF typ.strobj = NIL THEN typ.strobj := obj END
- END;
- ELSIF mode = Typ THEN
- FreeStruct (typ); struct [s] := obj.typ
- END
- |
- ePointer .. eRecord, eBPointer, eCPointer :
- (* structure *)
- typ := AllocStruct (); typ.strobj := NIL; typ.ref := 0;
- ReadInt (l); typ.BaseTyp := struct [l];
- ReadInt (l); typ.mno := SHORT (LocMod [l].a0);
- CASE class OF
- ePointer, eBPointer, eCPointer :
- typ.size := OCG.PtrSize; typ.n := 0;
- typ.symbol := OberonSysPtr;
- IF class = ePointer THEN
- typ.form := Pointer; ReadInt (typ.adr);
- IF typ.BaseTyp.form = DynArr THEN
- typ.size := typ.BaseTyp.size;
- MakeImportedTypeSymbol
- (GlbMod [typ.mno-1].name, typ.adr, typ.symbol)
- END
- ELSIF class = eCPointer THEN typ.form := CPointer
- ELSE typ.form := BPointer
- END;
- |
- eProcTyp :
- typ.form := ProcTyp; typ.size := OCG.ProcSize;
- typ.link := reversedList (lastpar [parlev]);
- DEC (parlev);
- |
- eArray :
- typ.form := Array; ReadInt (typ.size);
- ReadInt (typ.adr); ReadInt (l); typ.n := SHORT (l);
- |
- eDynArr :
- typ.form := DynArr; ReadInt (typ.size);
- ReadInt (typ.adr);
- |
- eRecord :
- typ.form := Record;
- ReadInt (typ.size); typ.n := 0;
- typ.link := reversedList (lastfld [fldlev]);
- DEC (fldlev);
- IF typ.BaseTyp = notyp THEN
- typ.BaseTyp := NIL; typ.n := 0;
- ELSE
- typ.n := typ.BaseTyp.n + 1;
- END;
- ReadInt (typ.adr); (* of descriptor *)
- MakeImportedTypeSymbol
- (GlbMod [typ.mno-1].name, typ.adr, typ.symbol);
- |
- ELSE
- OCS.Mark (1004); OCS.Mark (class)
- END; (* CASE class *)
- struct [strno] := typ; INC (strno);
- |
- eParList : (* parameter list start *)
- IF parlev < maxParLev - 1 THEN
- INC (parlev); lastpar [parlev] := NIL;
- ELSE
- OCS.Mark (229)
- END
- |
- eValPar, eVarPar, eValRegPar, eVarRegPar, eVarArg :
- (* parameter *)
- obj := AllocObj ();
- IF class = eValPar THEN obj.mode := Var
- ELSIF class = eVarPar THEN obj.mode := Ind
- ELSIF class = eValRegPar THEN obj.mode := VarR
- ELSIF class = eVarRegPar THEN obj.mode := IndR
- ELSE obj.mode := VarArg
- END;
- ReadInt (l); obj.typ := struct [l];
- ReadInt (obj.a0); ReadId (objName);
- obj.name := InsertName (objName);
- obj.link := lastpar [parlev]; lastpar [parlev] := obj
- |
- eFldList : (* start field list *)
- IF fldlev < maxParLev - 1 THEN
- INC (fldlev); lastfld [fldlev] := NIL;
- ELSE
- OCS.Mark (229);
- END
- |
- eFld :
- obj := AllocObj (); obj.mode := Fld; obj.link := NIL;
- ReadInt (l); obj.typ := struct [l];
- ReadInt (obj.a0); F.Read (SR, obj.visible);
- ReadId (objName); obj.name := InsertName (objName);
- obj.left := lastfld [fldlev]; lastfld [fldlev] := obj
- |
- eLibCall : (* library call procedure *)
- obj := AllocObj (); obj.mode := LibCall;
- ReadInt (l); typ := struct [l];
- ReadInt (l); obj.typ := struct [l];
- ReadInt (obj.a0); ReadId (objName);
- obj.name := InsertName (objName); obj.visible := Exp;
- obj.link := reversedList (lastpar [parlev]); DEC (parlev);
- obj.left := typ.link; typ.link := obj
-
- |
- eTProcE : (* exported type-bound procedure *)
- obj := AllocObj (); obj.mode := TProc;
- ReadInt (l); typ := struct [l];
- ReadInt (l); obj.typ := struct [l];
- ReadInt (obj.a0); ReadId (objName);
- obj.name := InsertName (objName);
- obj.a1 := typ.n; obj.visible := Exp;
- obj.link := reversedList (lastpar [parlev]); DEC (parlev);
- obj.link.a2 := -1; obj.left := typ.link; typ.link := obj;
- MakeTProcSymbol (typ.symbol, obj)
- |
- eTProc : (* hidden type-bound procedure *)
- obj := AllocObj (); obj.mode := TProc; obj.typ := notyp;
- ReadInt (l); typ := struct [l];
- ReadInt (obj.a0); obj.name := -1; obj.visible := NotExp;
- obj.link := NIL; obj.left := typ.link; typ.link := obj;
- MakeTProcSymbol (typ.symbol, obj)
- |
- eHPtr : (* hidden pointer field *)
- obj := AllocObj (); obj.mode := Fld;
- ReadInt (obj.a0); obj.name := -1; obj.typ := notyp;
- obj.visible := NotExp; obj.link := NIL;
- obj.left := lastfld [fldlev]; lastfld [fldlev] := obj
- |
- eHProc : (* hidden procedure field *)
- ReadInt (l);
- |
- eFixup : (* fixup pointer typ *)
- ReadInt (l); typ := struct [l];
- ReadInt (l);
- IF typ.BaseTyp = undftyp THEN
- typ.BaseTyp := struct [l];
- IF typ.BaseTyp.form = DynArr THEN
- typ.size := typ.BaseTyp.size;
- MakeImportedTypeSymbol
- (GlbMod [typ.mno-1].name, typ.adr, typ.symbol)
- END
- END
- |
- eMod, eMod0 : (* module anchor *)
- (*IF (class = eMod) & ~OCS.createObj THEN OCS.Mark (920) END;*)
- ReadLInt (k);
- ReadId (objName); modname := InsertName (objName);
- IF (modname = InsertName (ModuleName)) THEN OCS.Mark (49) END;
- i := 0;
- WHILE (i < nofGmod) & (modname # GlbMod [i].name) DO
- INC (i);
- END;
- IF i < nofGmod THEN (* module already present *)
- IF k # GlbMod [i].a1 THEN OCS.Mark (150); END;
- modobj := GlbMod [i];
- ELSE
- NEW (modobj);
- IF nofGmod < maxImps THEN
- GlbMod [nofGmod] := modobj; INC (nofGmod);
- ELSE
- OCS.Mark (227);
- END;
- modobj.mode := NotYetExp; modobj.name := modname;
- modobj.a1 := k; modobj.a0 := nofGmod;
- modobj.link := NIL; modobj.visible := NotExp;
- IF class = eMod THEN modobj.a2 := 0 ELSE modobj.a2 := 1 END;
-
- MakeInitProcSymbol (modname, k, modobj.symbol);
- MakeSymbol
- (modname, InsertName ("VAR"), "%", modobj.varSym);
- MakeSymbol
- (modname, InsertName ("CONST"), "%", modobj.constSym);
- MakeSymbol
- (modname, InsertName ("GC"), "%", modobj.gcSym);
- END;
- IF nofLmod < maxMod THEN
- LocMod [nofLmod] := modobj; INC (nofLmod)
- ELSE
- OCS.Mark (227);
- END
- |
- ELSE
- OCS.Mark (1005); OCS.Mark (class)
- END; (* CASE class *)
- END; (* LOOP *)
- Insert (name, obj, Mod); modobj := obj (Module);
- modobj.link := LocMod [0].link; modobj.a0 := LocMod [0].a0;
- modobj.typ := notyp; LocMod [0].visible := Exp;
- modobj.visible := NotExp; modobj.symbol := LocMod [0].symbol;
- modobj.varSym := LocMod [0].varSym;
- modobj.constSym := LocMod [0].constSym;
- modobj.gcSym := LocMod [0].gcSym;
- ELSE
- OCS.Mark (157) (* illegal file tag *)
- END;
- F.Close (SymFile); F.Set (SR, NIL, 0)
- ELSE
- OCS.Mark (152); (* sym file not found *)
- IO.WriteStr (" !! Could not find ");
- IO.WriteStr (FileName)
- END;
- IO.WriteLn ();
- END (* ELSE *)
- (* ;OCG.TraceOut (mname, pname); *)
- END Import;
-
-
- (*--- EXPORT ---------------------------------*)
-
- (*------------------------------------*)
- PROCEDURE WriteInt(i: LONGINT);
- (*
- Writes integers written in a compacted form. Taken from J. Templ.
- SPARC-Oberon. User's Guide and Implementation. Computersysteme ETH
- Zürich, Technical Report No. 133, June 1990.
- *)
- BEGIN
- WHILE (i < -64) OR (i > 63) DO
- F.Write(SR, CHR(i MOD 128 + 128)); i := i DIV 128
- END;
- F.Write(SR, CHR(i MOD 128))
- END WriteInt;
-
- (*------------------------------------*)
- PROCEDURE WriteLInt (k : LONGINT);
- BEGIN (* WriteLInt *)
- F.WriteBytes (SR, k, 4)
- END WriteLInt;
-
- (*------------------------------------*)
- PROCEDURE WriteId (i : LONGINT);
-
- VAR ch : CHAR; lim, bufX : INTEGER; buf : NameBufPtr;
-
- BEGIN (* WriteId *)
- buf := nameBuf [i DIV BufSize];
- bufX := SHORT (i MOD BufSize);
- REPEAT
- ch := buf [bufX]; F.Write (SR, ch); INC (bufX)
- UNTIL ch = 0X;
- END WriteId;
-
-
- (*------------------------------------*)
- PROCEDURE WriteSymbol ( symbol : Symbol );
-
- VAR i : LONGINT; ch : CHAR;
-
- BEGIN (* WriteSymbol *)
- i := 0;
- REPEAT
- ch := symbol [i]; F.Write (SR, ch); INC (i)
- UNTIL ch = 0X;
- END WriteSymbol;
-
- (*------------------------------------*)
- PROCEDURE^ OutStr (typ : Struct);
-
- (*------------------------------------*)
- PROCEDURE OutPars (par : Object);
-
- (* CONST name = "OutPars"; *)
-
- BEGIN (* OutPars *)
- (*OCG.TraceIn (mname, name);*)
- F.Write (SR, eParList);
- WHILE (par # NIL) & ((par.mode <= IndR) & (par.a0 >= 0)) DO
- OutStr (par.typ);
- IF par.mode = Var THEN F.Write (SR, eValPar)
- ELSIF par.mode = Ind THEN F.Write (SR, eVarPar)
- ELSIF par.mode = VarR THEN F.Write (SR, eValRegPar)
- ELSIF par.mode = IndR THEN F.Write (SR, eVarRegPar)
- ELSE F.Write (SR, eVarArg)
- END;
- WriteInt (par.typ.ref);
- (* A quick fix to the $L compiler switch bug *)
- IF par.mode IN {VarR, IndR, VarArg} THEN WriteInt (par.a0)
- ELSE WriteInt (0)
- END;
- WriteId (par.name);
- par := par.link
- END;
- (*;OCG.TraceOut (mname, name);*)
- END OutPars;
-
- (*------------------------------------*)
- PROCEDURE OutFlds (fld : Object; adr : LONGINT; visible : BOOLEAN);
- (* CONST name = "OutFlds"; *)
-
- BEGIN (* OutFlds *)
- (*OCG.TraceIn (mname, name);*)
- IF visible THEN F.Write (SR, eFldList) END;
- WHILE fld # NIL DO
- IF fld.mode = Fld THEN
- IF visible & (fld.visible # NotExp) THEN
- OutStr (fld.typ); F.Write (SR, eFld); WriteInt (fld.typ.ref);
- WriteInt (fld.a0); F.Write (SR, fld.visible); WriteId (fld.name)
- ELSIF fld.typ.form = Record THEN
- OutFlds (fld.typ.link, fld.a0 + adr, FALSE)
- ELSIF (fld.typ.form = Pointer) OR (fld.name < 0) THEN
- F.Write (SR, eHPtr); WriteInt (fld.a0 + adr)
- END
- END;
- fld := fld.left
- END;
- (*;OCG.TraceOut (mname, name);*)
- END OutFlds;
-
- (*------------------------------------*)
- PROCEDURE OutProcs (ref : INTEGER; fld : Object);
-
- (* CONST name = "OutProcs"; *)
-
- BEGIN (* OutProcs *)
- (*OCG.TraceIn (mname, name);*)
- WHILE fld # NIL DO
- IF fld.mode = TProc THEN
- IF fld.visible = Exp THEN
- OutStr (fld.typ); OutPars (fld.link); F.Write (SR, eTProcE);
- WriteInt (ref); WriteInt (fld.typ.ref); WriteInt (fld.a0);
- WriteId (fld.name)
- ELSE
- F.Write (SR, eTProc); WriteInt (ref); WriteInt (fld.a0)
- END
- ELSIF fld.mode = LibCall THEN
- IF fld.visible = Exp THEN
- OutStr (fld.typ); OutPars (fld.link); F.Write (SR, eLibCall);
- WriteInt (ref); WriteInt (fld.typ.ref); WriteInt (fld.a0);
- WriteId (fld.name)
- END
- END;
- fld := fld.left
- END; (* WHILE *)
- (*;OCG.TraceOut (mname, name);*)
- END OutProcs;
-
- (*------------------------------------*)
- PROCEDURE OutMod (VAR m : INTEGER);
-
- (* CONST name = "OutMod"; *)
-
- VAR em : INTEGER; mod : Module;
-
- BEGIN (* OutMod *)
- (*OCG.TraceIn (mname, name);*)
- mod := GlbMod [m - 1]; em := mod.mode;
- IF em = NotYetExp THEN
- GlbMod [m - 1].mode := nofExp; m := nofExp; INC (nofExp);
- F.Write (SR, eMod); WriteLInt (mod.a1); WriteId (mod.name);
- ELSE
- m := em;
- END
- (*;OCG.TraceOut (mname, name);*)
- END OutMod;
-
- (*------------------------------------*)
- PROCEDURE OutStr (typ : Struct);
-
- (* CONST name = "OutStr"; *)
-
- VAR m, r : INTEGER; btyp : Struct;
-
- BEGIN (* OutStr *)
- (*OCG.TraceIn (mname, name);*)
- IF typ.ref = NotYetExp THEN (* type not yet exported *)
- m := typ.mno; btyp := typ.BaseTyp;
- IF m > 0 THEN OutMod (m) END;
- CASE typ.form OF
- Undef .. NoTyp :
- |
- Pointer, BPointer, CPointer :
- IF typ.form = Pointer THEN F.Write (SR, ePointer);
- ELSIF typ.form = CPointer THEN F.Write (SR, eCPointer);
- ELSE F.Write (SR, eBPointer);
- END;
- IF btyp.ref > 0 THEN
- WriteInt (btyp.ref);
- ELSE
- F.Write (SR, eUndef);
- IF udpinx < maxUDP THEN
- undPtr [udpinx] := typ; INC (udpinx);
- ELSE
- OCS.Mark (224);
- END
- END;
- WriteInt (m); IF typ.form = Pointer THEN WriteInt (typ.adr) END
- |
- ProcTyp :
- OutStr (btyp); OutPars (typ.link);
- F.Write (SR, eProcTyp); WriteInt (btyp.ref); WriteInt (m);
- |
- Array :
- OutStr (btyp);
- F.Write (SR, eArray); WriteInt (btyp.ref); WriteInt (m);
- WriteInt (typ.size); WriteInt (typ.adr); WriteInt (typ.n);
- |
- DynArr :
- OutStr (btyp);
- F.Write (SR, eDynArr); WriteInt (btyp.ref); WriteInt (m);
- WriteInt (typ.size); WriteInt (typ.adr);
- |
- Record :
- IF btyp = NIL THEN r := NoTyp;
- ELSE OutStr (btyp); r := btyp.ref;
- END;
- OutFlds (typ.link, 0, TRUE);
- F.Write (SR, eRecord);
- WriteInt (r); WriteInt (m); WriteInt (typ.size);
- WriteInt (typ.adr);
- |
- ELSE
- OCS.Mark (1006); OCS.Mark (typ.form)
- END; (* CASE typ.form *)
- typ.ref := strno; INC (strno);
- IF strno > maxStr THEN OCS.Mark (228) END;
- IF typ.strobj # NIL THEN
- IF typ.strobj.visible = Exp THEN F.Write (SR, eTypE)
- ELSE F.Write (SR, eTyp);
- END;
- WriteInt (strno-1); WriteInt (m); WriteId (typ.strobj.name);
- IF typ.form = Record THEN OutProcs (strno-1, typ.link) END
- END;
- END; (* IF *)
- (*;OCG.TraceOut (mname, name);*)
- END OutStr;
-
- (*------------------------------------*)
- PROCEDURE OutObj (obj : Object);
-
- (* CONST name = "OutObj"; *)
-
- VAR f, m : INTEGER;
-
- BEGIN (* OutObj *)
- (*OCG.TraceIn (mname, name);*)
- IF obj # NIL THEN
- IF obj.visible # NotExp THEN
- IF obj.mode = Con THEN
- OutStr (obj.typ);
- F.Write (SR, eCon);
- f := obj.typ.form;
- IF f IN {CPointer, BPointer} THEN WriteInt (obj.typ.ref)
- ELSE WriteInt (f)
- END;
- CASE f OF
- Undef :
- |
- Byte, Bool, Char, SInt, BSet, Int, WSet,
- Word, LInt, Real, LReal, Set, Longword :
- WriteInt (obj.a0)
- |
- (*LReal : WriteInt (obj.a0); WriteInt (obj.a1);
- |*)
- String :
- IF obj.a1 <= 2 THEN
- WriteInt (-1); WriteInt (obj.a1); WriteInt (obj.a2)
- ELSE
- WriteInt (obj.a0); WriteInt (obj.a1);
- END
- |
- NilTyp :
- |
- CPtrTyp, BPtrTyp, CPointer, BPointer, ProcTyp :
- (* This is all VERY dodgy, but ... *)
- WriteInt (obj.a0);
- |
- ELSE
- OCS.Mark (1007); OCS.Mark (f)
- END; (* CASE f *)
- WriteId (obj.name);
- ELSIF obj.mode = Typ THEN
- OutStr (obj.typ);
- IF (obj.typ.strobj # obj) & (obj.typ.strobj # NIL) THEN
- F.Write (SR, eTypE); WriteInt (obj.typ.ref);
- WriteInt (0);(*<- module no *) WriteId (obj.name);
- END; (* IF *)
- ELSIF obj.mode = Var THEN
- OutStr (obj.typ); F.Write (SR, eVar);
- WriteInt (obj.typ.ref); WriteInt (obj.a0);
- F.Write (SR, obj.visible); WriteId (obj.name)
- ELSIF obj.mode = XProc THEN
- OutStr (obj.typ); OutPars (obj.link);
- F.Write (SR, eXProc); WriteInt (obj.typ.ref); WriteId (obj.name);
- ELSIF obj.mode = FProc THEN
- OutStr (obj.typ); OutPars (obj.link);
- F.Write (SR, eFProc); WriteInt (obj.typ.ref);
- WriteSymbol (obj.symbol); WriteId (obj.name);
- END
- END; (* IF *)
- OutObj (obj.left); OutObj (obj.right)
- END; (* IF *)
- (*;OCG.TraceOut (mname, name);*)
- END OutObj;
-
- (*------------------------------------*)
- PROCEDURE OutImports ();
-
- (* CONST name = "OutImports"; *)
-
- VAR m : INTEGER; mod : Module;
-
- BEGIN (* OutImports *)
- (*OCG.TraceIn (mname, name);*)
- m := 0;
- WHILE m < nofGmod DO
- mod := GlbMod [m];
- IF (mod.visible = Exp) & (mod.mode = NotYetExp) THEN
- mod.mode := nofExp; INC (nofExp);
- F.Write (SR, eMod); WriteLInt (mod.a1); WriteId (mod.name);
- END;
- INC (m);
- END
- (*;OCG.TraceOut (mname, name);*)
- END OutImports;
-
- (*------------------------------------*)
- PROCEDURE Export * (
- VAR FileName : ARRAY OF CHAR;
- VAR newSF : BOOLEAN; VAR key : LONGINT);
-
- (* CONST name = "Export"; *)
-
- VAR
- i : INTEGER;
- ch0, ch1 : CHAR;
- oldkey : LONGINT;
- typ : Struct;
- oldFile, newFile : F.File;
- res : LONGINT;
- oldSR : F.Rider;
- equal : BOOLEAN;
- pathName : ARRAY 256 OF CHAR;
-
- BEGIN (* Export *)
- (* OCG.TraceIn (mname, name); *)
- COPY (DestPath, pathName); Str.Append (pathName, FileName);
- newFile := F.New (pathName);
- IF newFile # NIL THEN
- F.Set (SR, newFile, 0);
- WriteLInt (SFtag);
- (*IF OCS.createObj THEN F.Write (SR, eMod) ELSE F.Write (SR, eMod0) END;*)
- F.Write (SR, eMod); WriteLInt (key); WriteId (InsertName (ModuleName));
-
- strno := firstStr;
- nofExp := 1;
- OutImports ();
- OutObj (topScope.link);
-
- i := 0;
- WHILE i < udpinx DO
- typ := undPtr [i]; OutStr (typ.BaseTyp); undPtr [i] := NIL; INC (i);
- F.Write (SR, eFixup);
- WriteInt (typ.ref); WriteInt (typ.BaseTyp.ref)
- END; (* WHILE *)
-
- IF ~OCS.scanerr THEN
- IF DU.Search (searchPath, FileName, pathName) THEN
- oldFile := F.Old (pathName);
- ELSE
- oldFile := NIL
- END;
- IF oldFile # NIL THEN
- F.Set (oldSR, oldFile, 5); F.ReadBytes (oldSR, oldkey, 4);
- F.Set (SR, newFile, 9);
- REPEAT
- F.Read (oldSR, ch0); F.Read(SR, ch1);
- UNTIL (ch0 # ch1) OR SR.eof;
- equal := oldSR.eof & SR.eof;
- F.Close (oldFile);
- IF equal THEN
- newSF := FALSE; key := oldkey; F.Purge (newFile);
- ELSIF newSF THEN
- F.Register (newFile);
- IF OCG.Verbose THEN
- IO.WriteF1
- (" %ld types exported\n", LONG (strno - firstStr))
- END;
- IF newFile.dosError # 0 THEN OCS.Mark (153) END;
- ELSE
- OCS.Mark (155); F.Purge (newFile);
- IO.WriteStr (" !! Symbol file is obsolete\n");
- END; (* ELSE *)
- ELSE
- F.Register (newFile); newSF := TRUE;
- IF newFile.dosError # 0 THEN OCS.Mark (153) END;
- END; (* ELSE *)
-
- MakeInitProcSymbol (InsertName (ModuleName), key, InitSymbol);
- ELSE
- newSF := FALSE; F.Purge (newFile);
- END;
-
- ELSE
- OCS.Mark (153);
- END;
- (* ;OCG.TraceOut (mname, name); *)
- END Export;
-
- (*--- INITIALISATION ---------------------------------*)
-
- (*------------------------------------*)
- PROCEDURE InitStruct (VAR typ : Struct; f : INTEGER);
-
- BEGIN (* InitStruct *)
- typ := AllocStruct (); typ.form := f; typ.ref := f; typ.size := 1;
- END InitStruct;
-
- (*------------------------------------*)
- (* $D- disable copying of open arrays *)
- PROCEDURE EnterConst (name : ARRAY OF CHAR; value : INTEGER);
-
- VAR obj : Object;
-
- BEGIN (* EnterConst *)
- Insert (name, obj, Con); obj.typ := booltyp; obj.a0 := value;
- END EnterConst;
-
- (*------------------------------------*)
- (* $D- disable copying of open arrays *)
- PROCEDURE EnterTyp (
- name : ARRAY OF CHAR; form, size : INTEGER; VAR res: Struct);
-
- VAR obj : Object; typ : Struct;
-
- BEGIN (* EnterTyp *)
- Insert (name, obj, Typ); typ := AllocStruct ();
- obj.typ := typ; obj.visible := Exp;
- typ.form := form; typ.strobj := obj; typ.size := size;
- typ.ref := form; res := typ;
- END EnterTyp;
-
- (*------------------------------------*)
- (* $D- disable copying of open arrays *)
- PROCEDURE EnterProc (name : ARRAY OF CHAR; num : INTEGER);
-
- VAR obj : Object;
-
- BEGIN (* EnterProc *)
- Insert (name, obj, SProc); obj.typ := notyp; obj.a0 := num
- END EnterProc;
-
- BEGIN (* OCT *)
- DestPath := ""; nameSize := 0; topScope := NIL;
- InitStruct (undftyp, Undef); InitStruct (notyp, NoTyp);
- InitStruct (stringtyp, String); InitStruct (niltyp, NilTyp);
- OpenScope (0);
-
- (* initialisation of module SYSTEM *)
-
- EnterTyp ("BYTESET", BSet, OCG.BSetSize, bsettyp);
- EnterTyp ("WORDSET", WSet, OCG.WSetSize, wsettyp);
- EnterTyp ("PTR", PtrTyp, OCG.PtrSize, ptrtyp);
- EnterTyp ("BPTR", BPtrTyp, OCG.PtrSize, bptrtyp);
- EnterTyp ("CPTR", CPtrTyp, OCG.PtrSize, cptrtyp);
- EnterTyp ("BYTE", Byte, OCG.ByteSize, bytetyp);
- EnterTyp ("WORD", Word, 2, wordtyp);
- EnterTyp ("LONGWORD", Longword, 4, lwordtyp);
- EnterTyp ("TYPETAG", TagTyp, 4, tagtyp);
-
- EnterProc ("ADR", pADR); EnterProc ("AND", pAND);
- EnterProc ("ARGLEN", pARGLEN); EnterProc ("ARGS", pARGS);
- EnterProc ("BIT", pBIT); EnterProc ("DISPOSE", pDISPOSE);
- EnterProc ("GET", pGET); EnterProc ("GETREG", pGETREG);
- EnterProc ("INLINE", pINLINE); EnterProc ("LOR", pOR);
- EnterProc ("LSH", pLSH); EnterProc ("MOVE", pMOVE);
- EnterProc ("NEW", pSYSNEW); EnterProc ("PUT", pPUT);
- EnterProc ("ROT", pROT); EnterProc ("SETCLEANUP", pSETCLEANUP);
- EnterProc ("STRLEN", pSTRLEN); EnterProc ("PUTREG", pPUTREG);
- EnterProc ("VAL", pVAL); EnterProc ("XOR", pXOR);
- EnterProc ("BIND", pBIND); EnterProc ("GC", pGC);
- EnterProc ("SETREG", pSETREG); EnterProc ("REG", pREG);
- EnterProc ("TAG", pTAG); EnterProc ("SIZETAG", pSIZETAG);
- EnterProc ("GETNAME", pGETNAME); EnterProc ("NEWTAG", pNEWTAG);
- EnterProc ("RC", pRC);
-
- syslink := topScope.link; universe := topScope; topScope.link := NIL;
-
- (* initialisation of predeclared types and procedures *)
-
- EnterTyp ("CHAR", Char, OCG.CharSize, chartyp);
- EnterTyp ("SET", Set, OCG.SetSize, settyp);
- EnterTyp ("REAL", Real, OCG.RealSize, realtyp);
- EnterTyp ("INTEGER", Int, OCG.IntSize, inttyp);
- EnterTyp ("LONGINT", LInt, OCG.LIntSize, linttyp);
- EnterTyp ("LONGREAL", LReal, OCG.LRealSize, lrltyp);
- EnterTyp ("SHORTINT", SInt, OCG.SIntSize, sinttyp);
- EnterTyp ("BOOLEAN", Bool, OCG.BoolSize, booltyp);
-
- EnterConst ("FALSE", 0); EnterConst ("TRUE", 1);
-
- EnterProc ("INC", pINC); EnterProc ("DEC", pDEC);
- EnterProc ("HALT", pHALT); EnterProc ("NEW", pNEW);
- EnterProc ("ABS", pABS); EnterProc ("CAP", pCAP);
- EnterProc ("ORD", pORD); EnterProc ("ENTIER", pENTIER);
- EnterProc ("ODD", pODD); EnterProc ("MIN", pMIN);
- EnterProc ("MAX", pMAX); EnterProc ("CHR", pCHR);
- EnterProc ("SHORT", pSHORT); EnterProc ("LONG", pLONG);
- EnterProc ("INCL", pINCL); EnterProc ("EXCL", pEXCL);
- EnterProc ("LEN", pLEN); EnterProc ("ASH", pASH);
- EnterProc ("COPY", pCOPY); EnterProc ("SIZE", pSIZE);
- EnterProc ("ASSERT", pASSERT);
-
- nameOrg := nameX;
- backupTab := nameTab; (* Save hash table for names so we can restore it *)
-
- (* initialisation of symbols *)
-
- NEW (OberonSysINIT, 15); COPY ("OberonSys_INIT", OberonSysINIT^);
- NEW (OberonSysCLEANUP, 18); COPY ("OberonSys_CLEANUP", OberonSysCLEANUP^);
- NEW (OberonSysVAR, 14); COPY ("OberonSys_VAR", OberonSysVAR^);
- NEW (OberonSysNEW, 14); COPY ("OberonSys_NEW", OberonSysNEW^);
- NEW (OberonSysSYSNEW, 17); COPY ("OberonSys_SYSNEW", OberonSysSYSNEW^);
- NEW (OberonSysDISPOSE, 18); COPY ("OberonSys_DISPOSE", OberonSysDISPOSE^);
- NEW (OberonSysGC, 13); COPY ("OberonSys_GC", OberonSysGC^);
- NEW (OberonSysMUL, 14); COPY ("OberonSys_MUL", OberonSysMUL^);
- NEW (OberonSysDIV, 14); COPY ("OberonSys_DIV", OberonSysDIV^);
- NEW (OberonSysMOD, 14); COPY ("OberonSys_MOD", OberonSysMOD^);
- NEW (OberonSysMOVE, 15); COPY ("OberonSys_MOVE", OberonSysMOVE^);
- NEW (OberonSysPtr, 17); COPY ("OberonSys_TYPE_0", OberonSysPtr^);
- NEW (OberonSysSETCLEANUP, 21); COPY ("OberonSys_SETCLEANUP", OberonSysSETCLEANUP^);
- NEW (OberonSysREGISTER, 19); COPY ("OberonSys_REGISTER", OberonSysREGISTER^);
- NEW (OberonSysSTACKCHK, 19); COPY ("OberonSys_STACKCHK", OberonSysSTACKCHK^);
- NEW (VarSymbol, 256);
- NEW (ConstSymbol, 256);
- NEW (InitSymbol, 256);
- NEW (GCSymbol, 256);
- END OCT.
-
- (***************************************************************************
-
- $Log: OCT.mod $
- Revision 4.9 1994/07/26 18:30:02 fjc
- *** empty log message ***
-
- Revision 4.8 1994/07/25 00:45:24 fjc
- - Created OberonSysSTACKCHK variable.
-
- Revision 4.7 1994/07/24 00:29:12 fjc
- - Changed format of linker symbols to allow for underscores
- in identifiers when they are implemented.
-
- Revision 4.6 1994/07/22 14:03:20 fjc
- - Added code for importing and exporting FProc objects.
-
- Revision 4.5 1994/07/10 12:54:17 fjc
- - Commented out trace code.
- - Changed Export() to output 0 as the offset for all
- non-register procedure parameters.
- - Added declarations for SYSTEM.RC and SYSTEM.REGISTER.
- - Added symbol variable for SYSTEM.SETCLEANUP.
-
- Revision 4.4 1994/06/17 18:03:43 fjc
- - Implemented TagTyp
- - Defined new SYSTEM procedures.
- - Fixed bug in exporting constants.
-
- Revision 4.3 1994/06/06 18:41:21 fjc
- - Implemented varargs for LibCall procedures:
- - Modified Import() and Export() to handle new element type.
-
- Revision 4.2 1994/06/05 22:51:32 fjc
- - Changed symbol table to use binary search trees.
- - Changed symbol file to use Templ's compact integer IO.
-
- ***************************************************************************)
-