DIRECTORY Convert, Core, CoreClasses, CoreIO, CoreOps, CoreProperties, FS, HashTable, IO, Rope; CoreIOImpl: CEDAR PROGRAM IMPORTS Convert, CoreOps, CoreProperties, FS, HashTable, IO, Rope EXPORTS CoreIO SHARES Core = BEGIN OPEN CoreIO; CoreWriteProcProp: ATOM = $CoreWriteProc; CoreReadProcProp: ATOM = $CoreReadProc; classRegistry: HashTable.Table _ HashTable.Create[equal: HashTable.RopeEqual, hash: HashTable.HashRope]; SaveCellType: PUBLIC PROC [cellType: Core.CellType, fileName: ROPE _ NIL] = { h: Handle _ NEW[HandleRec]; IF fileName=NIL THEN fileName _ Rope.Cat[CoreOps.GetCellTypeName[cellType], ".core"]; h.stream _ FS.StreamOpen[fileName, $create]; h.cellTypeIDTab _ HashTable.Create[]; h.ropeIDTab _ HashTable.Create[equal: HashTable.RopeEqual, hash: HashTable.HashRope]; WriteCellType[h, cellType]; }; RestoreCellType: PUBLIC PROC [cellName: ROPE _ NIL, fileName: ROPE _ NIL] RETURNS [cellType: Core.CellType] = { h: Handle _ NEW[HandleRec]; IF fileName=NIL AND cellName=NIL THEN ERROR; IF fileName=NIL THEN fileName _ Rope.Cat[cellName, ".core"]; h.stream _ FS.StreamOpen[fileName]; h.cellTypeIDTab _ HashTable.Create[equal: HashTable.RopeEqual, hash: HashTable.HashRope]; h.ropeIDTab _ HashTable.Create[equal: HashTable.RopeEqual, hash: HashTable.HashRope]; cellType _ ReadCellType[h]; }; WriteCellType: PROC [h: Handle, cellType: Core.CellType] = { cellTypeID: ROPE _ NARROW[HashTable.Fetch[h.cellTypeIDTab, cellType].value]; IF cellTypeID=NIL THEN { wireIDTab: HashTable.Table _ HashTable.Create[]; classWrite: REF ClassWriteProc _ NARROW[CoreProperties.GetCellClassProp[from: cellType.class, prop: CoreWriteProcProp]]; cellTypeID _ Rope.Cat["C", Convert.RopeFromInt[from: h.nextCellTypeID, base: 16, showRadix: FALSE]]; IF NOT HashTable.Insert[h.cellTypeIDTab, cellType, cellTypeID] THEN ERROR; h.nextCellTypeID _ h.nextCellTypeID + 1; WriteID[h, cellTypeID]; [] _ WriteWire[h, wireIDTab, 0, cellType.public]; WriteProperties[h, cellType.properties]; WriteRope[h, cellType.class.name]; classWrite^[h, cellType, wireIDTab]; } ELSE WriteID[h, cellTypeID]; }; ReadCellType: PROC [h: Handle] RETURNS [cellType: Core.CellType] = { cellTypeID: ROPE _ ReadID[h]; cellType _ NARROW[HashTable.Fetch[h.cellTypeIDTab, cellTypeID].value]; IF cellType=NIL THEN { wireIDTab: HashTable.Table _ HashTable.Create[equal: HashTable.RopeEqual, hash: HashTable.HashRope]; className: ROPE; classRead: REF ClassReadProc; cellType _ NEW[Core.CellTypeRec]; IF NOT HashTable.Insert[h.cellTypeIDTab, cellTypeID, cellType] THEN ERROR; cellType.public _ ReadWire[h, wireIDTab]; cellType.properties _ ReadProperties[h]; className _ ReadRope[h]; cellType.class _ NARROW[HashTable.Fetch[classRegistry, className].value]; classRead _ NARROW[CoreProperties.GetCellClassProp[from: cellType.class, prop: CoreReadProcProp]]; classRead^[h, cellType, wireIDTab]; }; }; WriteWire: PROC [h: Handle, wireIDTab: HashTable.Table, nextWireID: INT, wire: Core.Wire] RETURNS [newNextWireID: INT] = { wireID: ROPE _ NARROW[HashTable.Fetch[wireIDTab, wire].value]; newNextWireID _ nextWireID; IF wireID=NIL THEN { wireID _ Rope.Cat["W", Convert.RopeFromInt[from: newNextWireID, base: 16, showRadix: FALSE]]; IF NOT HashTable.Insert[wireIDTab, wire, wireID] THEN ERROR; newNextWireID _ newNextWireID + 1; WriteID[h, wireID]; WriteInt[h, wire.size]; WriteProperties[h, wire.properties]; FOR w: NAT IN [0..wire.size) DO newNextWireID _ WriteWire[h, wireIDTab, newNextWireID, wire[w]]; ENDLOOP; } ELSE WriteID[h, wireID]; }; ReadWire: PROC [h: Handle, wireIDTab: HashTable.Table] RETURNS [wire: Core.Wire] = { wireID: ROPE _ ReadID[h]; wire _ NARROW[HashTable.Fetch[wireIDTab, wireID].value]; IF wire=NIL THEN { wireSize: NAT _ ReadInt[h]; wire _ NEW[Core.WireRec[wireSize]]; IF NOT HashTable.Insert[wireIDTab, wireID, wire] THEN ERROR; wire.properties _ ReadProperties[h]; FOR w: NAT IN [0..wire.size) DO wire[w] _ ReadWire[h, wireIDTab]; ENDLOOP; }; }; WriteProperties: PROC [h: Handle, properties: Core.Properties] = { propCount: INT _ 0; FOR props: Core.Properties _ properties, props.rest UNTIL props=NIL DO propCount _ propCount + 1; ENDLOOP; WriteInt[h, propCount]; FOR props: Core.Properties _ properties, props.rest UNTIL props=NIL DO propKey: ATOM _ NARROW[props.first.key]; propWrite: REF PropWriteProc _ NARROW[CoreProperties.GetProp[from: CoreProperties.FetchProperties[propKey], prop: CoreWriteProcProp]]; IO.PutF[h.stream, "%g ", IO.atom[propKey]]; IF propWrite=NIL THEN WITH props.first.val SELECT FROM r: ROPE => {WriteID[h, "R"]; WriteRope[h, r]}; i: REF INT => {WriteID[h, "I"]; IO.PutF[h.stream, "%g ", IO.int[i^]]}; n: REF NAT => {WriteID[h, "N"]; IO.PutF[h.stream, "%g ", IO.int[n^]]}; a: ATOM => {WriteID[h, "A"]; IO.PutF[h.stream, "%g ", IO.atom[a]]}; ENDCASE => ERROR ELSE propWrite^[h, propKey, props.first.val]; ENDLOOP; }; ReadProperties: PROC [h: Handle] RETURNS [properties: Core.Properties _ NIL] = { propCount: INT _ ReadInt[h]; FOR c: INT IN [0..propCount) DO key: ATOM _ IO.GetAtom[h.stream]; val: REF ANY; propRead: REF PropReadProc _ NARROW[CoreProperties.GetProp[from: CoreProperties.FetchProperties[key], prop: CoreReadProcProp]]; IF propRead=NIL THEN { type: ROPE _ ReadID[h]; val _ SELECT TRUE FROM Rope.Equal["R", type] => ReadRope[h], Rope.Equal["I", type] => NEW[INT _ IO.GetInt[h.stream]], Rope.Equal["N", type] => NEW[INT _ IO.GetInt[h.stream]], Rope.Equal["A", type] => IO.GetAtom[h.stream], ENDCASE => ERROR; } ELSE val _ propRead^[h, key]; properties _ CONS[[key, val], properties]; ENDLOOP; }; WriteID: PROC [h: Handle, id: ROPE] = { IO.PutRope[h.stream, id]; IO.PutRope[h.stream, " "]; }; ReadID: PROC [h: Handle] RETURNS [id: ROPE] = { id _ IO.GetID[h.stream]; }; WriteRope: PROC [h: Handle, rope: ROPE] = { ropeID: ROPE _ NARROW[HashTable.Fetch[h.ropeIDTab, rope].value]; IF ropeID=NIL THEN { ropeID _ Rope.Cat["r", Convert.RopeFromInt[from: h.nextRopeID, base: 16, showRadix: FALSE]]; IF NOT HashTable.Insert[h.ropeIDTab, rope, ropeID] THEN ERROR; h.nextRopeID _ h.nextRopeID + 1; WriteID[h, ropeID]; IO.PutF[h.stream, "%g ", IO.refAny[rope]]; } ELSE WriteID[h, ropeID]; }; ReadRope: PROC [h: Handle] RETURNS [rope: ROPE] = { ropeID: ROPE _ ReadID[h]; rope _ NARROW[HashTable.Fetch[h.ropeIDTab, ropeID].value]; IF rope=NIL THEN { rope _ IO.GetRopeLiteral[h.stream]; IF NOT HashTable.Insert[h.ropeIDTab, ropeID, rope] THEN ERROR; }; }; WriteInt: PROC [h: Handle, val: INT] = { IO.PutF[h.stream, "%g ", IO.int[val]]; }; ReadInt: PROC [h: Handle] RETURNS [int: INT] = { int _ IO.GetInt[h.stream]; }; RegisterClass: PUBLIC PROC [class: Core.CellClass, write: ClassWriteProc, read: ClassReadProc] = { CoreProperties.PutCellClassProp[class, CoreWriteProcProp, NEW[ClassWriteProc _ write]]; CoreProperties.PutCellClassProp[class, CoreReadProcProp, NEW[ClassReadProc _ read]]; [] _ HashTable.Store[classRegistry, class.name, class]; }; RegisterProperty: PUBLIC PROC [prop: ATOM, write: PropWriteProc, read: PropReadProc] = { props: Core.Properties _ CoreProperties.FetchProperties[prop]; props _ CoreProperties.PutProp[props, CoreWriteProcProp, NEW[PropWriteProc _ write]]; props _ CoreProperties.PutProp[props, CoreReadProcProp, NEW[PropReadProc _ read]]; CoreProperties.StoreProperties[prop, props]; }; END. –CoreIOImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Barth, May 6, 1986 1:40:59 pm PDT Cell Type IO IO Registration Κy– "cedar" style˜codešœ™Kšœ Οmœ1™žœ žœ˜_K˜•StartOfExpansion[]šΠbn œžœž˜Kšžœ#žœ žœ˜AKšžœ˜Kšžœ˜ Kšœžœžœ˜K˜—KšΟnœžœ˜)Kš œžœ˜'K˜Kšœh˜hhead™ š   œžœžœ%žœžœ˜MKšœ žœ ˜Kšžœ žœžœA˜UKšœ žœ˜,Kšœ%˜%KšœU˜UKšœ˜K˜K™—š œžœžœ žœžœ žœžœžœ˜oKšœ žœ ˜Kš žœ žœžœ žœžœžœ˜,Kšžœ žœžœ(˜Kšœ˜šžœžœžœ˜KšœUžœ˜]Kšžœžœ+žœžœ˜Kšœ ˜ Kšœ˜Kšžœžœ˜*K˜—Kšžœ˜K˜K˜—š œžœ žœžœ˜3Kšœžœ ˜Kšœžœ-˜:šžœžœžœ˜Kšœžœ˜#Kšžœžœ-žœžœ˜>K˜—K˜K˜—š œžœžœ˜(Kšžœžœ ˜&K˜K˜—š œžœ žœžœ˜0Kšœžœ˜K˜K˜——™š  œžœžœH˜bKšœ:žœ˜WKšœ9žœ˜TKšœ7˜7Kšœ˜K˜—š œžœžœžœ/˜XKšœ>˜>Kšœ9žœ˜UKšœ8žœ˜RKšœ,˜,Kšœ˜K˜——Kšžœ˜—…—F%U