CoreSequenceCellsImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Last Edited by: Barth, August 13, 1985 7:31:19 pm PDT
Bertrand Serlet August 14, 1985 10:56:34 am PDT
Spreitzer, August 12, 1985 5:22:30 pm PDT
DIRECTORY Core, CoreOps, CoreProperties, CoreRecordCells, CoreSequenceCells, HashTable, IO;
CoreSequenceCellsImpl:
CEDAR
PROGRAM
IMPORTS CoreOps, CoreProperties, CoreRecordCells, HashTable, IO
EXPORTS CoreSequenceCells =
BEGIN OPEN Core, CoreSequenceCells;
sequenceCellClass: PUBLIC CellClass ← NEW[CellClassRec ← [name: "SequenceCell", recast: Recast, write: Write, read: Read]];
cacheAtom: ATOM = $SequenceCellCache;
Start:
PROC = {
CoreOps.RegisterCellClass[sequenceCellClass];
CoreProperties.RegisterProperty[prop: cacheAtom];
};
Recast: RecastProc = {
seqCell: SequenceCell ← NARROW[me.data];
recCell: CoreRecordCells.RecordCell ← NEW[CoreRecordCells.RecordCellRec];
new ←
NEW[CellTypeRec ← [
name: me.name,
class: CoreRecordCells.recordCellClass,
publicWire: CoreOps.CopyWire[wire: me.publicWire],
data: recCell,
properties: CoreProperties.CopyProps[propList: me.properties]]];
recCell.internalWire ←
NEW[WireRec ← [
structure: sequence]];
recCell.internalWire.elements ← NEW[WireSequenceRec[new.publicWire.elements.size + seqCell.stitches.length]];
FOR w:
NAT
IN [0..new.publicWire.elements.size)
DO
recCell.internalWire.elements[w] ← new.publicWire.elements[w];
ENDLOOP;
FOR w:
NAT
IN [new.publicWire.elements.size..recCell.internalWire.elements.size)
DO
recCell.internalWire.elements[w] ← NEW[WireRec ← [structure: sequence]];
recCell.internalWire.elements[w].elements ← NEW[WireSequenceRec[ seqCell.count]];
ENDLOOP;
FOR cell:
NAT
IN [0..seqCell.count)
DO
newWire: Wire ← NEW[WireRec ← new.publicWire^];
newWire.elements ← NEW[WireSequenceRec[new.publicWire.elements.size] ← new.publicWire.elements^];
FOR seqWire:
NAT
IN [0..seqCell.length)
DO
newWire.elements[seqCell.sequence[seqWire]] ← newWire.elements[seqCell.sequence[seqWire]].elements[cell];
ENDLOOP;
FOR stitchWire:
NAT
IN [0..seqCell.stitches.length)
DO
internal: Wire;
IF cell < seqCell.count -1
THEN {
internal ← CoreOps.CopyWire[wire: seqCell.base.publicWire.elements[seqCell.stitches[stitchWire].source]];
recCell.internalWire.elements[stitchWire + new.publicWire.elements.size].elements[cell] ← internal;
newWire.elements[seqCell.stitches[stitchWire].source] ← internal;
};
IF cell > 0 THEN newWire.elements[seqCell.stitches[stitchWire].sink] ← recCell.internalWire.elements[stitchWire + new.publicWire.elements.size].elements[cell-1];
ENDLOOP;
recCell.instances ←
CONS[
NEW[CoreRecordCells.InstanceRec ← [
name: IF seqCell.base.name=NIL THEN NIL ELSE IO.PutFR["%g%g", IO.rope[seqCell.base.name], IO.int[cell]],
actualWire: newWire,
type: seqCell.base]],
recCell.instances];
ENDLOOP;
};
Create:
PUBLIC
PROC [design: Design, name:
ROPE, args: SequenceCell]
RETURNS [cellType: CellType] = {
cache: HashTable.Table ← NARROW[CoreProperties.GetProp[from: design.properties, prop: cacheAtom]];
IF cache =
NIL
THEN {
cache ← HashTable.Create[equal: CompareType];
design.properties ← CoreProperties.PutProp[on: design.properties, prop: cacheAtom, value: cache];
};
cellType ← NARROW [HashTable.Fetch[table: cache, key: args].value];
IF cellType=
NIL
THEN {
cellType ←
NEW[CellTypeRec ← [
name: name,
class: sequenceCellClass,
publicWire: CoreOps.CopyWire[wire: args.base.publicWire],
data: args]];
FOR i:
NAT
IN [0..args.length)
DO
wire: Wire ← cellType.publicWire.elements[args.sequence[i]];
newWire: Wire ← CoreOps.CreateSequenceWire[name: wire.name, base: wire, count: args.count];
cellType.publicWire.elements[args.sequence[i]] ← newWire;
ENDLOOP;
};
};
CompareType:
PROC [key1, key2: HashTable.Key]
RETURNS [
BOOL] = {
s1: SequenceCell ← NARROW[key1];
s2: SequenceCell ← NARROW[key2];
IF s1.base#s2.base OR s1.count#s2.count OR s1.length#s2.length OR s1.stitches.length#s2.stitches.length THEN RETURN[FALSE];
FOR i:
NAT
IN [0..s1.length)
DO
IF s1.sequence[i]#s2.sequence[i] THEN RETURN[FALSE];
ENDLOOP;
FOR i:
NAT
IN [0..s1.stitches.length)
DO
IF s1.stitches[i]#s2.stitches[i] THEN RETURN[FALSE];
ENDLOOP;
RETURN[TRUE];
};
Print:
PUBLIC
PROC [cell: SequenceCell, out:
STREAM] = {
IO.PutF[out, "\n\nBase cell type: %g", IO.rope[cell.base.name]];
IO.PutF[out, ", count: %g, sequence wires:", IO.int[cell.count]];
FOR seq:
NAT
IN [0..cell.length)
DO
IO.PutF[out, " %g", IO.rope[cell.base.publicWire.elements[cell[seq]].name]];
ENDLOOP;
};
Start[];
END.