home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 2
/
goldfish_vol2_cd1.bin
/
files
/
dev
/
obero
/
oberon-a
/
source
/
oc
/
oct.mod
< prev
next >
Wrap
Text File
|
1994-08-08
|
56KB
|
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.
***************************************************************************)