home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-06-29 | 49.5 KB | 1,659 lines |
- (*************************************************************************
-
- $RCSfile: OCT.mod $
- Description: Symbol table handler
-
- Created by: fjc (Frank Copeland)
- $Revision: 5.23 $
- $Author: fjc $
- $Date: 1995/06/29 19:10:08 $
-
- Copyright © 1990-1993, ETH Zuerich
- Copyright © 1993-1995, 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.
-
- *************************************************************************)
-
- <* STANDARD- *> <* MAIN- *>
-
- MODULE OCT;
-
- IMPORT
- SYS := SYSTEM, E := Exec, Str := Strings, DU := DosUtil,
- F := Files, OCM, OCS, conv := Conversions, OCStrings, OCOut;
-
-
- (* --- Exported declarations -------------------------------------------- *)
-
- CONST
- maxImps = 64;
-
- (* 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; AdrTyp * = 16;
- BPtrTyp * = 17; Word * = 18; Longword * = 19; TagTyp * = 20;
- Pointer * = 21; ProcTyp * = 24; Array * = 25; DynArr * = 26;
- Record * = 27;
-
- (* standard procedure codes *)
- pABS * = 0; pCAP * = 1; pCHR * = 2; pENTIER * = 3; pHALT * = 4;
- pLONG * = 5; pMAX * = 6; pMIN * = 7; pNEW * = 8; pODD * = 9;
- pORD * = 10; pSHORT * = 11;
-
- pASH * = 19; pASSERT * = 20; pCOPY * = 21; pDEC * = 22; pEXCL * = 23;
- pINC * = 24; pINCL * = 25; pLEN * = 26;
-
- (* module SYSTEM procedure codes *)
- pADR * = 12; pCC * = 13; pDISPOSE * = 14; pREG * = 15; pSIZE * = 16;
- pSTRLEN * = 17; pTAG * = 18;
-
- pAND * = 27; pBIT * = 28; pGET * = 29; pGETREG * = 30; pLSH * = 31;
- pOR * = 32; pPUT * = 33; pPUTREG * = 34; pSETREG * = pPUTREG;
- pROT * = 35; pVAL * = 36; pXOR * = 37;
-
- pINLINE * = 38; pMOVE * = 39; pSYSNEW * = 40;
-
- LastProc * = pSYSNEW;
- TwoPar * = pASH;
-
- (* String lengths *)
-
- NameLen * = 255;
- PathLen = 256;
- LabelLen = NameLen * 2 + 1;
-
- (* Values for visible field of ObjDesc *)
-
- Exp * = -1;
- NotExp * = 0;
- RdOnly * = 1;
-
- TYPE
- Name = ARRAY NameLen + 1 OF CHAR;
- Label * = POINTER TO ARRAY (*LabelLen*) OF CHAR;
-
- Object * = POINTER TO ObjDesc;
- Module * = POINTER TO ModDesc;
- Struct * = POINTER TO StrDesc;
-
- ObjDesc * = RECORD
- left *, right *, link * : Object;
- typ * : Struct;
- a0 *, a1 *, a2 * : LONGINT;
- fwd * : BOOLEAN;
- mode * : SHORTINT;
- visible * : SHORTINT;
- name * : LONGINT;
- label * : Label;
- END; (* ObjDesc *)
-
- ModDesc * = RECORD (ObjDesc)
- varLab *, constLab *, gcLab *, endLab * : Label;
- END; (* ModDesc *)
-
- StrDesc * = RECORD
- form *, sysflg *, mno *, ref * : INTEGER;
- n *, size *, adr * : LONGINT;
- BaseTyp * : Struct;
- link *, strobj * : Object;
- label * : Label;
- END; (* StrDesc *)
-
- Desc * = POINTER TO DescRec;
- DescRec = RECORD
- next : Desc;
- mode *, lev * : INTEGER;
- a0 *, a1 *, a2 * : LONGINT;
- END; (* DescRec *)
-
- Item * = RECORD
- mode *, lev * : INTEGER;
- a0 *, a1 *, a2 * : LONGINT;
- typ * : Struct;
- obj * : Object;
- label * : Label;
- wordIndex *, rdOnly * : BOOLEAN;
- desc * : Desc
- END; (* Item *)
-
- VAR
- topScope * : Object;
-
- undftyp *, bytetyp *, booltyp *, chartyp *, sinttyp *, inttyp *,
- linttyp *, realtyp *, lrltyp *, settyp *, stringtyp *, niltyp *, notyp *,
- ptrtyp *, adrtyp *, bptrtyp *, bsettyp *, wsettyp *, wordtyp *,
- lwordtyp *, tagtyp *
- : Struct;
-
- nofGmod * : INTEGER; (* nof imports *)
- GlbMod * : ARRAY maxImps OF Module;
-
- ModuleName * : Name;
-
- VarLabel *, ConstLabel *, InitLabel *, EndLabel *, GCLabel *,
- PointerDesc *
- : Label;
-
-
- (* --- Local declarations ----------------------------------------------- *)
-
-
- CONST
- (* object modes *)
- Var = OCM.Var; VarX = OCM.VarX; Ind = OCM.Ind; IndX = OCM.IndX;
- Con = OCM.Con; Reg = OCM.Reg; RegI = OCM.RegI; RegX = OCM.RegX;
- Fld = OCM.Fld; Typ = OCM.Typ; LProc = OCM.LProc; XProc = OCM.XProc;
- SProc = OCM.SProc; LibCall = OCM.LibCall; TProc = OCM.TProc;
- AProc = OCM.AProc; Mod = OCM.Mod; Head = OCM.Head; VarArg = OCM.VarArg;
- M2Proc = OCM.M2Proc; CProc = OCM.CProc; CallBack = OCM.CallBack;
- VarR = OCM.VarR; IndR = OCM.IndR;
-
- (* System flags *)
-
- OberonFlag = OCM.OberonFlag; M2Flag = OCM.M2Flag; CFlag = OCM.CFlag;
- AsmFlag = OCM.AsmFlag; BCPLFlag = OCM.BCPLFlag; CBackFlag = OCM.CBackFlag;
-
- SFtag * = 53594D08H; (* "SYM" + version # *)
- MinSFtag = 53594D08H; (* Earliest version that can be read. *)
- firstStr = 32; maxStr = 512;
- maxUDP = 128; maxMod = 32; maxParLev = 6; maxExtLib = 8;
- NotYetExp = 0;
-
- (* terminal symbols for symbol file elements *)
- eUndef = 0; eCon = 1; eTypE = 2; eTyp = 3; eVar = 4; eXProc = 5;
- eLibCall = 6; eM2Proc = 7; eCProc = 8; eAProc = 9; ePointer = 10;
- eProcTyp = 11; eArray = 12; eDynArr = 13; eRecord = 14; eParList = 15;
- eValPar = 16; eVarPar = 17; eVarArg = 18; eFldList = 19; eFld = 20;
- eHPtr = 21; eHProc = 22; eTProcE = 23; eTProc = 24; eFixup = 25;
- eMod = 26; eExtLib = 27; eCallBack = 28; eCBackTyp = 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;
- nameBuf : ARRAY MaxBuffers OF NameBufPtr;
- nameX, nameOrg, nameSize : LONGINT;
- nameTab, backupTab : ARRAY HashTableSize OF LONGINT;
-
- nofExtLib : INTEGER;
- extLib : ARRAY maxExtLib OF LONGINT;
-
-
- (*--- Procedure declarations -------------------------------------------*)
-
-
- (*------------------------------------*)
- PROCEDURE Tagged * ( typ : Struct ) : BOOLEAN;
- BEGIN (* Tagged *)
- RETURN ((typ.form IN {Record, Pointer}) & (typ.sysflg = OberonFlag))
- END Tagged;
-
- (*------------------------------------*)
- PROCEDURE Address * ( typ : Struct ) : BOOLEAN;
- BEGIN (* Address *)
- RETURN
- ((typ.form = Pointer) & (typ.sysflg IN {M2Flag, CFlag, AsmFlag}))
- OR (typ.form = AdrTyp) OR (typ.form = NilTyp)
- END Address;
-
- (*------------------------------------*)
- PROCEDURE IsParam * (obj : Object) : BOOLEAN;
-
- BEGIN (* IsParam *)
- RETURN (obj # NIL)
- & (obj.mode IN {Var, VarR, VarArg, Ind, IndR})
- & (obj.a0 >= 0)
- END IsParam;
-
- (*------------------------------------*)
- PROCEDURE Init * ();
-
- BEGIN (* Init *)
- topScope := universe; strno := 0; udpinx := 0; nofGmod := 0;
- ModuleName := ""; COPY ("VAR", VarLabel^); COPY ("CONST", ConstLabel^);
- COPY ("INIT", InitLabel^); COPY ("END", EndLabel^); COPY ("GC", GCLabel^);
- nofExtLib := 0;
- END Init;
-
- (*------------------------------------*)
- PROCEDURE Close * ();
-
- VAR i : INTEGER;
-
- BEGIN (* Close *)
- 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
- END Close;
-
- (*------------------------------------*)
- PROCEDURE^ Join (module, object : LONGINT; VAR name : ARRAY OF CHAR);
- PROCEDURE^ InsertName * (n : ARRAY OF CHAR) : LONGINT;
-
- PROCEDURE StartModule * ();
-
- VAR mn : LONGINT;
-
- BEGIN (* StartModule *)
- mn := InsertName (ModuleName);
- Join (mn, InsertName ("VAR"), VarLabel^);
- Join (mn, InsertName ("CONST"), ConstLabel^);
- Join (mn, InsertName ("GC-OFFSET"), GCLabel^);
- END StartModule;
-
- (*------------------------------------*)
- PROCEDURE ExtLib * ();
- BEGIN (* ExtLib *)
- IF nofExtLib >= maxExtLib THEN OCS.Mark (234); nofExtLib := 0 END;
- extLib [nofExtLib] := InsertName (OCS.name); INC (nofExtLib)
- END ExtLib;
-
- (*------------------------------------*)
- PROCEDURE EndModule * ();
-
- BEGIN (* EndModule *)
- END EndModule;
-
- (*------------------------------------*)
- PROCEDURE CheckBuf (size : LONGINT);
-
- VAR newBuf : NameBufPtr; newX : LONGINT;
-
- BEGIN (* CheckBuf *)
- 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
- END CheckBuf;
-
- (*------------------------------------*)
- PROCEDURE InsertName * (n : ARRAY OF CHAR) : LONGINT;
-
- VAR i, j, k, len, bufX : INTEGER; x, x1 : LONGINT; ch : CHAR;
- buf : NameBufPtr;
-
- <*$CopyArrays-*>
- BEGIN (* InsertName *)
- k := 0; len := 0; ch := n [0];
- WHILE ch # 0X DO
- <*$ < OvflChk- *>
- INC (k, ORD (ch));
- <*$ > *>
- 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;
- 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
- RETURN x
- ELSE
- INC (i); INC (j)
- END
- END
- END; (* ELSE *)
- END; (* LOOP *)
- END InsertName;
-
- (*------------------------------------*)
- PROCEDURE NameLength (name : LONGINT) : INTEGER;
-
- VAR buf : NameBufPtr; len, bufX : INTEGER;
-
- BEGIN (* NameLength *)
- buf := nameBuf [name DIV BufSize];
- bufX := SHORT (name MOD BufSize);
- len := 0;
- WHILE buf [bufX] # 0X DO INC (len); INC (bufX) END;
- RETURN len
- END NameLength;
-
- (*------------------------------------*)
- PROCEDURE GetName * (adr : LONGINT; VAR name : ARRAY OF CHAR);
-
- VAR buf : NameBufPtr; i, bufX : INTEGER; ch : CHAR;
-
- BEGIN (* GetName *)
- 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;
- END GetName;
-
- (*------------------------------------*)
- PROCEDURE FindObj (obj : Object; name : ARRAY OF CHAR) : Object;
-
- VAR
- buf : NameBufPtr; n1, n2 : LONGINT; bufX, i : INTEGER; ch1, ch2 : CHAR;
-
- <*$CopyArrays-*>
- 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);
-
- VAR obj : Object;
-
- BEGIN (* FindImport *)
- obj := FindObj (mod.link, OCS.name);
- IF (obj # NIL) & (obj.mode = Typ) & (obj.visible = NotExp) THEN
- obj := NIL
- END;
- res := obj
- END FindImport;
-
- (*------------------------------------*)
- PROCEDURE Find * (VAR res : Object; VAR level : INTEGER);
-
- VAR obj, head : Object;
-
- BEGIN (* Find *)
- 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;
- END Find;
-
- (*------------------------------------*)
- PROCEDURE FindField * (typ : Struct; VAR res : Object);
-
- VAR obj : Object; typ1 : Struct; n : LONGINT;
-
- BEGIN (* FindField *)
- (* 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;
- res := obj;
- END FindField;
-
- (*------------------------------------*)
- PROCEDURE SuperCall * (pname : LONGINT; typ : Struct; VAR proc : Object);
-
- VAR obj : Object;
-
- BEGIN (* SuperCall *)
- 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.name # pname)) DO
- obj := obj.left
- END;
- IF obj # NIL THEN EXIT END
- END
- END;
- proc := obj
- END SuperCall;
-
- (*------------------------------------*)
- PROCEDURE NextProc * (typ : Struct) : LONGINT;
-
- VAR pno : LONGINT; obj : Object;
-
- BEGIN (* NextProc *)
- (* 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;
- RETURN pno + 1
- END NextProc;
-
- (*------------------------------------*)
- PROCEDURE InsertObj
- ( VAR name : ARRAY OF CHAR; root : Object; mode : SHORTINT;
- VAR res : Object ) : BOOLEAN;
-
- VAR
- obj, prev : Object; mod : Module; result : BOOLEAN;
- buf : NameBufPtr; n1, n2 : LONGINT; bufX, i : INTEGER; ch1, ch2 : CHAR;
-
- BEGIN (* InsertObj *)
-
- 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 NEW (obj)
- 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;
- RETURN result
- END InsertObj;
-
- (*------------------------------------*)
- PROCEDURE Insert *
- ( VAR name : ARRAY OF CHAR; VAR res : Object; mode : SHORTINT );
-
- BEGIN (* Insert *)
- IF ~InsertObj (name, topScope, mode, res) THEN
- IF res.mode # Undef THEN OCS.Mark (1) END;
- res.mode := mode
- END
- END Insert;
-
- (*------------------------------------*)
- PROCEDURE OpenScope * (level : INTEGER);
-
- VAR head : Object;
-
- BEGIN (* OpenScope *)
- NEW (head);
- head.mode := Head; head.a0 := level; head.left := topScope;
- topScope := head;
- END OpenScope;
-
- (*------------------------------------*)
- PROCEDURE CloseScope * ();
-
- BEGIN (* CloseScope *)
- topScope := topScope.left;
- END CloseScope;
-
-
- (*--- SYMBOLS ---------------------------------*)
-
-
- (*------------------------------------*)
- PROCEDURE Join (name1, name2 : LONGINT; VAR name : ARRAY OF CHAR);
-
- VAR src, dst : INTEGER; buf : NameBufPtr; ch : CHAR;
-
- BEGIN (* Join *)
- 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] := "_"; 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
- END Join;
-
- (*------------------------------------*)
- PROCEDURE MakeLabel (moduleName, name : LONGINT; VAR label : Label);
-
- BEGIN (* MakeLabel *)
- IF label = NIL THEN
- NEW (label, NameLength (moduleName) + NameLength (name) + 4)
- END;
- Join (moduleName, name, label^)
- END MakeLabel;
-
- (*------------------------------------*)
- PROCEDURE MakeInitProcLabel (module, key : LONGINT; VAR label : Label);
-
- VAR
- keyPart : ARRAY 10 OF CHAR;
- modname : ARRAY 40 OF CHAR;
-
- BEGIN (* MakeInitProcLabel *)
- GetName (module, modname);
- ASSERT (conv.IntToStr (key, 16, 9, "0", keyPart));
- IF label = NIL THEN NEW (label, Str.Length (modname) + 16) END;
- COPY (modname, label^); Str.Append ("_", label^);
- Str.Append (keyPart, label^);
- IF OCM.SmallData THEN Str.Append ("INITs", label^)
- ELSIF OCM.Resident THEN Str.Append ("INITr", label^)
- ELSE Str.Append ("INIT", label^)
- END;
- END MakeInitProcLabel;
-
- (*------------------------------------*)
- PROCEDURE MakeProcLabel * (obj : Object);
-
- VAR pnoPart : ARRAY 6 OF CHAR; mn : LONGINT;
-
- BEGIN (* MakeProcLabel *)
- IF obj.a0 = 0 THEN
- MakeLabel (InsertName (ModuleName), obj.name, obj.label);
- ELSE
- ASSERT (conv.IntToStr (obj.a0, 10, 0, "0", pnoPart));
- NEW (obj.label, Str.Length (ModuleName) + Str.Length (pnoPart) + 4);
- COPY (ModuleName, obj.label^);
- Str.Append ("_", obj.label^);
- Str.Append (pnoPart, obj.label^);
- Str.Append ("P", obj.label^)
- END
- END MakeProcLabel;
-
- (*------------------------------------*)
- PROCEDURE MakeTypeLabel * (typ : Struct);
-
- VAR
- label : ARRAY LabelLen OF CHAR; typname : Name;
- typnum : ARRAY 16 OF CHAR;
-
- BEGIN (* MakeTypeLabel *)
- IF
- (typ.label = NIL) & (typ.sysflg = OberonFlag) &
- ( (typ.form = Record) OR
- ((typ.form = Pointer) & (typ.BaseTyp.form = DynArr)))
- THEN
- IF typ.mno > 0 THEN GetName (GlbMod [typ.mno-1].name, label)
- ELSE COPY (ModuleName, label)
- END;
- Str.Append ("_", label);
- ASSERT (conv.IntToStr (typ.adr, 10, 0, "0", typnum));
- Str.Append (typnum, label); Str.Append ("T", label);
- NEW (typ.label, Str.Length (label) + 1);
- COPY (label, typ.label^)
- END
- END MakeTypeLabel;
-
- (*------------------------------------*)
- PROCEDURE MakeTProcLabel * (typ : Struct; proc : Object);
-
- VAR
- modname, typname, procname : Name; typnum : ARRAY 16 OF CHAR;
- label : ARRAY LabelLen OF CHAR;
-
- BEGIN (* MakeTProcLabel *)
- IF typ.mno > 0 THEN GetName (GlbMod [typ.mno-1].name, label)
- ELSE COPY (ModuleName, label)
- END;
- Str.Append ("_", label);
- ASSERT (conv.IntToStr (typ.adr, 10, 0, "0", typnum));
- Str.Append (typnum, label); Str.Append ("T_", label);
- GetName (proc.name, procname); Str.Append (procname, label);
- NEW (proc.label, Str.Length (label) + 1);
- COPY (label, proc.label^)
- END MakeTProcLabel;
-
- (*--- IMPORT ---------------------------------*)
-
- (*------------------------------------*)
- 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 * (name, alias : ARRAY OF CHAR);
-
- 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, a2 : LONGINT;
- mode : SHORTINT;
- visible : SHORTINT;
- label : Label;
- 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;
-
- <*$CopyArrays-*>
- BEGIN (* Import *)
- nofLmod := 0; strno := firstStr; parlev := -1; fldlev := -1;
- IF name = "SYSTEM" THEN
- Insert (alias, obj, Mod); obj.link := syslink;
- obj.a0 := 0; obj.typ := notyp
- ELSE
- IF OCM.FindSymbolFile (name, pathName) THEN SymFile := F.Old (pathName)
- ELSE SymFile := NIL
- END;
- IF SymFile # NIL THEN
- IF OCM.Verbose THEN
- OCOut.Str (" << "); OCOut.Str (pathName); OCOut.Ln
- END;
- F.Set (SR, SymFile, 0); ReadLInt (k);
- IF k >= MinSFtag 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 [AdrTyp] := adrtyp; 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; label := NIL;
- objName := "";
- CASE class OF
- eUndef : OCS.Mark (151);
- |
- eCon .. eAProc : (* 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 := l; label := NIL
- ELSE
- label := LocMod[0].constLab
- END
- |
- NilTyp : (* NIL *)
- |
- AdrTyp, BPtrTyp, Pointer, 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)
- |
- eLibCall : (* library call procedure *)
- mode := LibCall;
- ReadInt (a0); ReadInt (a1); visible := Exp;
- link := reversedList (lastpar [parlev]);
- DEC (parlev);
- |
- eM2Proc, eCProc, eAProc :
- IF class = eM2Proc THEN mode := M2Proc
- ELSIF class = eCProc THEN mode := CProc
- ELSE mode := AProc
- END;
- link := reversedList (lastpar [parlev]);
- DEC (parlev);
- ReadId (objName); NEW (label, Str.Length (objName) + 1);
- COPY (objName, label^)
- |
- 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.label := label;
- IF class = eXProc THEN
- MakeLabel (LocMod [m].name, obj.name, obj.label);
- ELSIF mode = Typ THEN
- IF typ.strobj = NIL THEN typ.strobj := obj END
- END;
- ELSIF mode = Typ THEN
- struct [s] := obj.typ
- END
- |
- ePointer .. eRecord :
- (* structure *)
- NEW (typ); typ.strobj := NIL; typ.ref := 0;
- typ.sysflg := OberonFlag;
- ReadInt (l); typ.BaseTyp := struct [l];
- ReadInt (l); typ.mno := SHORT (LocMod [l].a0);
- CASE class OF
- ePointer :
- typ.form := Pointer; typ.size := OCM.PtrSize;
- typ.n := 0; typ.label := PointerDesc;
- ReadInt (l); typ.sysflg := SHORT (l);
- ReadInt (typ.adr);
- IF
- (typ.BaseTyp.form = DynArr) & (typ.sysflg = OberonFlag)
- THEN
- typ.size := typ.BaseTyp.size; MakeTypeLabel (typ)
- END
- |
- eProcTyp :
- typ.form := ProcTyp; typ.size := OCM.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 (l); typ.sysflg := SHORT (l);
- ReadInt (typ.adr); (* of descriptor *)
- IF typ.sysflg = OberonFlag THEN MakeTypeLabel (typ) END
- |
- 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, eVarArg : (* parameter *)
- NEW (obj);
- IF class = eValPar THEN obj.mode := Var
- ELSIF class = eVarPar THEN obj.mode := Ind
- 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 :
- NEW (obj); 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
- |
- eTProcE : (* exported type-bound procedure *)
- NEW (obj); 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;
- MakeTProcLabel (typ, obj)
- |
- eTProc : (* hidden type-bound procedure *)
- NEW (obj); obj.mode := TProc; obj.typ := notyp;
- ReadInt (l); typ := struct [l];
- ReadInt (obj.a0); ReadId (objName);
- obj.name := InsertName (objName);
- obj.a1 := typ.n; obj.visible := NotExp;
- obj.link := NIL; obj.left := typ.link; typ.link := obj;
- MakeTProcLabel (typ, obj); obj.name := -obj.name
- |
- eHPtr : (* hidden pointer field *)
- NEW (obj); 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;
- MakeTypeLabel (typ)
- END
- END
- |
- eMod : (* module anchor *)
- 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;
-
- MakeInitProcLabel (modname, k, modobj.label);
- MakeLabel (modname, InsertName ("VAR"), modobj.varLab);
- MakeLabel (modname, InsertName ("CONST"), modobj.constLab);
- MakeLabel (modname, InsertName ("GC-OFFSET"), modobj.gcLab);
- MakeLabel (modname, InsertName ("END"), modobj.endLab)
- END;
- IF nofLmod < maxMod THEN
- LocMod [nofLmod] := modobj; INC (nofLmod)
- ELSE
- OCS.Mark (227);
- END
- |
- eExtLib : (* External library, ignore *)
- ReadId (objName)
- |
- ELSE
- OCS.Mark (1005); OCS.Mark (class)
- END; (* CASE class *)
- END; (* LOOP *)
- Insert (alias, 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.label := LocMod [0].label;
- modobj.varLab := LocMod [0].varLab;
- modobj.constLab := LocMod [0].constLab;
- modobj.gcLab := LocMod [0].gcLab;
- modobj.endLab := LocMod [0].endLab
- ELSE
- OCS.Mark (157) (* illegal file tag *)
- END;
- F.Set (SR, NIL, 0); F.Close (SymFile)
- ELSE
- OCS.Mark (152); (* sym file not found *)
- OCM.SymbolFileName (name, pathName, FALSE);
- OCOut.Str1 (OCStrings.OCT1, pathName);
- END;
- END (* ELSE *)
- END Import;
-
-
- (*------------------------------------*)
- PROCEDURE ModuleInit * (name : ARRAY OF CHAR; VAR lab : Label);
-
- VAR
- s : SHORTINT;
- k : LONGINT;
- SymFile : F.File;
- fileName : ARRAY 32 OF CHAR;
- pathName : ARRAY 256 OF CHAR;
- modName : Name;
-
- <*$CopyArrays-*>
- BEGIN (* ModuleInit *)
- lab := NIL; k := 0;
- IF OCM.FindSymbolFile (name, pathName) THEN
- SymFile := F.Old (pathName);
- IF SymFile # NIL THEN
- F.Set (SR, SymFile, 0); ReadLInt (k);
- IF k >= MinSFtag THEN
- F.Read (SR, s);
- IF s = eMod THEN
- ReadLInt (k); ReadId (modName);
- IF modName # name THEN
- OCOut.Str1 (OCStrings.OCT2, pathName)
- END;
- ELSE
- OCOut.Str1 (OCStrings.OCT2, pathName)
- END
- ELSE
- OCOut.Str1 (OCStrings.OCT2, pathName)
- END;
- F.Set (SR, NIL, 0); F.Close (SymFile)
- ELSE
- OCOut.Str1 (OCStrings.OCT3, pathName)
- END
- ELSE
- OCM.SymbolFileName (name, pathName, FALSE);
- OCOut.Str1 (OCStrings.OCT1, pathName)
- END;
- MakeInitProcLabel (InsertName (name), k, lab)
- END ModuleInit;
-
-
- (*--- 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 WriteLabel ( label : Label );
-
- VAR i : LONGINT; ch : CHAR;
-
- BEGIN (* WriteLabel *)
- i := 0;
- REPEAT
- ch := label [i]; F.Write (SR, ch); INC (i)
- UNTIL ch = 0X;
- END WriteLabel;
-
- (*------------------------------------*)
- PROCEDURE^ OutStr (typ : Struct);
-
- (*------------------------------------*)
- PROCEDURE OutPars (par : Object; mode : INTEGER);
-
- BEGIN (* OutPars *)
- F.Write (SR, eParList);
- WHILE IsParam (par) DO
- OutStr (par.typ);
- IF par.mode = Var THEN F.Write (SR, eValPar)
- ELSIF par.mode = Ind THEN F.Write (SR, eVarPar)
- ELSE F.Write (SR, eVarArg)
- END;
- WriteInt (par.typ.ref);
- IF mode IN {LibCall, AProc} THEN WriteInt (par.a0)
- ELSE WriteInt (0)
- END;
- WriteId (par.name);
- par := par.link
- END;
- END OutPars;
-
- (*------------------------------------*)
- PROCEDURE OutFlds (fld : Object; adr : LONGINT; visible : BOOLEAN);
- BEGIN (* OutFlds *)
- 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) & (fld.typ.sysflg = OberonFlag))
- OR (fld.name < 0)
- THEN
- F.Write (SR, eHPtr); WriteInt (fld.a0 + adr)
- END
- END;
- fld := fld.left
- END;
- END OutFlds;
-
- (*------------------------------------*)
- PROCEDURE OutProcs (ref : INTEGER; fld : Object);
-
- BEGIN (* OutProcs *)
- WHILE fld # NIL DO
- IF fld.mode = TProc THEN
- IF fld.visible = Exp THEN
- OutStr (fld.typ); OutPars (fld.link, TProc);
- 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);
- WriteId (ABS (fld.name))
- END
- END;
- fld := fld.left
- END
- END OutProcs;
-
- (*------------------------------------*)
- PROCEDURE OutMod (VAR m : INTEGER);
-
- VAR em : INTEGER; mod : Module;
-
- BEGIN (* OutMod *)
- 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
- END OutMod;
-
- (*------------------------------------*)
- PROCEDURE OutStr (typ : Struct);
-
- VAR m, r : INTEGER; btyp : Struct;
-
- BEGIN (* OutStr *)
- 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 :
- F.Write (SR, ePointer);
- 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); WriteInt (typ.sysflg); WriteInt (typ.adr)
- |
- ProcTyp :
- OutStr (btyp); OutPars (typ.link, ProcTyp);
- 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.sysflg); 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) & (typ.sysflg = OberonFlag) THEN
- OutProcs (strno-1, typ.link)
- END
- END
- END; (* IF *)
- END OutStr;
-
- (*------------------------------------*)
- PROCEDURE OutObj (obj : Object);
-
- VAR f, m : INTEGER;
-
- BEGIN (* OutObj *)
- 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 = Pointer 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 :
- |
- AdrTyp, BPtrTyp, Pointer, 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, XProc);
- F.Write (SR, eXProc); WriteInt (obj.typ.ref); WriteId (obj.name);
- ELSIF obj.mode IN {M2Proc, CProc, AProc} THEN
- OutStr (obj.typ); OutPars (obj.link, obj.mode);
- IF obj.mode = M2Proc THEN F.Write (SR, eM2Proc)
- ELSIF obj.mode = CProc THEN F.Write (SR, eCProc)
- ELSE F.Write (SR, eAProc)
- END;
- WriteInt (obj.typ.ref); WriteLabel (obj.label);
- WriteId (obj.name);
- ELSIF obj.mode = LibCall THEN
- OutStr (obj.typ); OutPars (obj.link, LibCall);
- F.Write (SR, eLibCall); WriteInt (obj.typ.ref);
- WriteInt (obj.a0); WriteInt (obj.a1); WriteId (obj.name);
- END
- END; (* IF *)
- OutObj (obj.left); OutObj (obj.right)
- END; (* IF *)
- END OutObj;
-
- (*------------------------------------*)
- PROCEDURE OutImports ();
-
- VAR m : INTEGER; mod : Module;
-
- BEGIN (* OutImports *)
- FOR m := 0 TO (nofGmod - 1) 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
- END;
- FOR m := 0 TO (nofExtLib - 1) DO
- F.Write (SR, eExtLib); WriteId (extLib [m])
- END;
- END OutImports;
-
- (*------------------------------------*)
- PROCEDURE Export * (
- name : ARRAY OF CHAR;
- VAR newSF : BOOLEAN; VAR key : LONGINT);
-
- VAR
- i : INTEGER;
- ch0, ch1 : CHAR;
- oldkey : LONGINT;
- typ : Struct;
- oldFile, newFile : F.File;
- res : LONGINT;
- oldSR : F.Rider;
- equal : BOOLEAN;
- pathName, oldPathName : ARRAY 256 OF CHAR;
-
- <*$CopyArrays-*>
- BEGIN (* Export *)
- OCM.SymbolFileName (name, pathName, TRUE);
- newFile := F.New (pathName);
- IF newFile # NIL THEN
- F.Set (SR, newFile, 0);
- WriteLInt (SFtag);
- 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;
-
- IF OCM.Force OR ~OCS.scanerr THEN
- IF OCM.FindSymbolFile (name, oldPathName) THEN
- oldFile := F.Old (oldPathName)
- 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.Set (oldSR, NIL, 0); F.Close (oldFile);
- F.Set (SR, NIL, 0);
- IF equal THEN
- newSF := FALSE; key := oldkey; F.Purge (newFile);
- ELSIF newSF THEN
- F.Register (newFile);
- ELSE
- OCS.Mark (155); (*F.Purge (newFile);*) F.Close (newFile);
- OCOut.Str1 (OCStrings.OCT4, oldPathName)
- END
- ELSE
- F.Set (SR, NIL, 0); F.Register (newFile); newSF := TRUE
- END;
-
- IF newSF THEN
- IF OCM.Verbose THEN OCOut.Str1 (OCStrings.OCT5, pathName) END;
- OCM.MakeIcon (pathName, OCM.iconSym)
- END;
-
- MakeInitProcLabel (InsertName (ModuleName), key, InitLabel);
- MakeLabel (InsertName (ModuleName), InsertName ("END"), EndLabel)
- ELSE
- F.Set (SR, NIL, 0); F.Purge (newFile); newSF := FALSE
- END;
-
- ELSE
- OCOut.Str1 (OCStrings.OCT3, pathName);
- OCS.Mark (153)
- END;
- END Export;
-
- (*--- INITIALISATION ---------------------------------*)
-
- (*------------------------------------*)
- PROCEDURE InitStruct (VAR typ : Struct; f : INTEGER);
-
- BEGIN (* InitStruct *)
- NEW (typ); typ.form := f; typ.ref := f; typ.size := 1;
- typ.sysflg := OberonFlag
- END InitStruct;
-
- (*------------------------------------*)
- PROCEDURE EnterConst (name : ARRAY OF CHAR; value : INTEGER);
-
- VAR obj : Object;
-
- <*$CopyArrays-*>
- BEGIN (* EnterConst *)
- Insert (name, obj, Con); obj.typ := booltyp; obj.a0 := value;
- END EnterConst;
-
- (*------------------------------------*)
- PROCEDURE EnterTyp (
- name : ARRAY OF CHAR; form, size : INTEGER; VAR res: Struct);
-
- VAR obj : Object; typ : Struct;
-
- <*$CopyArrays-*>
- BEGIN (* EnterTyp *)
- Insert (name, obj, Typ); NEW (typ);
- obj.typ := typ; obj.visible := Exp;
- typ.form := form; typ.strobj := obj; typ.size := size;
- typ.sysflg := OberonFlag; typ.ref := form; res := typ;
- END EnterTyp;
-
- (*------------------------------------*)
- PROCEDURE EnterProc (name : ARRAY OF CHAR; num : INTEGER);
-
- VAR obj : Object;
-
- <*$CopyArrays-*>
- BEGIN (* EnterProc *)
- Insert (name, obj, SProc); obj.typ := notyp; obj.a0 := num
- END EnterProc;
-
- BEGIN (* OCT *)
- 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, OCM.BSetSize, bsettyp);
- EnterTyp ("WORDSET", WSet, OCM.WSetSize, wsettyp);
- EnterTyp ("PTR", PtrTyp, OCM.PtrSize, ptrtyp);
- EnterTyp ("BPTR", BPtrTyp, OCM.PtrSize, bptrtyp);
- bptrtyp.sysflg := BCPLFlag;
- EnterTyp ("ADDRESS", AdrTyp, OCM.PtrSize, adrtyp);
- adrtyp.sysflg := CFlag;
- EnterTyp ("BYTE", Byte, OCM.ByteSize, bytetyp);
- EnterTyp ("WORD", Word, 2, wordtyp);
- EnterTyp ("LONGWORD", Longword, 4, lwordtyp);
- EnterTyp ("TYPETAG", TagTyp, 4, tagtyp);
-
- EnterProc ("ADR", pADR); EnterProc ("AND", pAND);
- EnterProc ("BIT", pBIT); EnterProc ("CC", pCC);
- 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 ("STRLEN", pSTRLEN); EnterProc ("PUTREG", pPUTREG);
- EnterProc ("VAL", pVAL); EnterProc ("XOR", pXOR);
- EnterProc ("SETREG", pSETREG); EnterProc ("REG", pREG);
- EnterProc ("TAG", pTAG);
-
- syslink := topScope.link; universe := topScope; topScope.link := NIL;
-
- (* initialisation of predeclared types and procedures *)
-
- EnterTyp ("CHAR", Char, OCM.CharSize, chartyp);
- EnterTyp ("SET", Set, OCM.SetSize, settyp);
- EnterTyp ("REAL", Real, OCM.RealSize, realtyp);
- EnterTyp ("INTEGER", Int, OCM.IntSize, inttyp);
- EnterTyp ("LONGINT", LInt, OCM.LIntSize, linttyp);
- EnterTyp ("LONGREAL", LReal, OCM.LRealSize, lrltyp);
- EnterTyp ("SHORTINT", SInt, OCM.SIntSize, sinttyp);
- EnterTyp ("BOOLEAN", Bool, OCM.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);
-
- (* Save hash table for names so we can restore it *)
-
- nameOrg := nameX; backupTab := nameTab;
-
- (* initialisation of labels *)
-
- NEW (VarLabel, 64);
- NEW (ConstLabel, 64);
- NEW (InitLabel, 64);
- NEW (EndLabel, 64);
- NEW (GCLabel, 64);
- NEW (PointerDesc, 16); COPY ("Kernel_0T", PointerDesc^)
- END OCT.
-
- (***************************************************************************
-
- $Log: OCT.mod $
- Revision 5.23 1995/06/29 19:10:08 fjc
- - Removed code that was second-guessing the garbage collector
-
- Revision 5.22 1995/06/02 18:34:21 fjc
- - Added code to generate different init code label for
- resident modules.
-
- Revision 5.21 1995/05/19 16:00:57 fjc
- - Uses OCOut for console IO.
-
- Revision 5.20 1995/05/13 23:02:36 fjc
- - Made the a2 field a LONGINT;
-
- Revision 5.19 1995/05/08 17:09:16 fjc
- - Fixed bug in exporting VarArg parameters.
-
- Revision 5.18 1995/04/23 16:59:03 fjc
- - Merging 5.26 & 5.27
-
- Revision 5.16 1995/04/02 13:39:34 fjc
- - Generates different symbol for init code under the small
- data model.
-
- Revision 5.15 1995/03/25 16:58:55 fjc
- - Name field for hidden TProc objects is now <0.
-
- Revision 5.14 1995/03/23 18:03:23 fjc
- - Fixed pragmas.
-
- Revision 5.13 1995/02/27 16:53:17 fjc
- - Removed tracing code.
-
- Revision 5.12 1995/01/26 00:17:17 fjc
- - Release 1.5
-
- Revision 5.11 1995/01/09 13:50:25 fjc
- - Added call to OCM.MakeIcon().
- - Changed console output depending on OCM.Verbose.
-
- Revision 5.10 1995/01/05 11:29:50 fjc
- - Changed to force output of symbol file if OCM.Force is TRUE.
-
- Revision 5.9 1995/01/03 21:13:22 fjc
- - Changed OCG to OCM.
- - Changed to use catalogs:
- - Uses OCM for console I/O instead of Out.
- - Gets text from OCStrings instead of hard-coding it.
-
- Revision 5.7 1994/12/16 17:05:39 fjc
- - Moved code for constructing symbol file names and
- searching for symbol files to module OCG.
- - Renamed the Symbol type as Label and renamed associated
- variables, record fields and procedures.
- - Changed the way linker labels are generated.
-
- Revision 5.6 1994/11/13 11:20:48 fjc
- - Added CC to module SYSTEM.
-
- Revision 5.5 1994/10/23 15:44:27 fjc
- - Changed all references to OberonSys.lib to module Kernel.
- - Removed obsolete SYSTEM procedures: GC, RC, ARGLEN, ARGS,
- SIZETAG, SETCLEANUP, BIND, GETNAME and NEWTAG.
- - Increased # of modules that can be imported.
- - Renamed SYSTEM.CPTR to SYSTEM.ADDRESS, CPtrTyp to AdrTyp,
- and cptrtyp to adrtyp.
- - Uses new interface to module Strings, and module
- Conversions.
- - Added ModuleInit().
-
- Revision 5.4 1994/09/25 17:37:28 fjc
- - Removed code dealing with CPOINTERS, BPOINTERS and
- LIBCALLS.
- - Added code for new system flags and procedure types.
- - Implemented new symbol-file format.
-
- Revision 5.3 1994/09/19 23:10:05 fjc
- - Re-implemented Amiga library calls
-
- Revision 5.2 1994/09/15 10:15:51 fjc
- - Replaced switches with pragmas.
-
- Revision 5.1 1994/09/03 19:29:08 fjc
- - Bumped version number
-
- ***************************************************************************)
-