DIRECTORY Atom USING [EmptyAtom, GetPName, MakeAtom], Basics USING [LongNumber], FS USING [ComponentPositions, Error, ExpandName, StreamOpen], RefTab USING [Ref, Val, Create, Delete, Fetch, Store], RefText USING [line, TrustTextAsRope], IO, Rope, MicroDefs, MicroGlobalVars, MicroOps, MicroUtils; MicroSymbolsImpl: CEDAR PROGRAM IMPORTS Atom, FS, IO, RefTab, RefText, Rope, MicroDefs, MicroGlobalVars, MicroOps, MicroUtils EXPORTS MicroOps, MicroUtils = BEGIN OPEN MicroDefs, MicroGlobalVars, MicroUtils; ROPE: TYPE = Rope.ROPE; symbolIndexBase: INTEGER = 256; SymbolIndexSeq: TYPE = REF SymbolIndexSeqRec; SymbolIndexSeqRec: TYPE = RECORD[sym: SEQUENCE max: [symbolIndexBase .. 4256] OF MicroDefs.SymbolObj]; symbolTable: RefTab.Ref; symbolTableSize: NAT = 2047; symbolIndexSeq: SymbolIndexSeq; nextSymbolIndex: INTEGER _ symbolIndexBase; nullSymObj: SymbolObj; lastStIndexPlus1: INTEGER _ 256; line: REF TEXT _ NEW[TEXT[RefText.line]]; symbolsTimeStamp: ROPE _ NIL; symbolsVersionStamp: ROPE = "March 3, 1986 12:43:59 pm PST"; LookupSymbol: PUBLIC PROC[ePtr: LONG POINTER TO WORD, len: INTEGER] RETURNS[symIndex: INTEGER, symb: ATOM] = { found: BOOL; val: RefTab.Val; symb _ MicroUtils.AtomAtPointer[ePtr, len]; [found, val] _ RefTab.Fetch[symbolTable, symb]; IF found THEN { sym: SymbolObj _ NARROW[val]; IF sym.symIndex < symbolIndexBase THEN MicroDefs.Error[" Bad symIndex: LookupSymbol"]; RETURN[sym.symIndex, symb] }; RETURN[0, symb]; }; GetSymbol: PUBLIC PROC[symIndex: INTEGER] RETURNS[symbolRec: SymbolObj] = { IF symIndex >= nextSymbolIndex THEN RETURN[NIL]; IF symIndex = 0 THEN RETURN[nullSymObj]; IF symIndex < symbolIndexBase THEN MicroDefs.Error[" Bad symIndex: GetSymbol"]; RETURN[symbolIndexSeq[symIndex]]; }; NewDef: PUBLIC PROC[symIndex: INTEGER] RETURNS[newObj: SymbolObj] = { sym: SymbolObj; newIndex: INTEGER; IF symIndex >= lastStIndexPlus1 THEN RETURN[GetSymbol[symIndex]]; sym _ symbolIndexSeq[symIndex]; -- old symbol IF sym.redef # NIL AND sym.symIndex >= lastStIndexPlus1 THEN RETURN[sym]; [newIndex, newObj] _ PutInSymbol[sym.symb, nullType]; newObj.redef _ sym; -- link to old symbol via its symbolObj symbolIndexSeq[symIndex] _ newObj; [] _ RefTab.Store[symbolTable, sym.symb, newObj]; -- replace old object in symbolTable }; PutInSymbol: PUBLIC PROC[symb: ATOM, type: SymbolType] RETURNS[symIndex: INTEGER, sObj: SymbolObj] = { really: ATOM = IF symb = NIL THEN Atom.EmptyAtom[] ELSE symb; IF nextSymbolIndex < symbolIndexBase THEN MicroDefs.Error[" Bad symIndex: PutInSymbol"]; sObj _ NEW[SymbolRec _ [really, Atom.GetPName[really], type, nextSymbolIndex] ]; [] _ RefTab.Store[symbolTable, really, sObj]; symbolIndexSeq[symIndex _ nextSymbolIndex] _ sObj; nextSymbolIndex _ nextSymbolIndex + 1; }; LookupAtom: PUBLIC PROC[symb: ATOM] RETURNS[symIndex: INTEGER] = { found: BOOL; val: RefTab.Val; [found, val] _ RefTab.Fetch[symbolTable, symb]; IF found THEN { sym: SymbolObj _ NARROW[val]; IF sym.symIndex < symbolIndexBase THEN MicroDefs.Error[" Bad symIndex: LookupAtom"]; RETURN[sym.symIndex] }; RETURN[0]; }; InitSymbolTable: PUBLIC PROC = { symbolTable _ RefTab.Create[symbolTableSize]; -- easiest IF symbolIndexSeq = NIL THEN symbolIndexSeq _ NEW[SymbolIndexSeqRec[4000]] ELSE FOR i: INTEGER IN [400 .. nextSymbolIndex) DO symbolIndexSeq[i] _ NIL; ENDLOOP; lastStIndexPlus1 _ nextSymbolIndex _ symbolIndexBase; nullSymObj _ PutInSymbol[NIL, nullType].sObj; -- 0 and 1 are not valid symbol indices [] _ PutInSymbol[NIL, nullType]; }; prefixRope: ROPE = "*prefix*"; symbolRope: ROPE = "*symbol*"; memoryRope: ROPE = "*memory*"; macroRope: ROPE = "*macros*"; RecoverSymbols: PUBLIC PROC[fromFile: ROPE, recoverOld: BOOL _ FALSE] RETURNS[success: BOOL] = { StripDirectory: PROC [in: ROPE] RETURNS [rope: ROPE] ~ { fullFName: ROPE; cp: FS.ComponentPositions; [fullFName, cp, ] _ FS.ExpandName[in]; RETURN [Rope.Substr[base: fullFName, start: cp.base.start, len: cp.base.length+cp.ext.length+1]]; }; strm: STREAM; currentNextSymbolIndex: INTEGER _ nextSymbolIndex; newNextSymbolIndex: INTEGER; ropeIn, versionOnFile: ROPE; sameSymbols: BOOL _ FALSE; success _ FALSE; strm _ FS.StreamOpen[fromFile ! FS.Error => { reportStrm.PutRope[error.explanation]; GOTO cant} ]; strm.SetIndex[0]; ropeIn _ strm.GetLineRope[]; -- *prefix* IF ~ropeIn.Equal[prefixRope] THEN RETURN[FALSE]; ropeIn _ StripDirectory[strm.GetLineRope[]]; -- fileName IF ~ropeIn.Equal[StripDirectory[fromFile], FALSE] THEN RETURN[FALSE]; versionOnFile _ strm.GetLineRope[]; -- versionStamp as rope IF ~versionOnFile.Equal[symbolsVersionStamp] THEN MicroDefs.Error[IO.PutFR[ "Symbols versionStamp on file (%g) is different than program's (%g)", IO.rope[versionOnFile], IO.rope[symbolsVersionStamp] ]]; ropeIn _ strm.GetLineRope[]; -- timeStamp as rope sameSymbols _ ropeIn.Equal[symbolsTimeStamp]; commentChar _ strm.GetChar[]; [] _ strm.GetChar[]; mbExtn _ strm.GetLineRope[]; newNextSymbolIndex _ nextSymbolIndex _ lastStIndexPlus1 _ strm.GetInt[]; lastMemNum _ strm.GetInt[]; targetSym _ strm.GetInt[]; nextMacroIndex _ strm.GetInt[]; traceCalls _ strm.GetBool[]; ignore _ strm.GetBool[]; traceSyms _ strm.GetBool[]; [] _ strm.GetChar[]; -- '\n IF sameSymbols THEN { FOR i: INTEGER IN [nextSymbolIndex .. currentNextSymbolIndex) DO sObj: SymbolObj = symbolIndexSeq[i]; symbolIndexSeq[i] _ NIL; -- release storage as well IF sObj.redef = NIL OR sObj.redef.symIndex >= nextSymbolIndex THEN { [] _ RefTab.Delete[symbolTable, sObj.symb]; LOOP; }; [] _ RefTab.Store[symbolTable, sObj.symb, sObj.redef]; symbolIndexSeq[sObj.redef.symIndex] _ sObj.redef; ENDLOOP; } ELSE { InitSymbolTable[]; nextSymbolIndex _ newNextSymbolIndex; }; DO line _ strm.GetLine[line]; IF ~symbolRope.Equal[RefText.TrustTextAsRope[line]] THEN EXIT; RecoverOneSymbol[strm, sameSymbols]; ENDLOOP; IF ~macroRope.Equal[RefText.TrustTextAsRope[line]] THEN ERROR MicroDefs.Error[]; IF ~sameSymbols THEN TRUSTED { macIndex: INT = nextMacroIndex; MicroOps.InitMacroOps[]; -- make sure there is macro storage [] _ strm.UnsafeGetBlock[[LOOPHOLE[macroStorageStart], 0, 2*macIndex]]; nextMacroIndex _ macIndex; }; lastStIndexPlus1 _ nextSymbolIndex; symbolsTimeStamp _ ropeIn; RETURN[TRUE]; EXITS cant => RETURN[FALSE]; }; RecoverOneSymbol: PROC[strm: STREAM, sameSymbols: BOOL] = { sObj: SymbolObj; IF sameSymbols THEN { symb: ATOM = Atom.MakeAtom[strm.GetLineRope[]]; sObj _ GetSymbol[LookupAtom[symb]]; IF sObj = NIL THEN MicroDefs.Error[ IO.PutFR["%g not found in symbols table", IO.atom[symb]]]; } ELSE { sObj _ NEW[SymbolRec]; sObj.name _ strm.GetLineRope[]; sObj.symb _ Atom.MakeAtom[sObj.name]; }; sObj.sType _ LOOPHOLE[LOOPHOLE[strm.GetInt[], Basics.LongNumber].lo, SymbolType]; sObj.symIndex _ strm.GetInt[]; sObj.sMisc _ strm.GetInt[]; sObj.sVal _ LOOPHOLE[strm.GetCard[], Basics.LongNumber].lo; [] _ strm.GetChar[]; -- \n following number SELECT sObj.sType FROM macroType => { mDef: INT _ strm.GetInt[]; [] _ strm.GetChar[]; sObj.sData _ NEW[INT _ mDef]; }; memoryType => { memNum: INTEGER _ strm.GetInt[]; [] _ strm.GetChar[]; IF memNum # -1 THEN RecoverOneMemory[strm, sObj, memNum] }; bitTableType => { bitTabSize: INTEGER _ strm.GetInt[]; [] _ strm.GetChar[]; IF bitTabSize # 0 THEN { bt: BitTableObj _ NEW[BitTableRec _ [btSize: bitTabSize]]; bt.btBits _ NEW[WordSeqRec[bitTabSize]]; FOR j: INTEGER IN [0..bitTabSize) DO bt.btBits[j] _ GetWord[strm]; ENDLOOP; sObj.sData _ bt; }; }; ENDCASE => NULL; [] _ RefTab.Store[symbolTable, sObj.symb, sObj]; symbolIndexSeq[sObj.symIndex] _ sObj; }; RecoverOneMemory: PROC[strm: STREAM, sObj: SymbolObj, memNum: INTEGER] = { mem: Memory _ NARROW[sObj.sData]; accWord, listFields: INTEGER; line _ strm.GetLine[line]; -- should be *memory* IF ~memoryRope.Equal[RefText.TrustTextAsRope[line]] THEN ERROR MicroDefs.Error[]; IF mem = NIL THEN sObj.sData _ mem _ NEW[MemoryRec]; mem.symIndex _ sObj.symIndex; mem.memoryNum _ memNum; mem.widthInBits _ strm.GetInt[]; mem.widthInWords _ strm.GetInt[]; mem.size _ strm.GetInt[]; mem.sourceIndex _ strm.GetInt[]; mem.sinkIndex _ strm.GetInt[]; mem.listOptions _ strm.GetInt[]; mem.lTag _ strm.GetInt[]; mem.memSymPost _ strm.GetInt[]; mem.tagMacro _ strm.GetInt[]; MicroUtils.SetMemoryFromNum[memNum, mem]; accWord _ strm.GetInt[]; [] _ strm.GetChar[]; IF accWord = 0 THEN mem.accumWord _ NIL ELSE { len: NAT = accWord; mem.accumWord _ NEW[WordSeqRec[len]]; FOR j: NAT IN [0 .. len) DO mem.accumWord[j] _ GetWord[strm]; ENDLOOP; [] _ strm.GetChar[]; }; listFields _ strm.GetInt[]; [] _ strm.GetChar[]; IF listFields = 0 THEN mem.listFields _ NIL ELSE { len: NAT = listFields; mem.listFields _ NEW[WordSeqRec[len]]; FOR j: NAT IN [0 .. len) DO mem.listFields[j] _ GetWord[strm]; ENDLOOP; [] _ strm.GetChar[]; }; }; DumpSymbols: PUBLIC PROC[toFileRec: MicroDefs.OutputFile] RETURNS[success: BOOL, oldLastStIndexPlus1: INTEGER] = { strm: STREAM; success _ FALSE; oldLastStIndexPlus1 _ lastStIndexPlus1; IF toFileRec.strm = NIL THEN MicroUtils.OpenOutputStream[toFileRec]; strm _ toFileRec.strm; strm.PutRope[prefixRope]; strm.PutChar['\n]; strm.PutRope[toFileRec.fullName]; strm.PutF["\n%g", IO.rope[symbolsVersionStamp] ]; -- versionStamp strm.PutF["\n%g\n", IO.rope[symbolsTimeStamp _ IO.PutFR[NIL, IO.time[]]] ]; -- timestamp strm.PutChar[commentChar]; strm.PutChar[' ]; strm.PutRope[mbExtn]; strm.PutF["\n%g %g %g %g\n", IO.int[nextSymbolIndex], IO.int[lastMemNum], IO.int[targetSym], IO.int[nextMacroIndex]]; strm.PutF["%g %g %g\n", IO.bool[traceCalls], IO.bool[ignore], IO.bool[traceSyms]]; FOR i: INTEGER IN [symbolIndexBase+2 .. nextSymbolIndex) DO sObj: SymbolObj = GetSymbol[i]; strm.PutRope[symbolRope]; strm.PutChar['\n]; strm.PutF["%g\n%g %g %g %g\n", IO.rope[sObj.name], IO.int[LOOPHOLE[sObj.sType, INTEGER]], IO.int[sObj.symIndex], IO.int[sObj.sMisc], IO.card[sObj.sVal] ]; SELECT sObj.sType FROM macroType => { mDef: REF INT = NARROW[sObj.sData]; strm.PutF["%g\n", IO.int[mDef^]]; }; memoryType => IF sObj.sData = NIL THEN strm.PutRope["-1\n"] ELSE { mem: Memory = NARROW[sObj.sData]; strm.PutF["%g\n", IO.int[mem.memoryNum]]; strm.PutRope[memoryRope]; strm.PutChar['\n]; strm.PutF["%g %g %g %g\n", IO.int[mem.widthInBits], IO.int[mem.widthInWords], IO.int[mem.size], IO.int[mem.sourceIndex]]; strm.PutF["%g %g %g %g %g\n", IO.int[mem.sinkIndex], IO.int[mem.listOptions], IO.int[mem.lTag], IO.int[mem.memSymPost], IO.int[mem.tagMacro]]; IF mem.accumWord = NIL THEN strm.PutF["0\n"] ELSE { strm.PutF["%g\n", IO.int[mem.accumWord.length]]; FOR j: NAT IN [0..mem.accumWord.length) DO MicroUtils.PutWord[strm, mem.accumWord[j]]; ENDLOOP; strm.PutChar['\n]; }; IF mem.listFields = NIL THEN strm.PutF["0\n"] ELSE { strm.PutF["%g\n", IO.int[mem.listFields.length]]; FOR j: NAT IN [0..mem.listFields.length) DO PutWord[strm, mem.listFields[j]]; ENDLOOP; strm.PutChar['\n]; }; }; bitTableType => { IF sObj.sData = NIL THEN strm.PutRope["0\n"] ELSE { bt: BitTableObj = NARROW[sObj.sData]; strm.PutF["%g\n", IO.int[bt.btSize]]; FOR j: INTEGER IN [0..bt.btSize) DO PutWord[strm, bt.btBits[j]]; ENDLOOP; strm.PutChar['\n]; }; }; ENDCASE => NULL; ENDLOOP; strm.Flush[]; strm.PutRope[macroRope]; strm.PutChar['\n]; strm.UnsafePutBlock[[base: LOOPHOLE[macroStorageStart], startIndex: 0, count: 2*nextMacroIndex]]; strm.Flush[]; lastStIndexPlus1 _ nextSymbolIndex; success _ TRUE; }; FilterSyms: PUBLIC PROC[typ: SymbolType, startIndex: INTEGER _ -1] RETURNS[lSyms: LIST OF MicroDefs.SymbolObj] = { lowestIndex: INTEGER = IF startIndex = -1 THEN lastStIndexPlus1 ELSE startIndex; symIndex: INTEGER _ nextSymbolIndex; dontDumpList: LIST OF INTEGER _ NIL; MaybeAddToSeq: PROC[so: SymbolObj] = { sI: INTEGER = so.symIndex; reDefSym: SymbolObj = so.redef; IF reDefSym # NIL AND reDefSym.symIndex >= lowestIndex THEN dontDumpList _ CONS[reDefSym.symIndex, dontDumpList] ELSE IF dontDumpList # NIL THEN { -- see if this sI should NOT be dumped FOR iL: LIST OF INTEGER _ dontDumpList, iL.rest UNTIL iL=NIL DO IF iL.first = sI THEN RETURN; ENDLOOP; }; lSyms _ CONS[so, lSyms]; }; DO sObj: SymbolObj; IF (symIndex _ symIndex - 1) < lowestIndex THEN EXIT; sObj _ MicroOps.GetSymbol[symIndex]; IF sObj.sType = typ THEN MaybeAddToSeq[sObj]; ENDLOOP; }; nullSymObj _ NEW[SymbolRec _ [Atom.EmptyAtom[], Atom.GetPName[Atom.EmptyAtom[]], nullType, 0] ]; END. JMicroSymbolsImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Willie-sue, October 29, 1987 1:46:56 pm PST Dave Rumph, April 20, 1988 11:13:12 am PDT taken from MicSym.bcpl and (distantly) MicSA.bcpl If symIndex is new, do nothing; if symIndex is old, make a new symbol for its name and return the new index; the new symbolObj gets stored in BOTH the old and new places in the symbolTable read the rest of the prefix clean out any symbols with index >= nextSymbolIndex; put old SymbolObj back into symbol table this ends the prefix information dump the symbols; do not dump symbolIndexBase & symbolIndexBase+1, but rather start with symbolIndexBase+2 dump macro storage Collect all symbols whose sType = typ and are new since a RestoreSymbols was done, if newSinceStFile is -1, else startLooking at startIndex Κ’˜šœ™Icodešœ Οmœ1™Jšœ$˜$Jšžœ˜—šžœ1ž˜7Jšžœ˜—šžœžœžœ˜Jšœ žœ˜Jšœ #˜=Jšœžœ%˜GJšœ˜J˜—Jšœ#˜#Jšœ˜šžœžœ˜ J˜Jšžœ žœžœ˜—J˜—J˜šŸœžœžœžœ˜;Jšœ˜šžœ žœ˜Jšœžœ%˜/Jšœ#˜#šžœžœžœ˜#Jšžœ(žœ˜:—J˜šžœ˜Jšœžœ ˜J˜J˜%J˜——J˜Jšœ žœžœ3˜QJšœ˜Jšœ˜Jšœ žœ'˜;Jšœ ˜,J˜šžœ ž˜šœ˜Jšœžœ˜J˜Jšœ žœžœ ˜J˜—šœ˜Jšœžœ˜ J˜Jšžœ žœ%˜8Jšœ˜—šœ˜Jšœ žœ˜$J˜šžœžœ˜Jšœžœ%˜:Jšœ žœ˜(šžœžœžœž˜%J˜Jšžœ˜—Jšœ˜J˜—J˜—šžœžœ˜J˜——Jšœ0˜0Jšœ%˜%J˜—J˜šŸœžœžœžœ˜JJšœžœ ˜!Jšœžœ˜Jšœ ˜1šžœ2ž˜8Jšžœ˜—Jšžœžœžœžœ ˜4Jšœ˜Jšœ˜Jšœ ˜ Jšœ!˜!Jšœ˜Jšœ ˜ Jšœ˜Jšœ ˜ Jšœ˜Jšœ˜Jšœ˜Jšœ)˜)J˜.šžœ žœžœžœ˜.Jšœžœ ˜Jšœžœ˜%Jš žœžœžœ žœ#žœ˜FJ˜J˜—Jšœ1˜1šžœžœžœžœ˜2Jšœžœ˜Jšœžœ˜&Jš žœžœžœ žœ$žœ˜GJ˜J˜—J˜—J˜šŸ œžœžœ!˜9Jšœžœ žœžœ˜9Jšœžœ˜ Jšœ žœ˜Jšœ'˜'Jšžœžœžœ(˜DJšœ˜J˜-Jšœ!˜!Jšœžœ ˜Bšœ˜Jš œžœžœžœžœ  ˜F—J˜-J˜šœžœžœ˜IJšžœžœ˜+—Jšœžœžœžœ˜RJšœ ™ J™Jšœk™kšžœžœžœ(ž˜;J˜Jšœ-˜-šœ˜Jšžœžœžœ žœ˜:Jšžœžœžœ˜@—J˜šžœ ž˜˜Jšœžœžœžœ ˜#Jšœžœ ˜!J˜—˜ šžœžœžœžœ˜4Jšœžœ ˜!Jšœžœ˜)J˜-šœžœžœ˜MJšžœžœ˜+—šœžœžœ˜MJšžœžœžœ˜@—J˜šžœžœžœžœ˜3Jšœžœ˜0šžœžœžœž˜+Jšœ+˜+Jšžœ˜—J˜J˜—šžœžœžœžœ˜4Jšœžœ˜1šžœžœžœž˜,Jšœ!˜!Jšžœ˜—J˜J˜—J˜—˜šžœžœžœžœ˜3Jšœžœ ˜%Jšœžœ˜%šžœžœžœž˜$Jšœ˜Jšžœ˜—J˜J˜—J˜—Jšžœžœ˜——Jšžœ˜—J˜J˜ Jšœ™Jšœ+˜+Jšœžœ>˜aJ˜ Jšœ#˜#Jšœ žœ˜J˜—J˜šŸ œžœžœžœ˜BJšœžœžœžœ˜0Jšœ‹™‹J™Jš œ žœžœžœžœ ˜PJšœ žœ˜$Jš œžœžœžœžœ˜$šŸ œžœ˜&Jšœžœ˜Jšœ˜š žœ žœžœ"žœžœ"˜qš žœžœžœžœ &˜Iš žœžœžœžœžœžœž˜?Jšžœžœžœ˜Jšžœ˜—J˜——Jšœžœ ˜Jšœ˜—šž˜Jšœ˜Jšžœ)žœžœ˜5Jšœ$˜$Jšžœžœž˜-Jšžœ˜ —J˜—J˜—šœ ˜ JšžœP˜S—J˜Jšžœ˜—…—/ςBή