CoreOps.mesa 
Copyright Ó 1985, 1986, 1987 by Xerox Corporation. All rights reserved.
Barth, October 31, 1986 9:44:19 am PST
Bertrand Serlet, June 4, 1987 1:23:12 pm PDT
Spreitzer, April 8, 1986 4:29:54 pm PST
Louis Monier, May 1, 1986 4:43:54 pm PDT
Pradeep Sindhu, February 7, 1986 3:20:36 pm PST
Mike Spreitzer February 27, 1987 2:35:34 pm PST
Last tweaked by Mike Spreitzer on November 2, 1987 3:39:45 pm PST
DIRECTORY Core, RefTab;
CoreOps: CEDAR DEFINITIONS = BEGIN OPEN Core;
Theory
This interface defines interesting utilities for the data structure defined in Core.
Property
nameProp: ATOM;
This atom is used by various types (wires, cellTypes, ...) to define a name (of type ROPE).
Cell Classes
SetClassPrintProc: PROC [class: CellClass, proc: PrintClassProc] RETURNS [sameClass: CellClass];
PrintClassProc: TYPE = PROC [data: REF ANY, out: STREAM, indent: NAT ← 0, level: NAT ← 2];
Cell Types
CreateCellType: PROC [class: CellClass, public: WireSeq, data: REF ANYNIL, name: ROPENIL, props: Properties ← NIL] RETURNS [cellType: CellType];
name, if non NIL, has precedence over props.
SetCellTypeName: PROC [cellType: CellType, name: ROPE] RETURNS [sameCellType: CellType];
Convenience for CoreProperties.PutCellTypeProp[cellType, nameProp, name].
GetCellTypeName: PROC [cellType: CellType] RETURNS [name: ROPE];
Convenience for CoreProperties.GetCellTypeProp[cellType, nameProp].
InheritCellTypeName: PROC [cellType: CellType] RETURNS [name: ROPE];
Looks for name on cellType. If not found and cellType.class.layersProps=TRUE then recasts and tries again. Keeps trying until found or cellType.class.layersProps=FALSE.
Recast: PROC [me: CellType, fillCacheIfEmpty: BOOLTRUE] RETURNS [new: CellType];
Returns the same pointer given the same cell type if fillCacheIfEmpty=TRUE. See the theory in Core.Mesa. IF fillCacheIfEmpty=FALSE then the recast cache is unchanged.
RecastBindingTable: PROC [cellType: CellType] RETURNS [table: RefTab.Ref];
Assumes it can call Recast[cellType].
table contains publics of cellType as keys and corresponding publics of Recast[cellType] as values.
ToBasic: PROC [cellType: Core.CellType] RETURNS [basic: Core.CellType];
Recasts as much as possible.
PrintCellType: PROC [cellType: CellType, out: STREAMNIL, indent: NAT ← 0, level: NAT ← 2];
PrintIndent: PROC [indent: NAT, out: STREAM, cr: BOOLTRUE];
Wire Creation
CreateWire: PROC [elements: Wires ← NIL, name: ROPENIL, props: Properties ← NIL] RETURNS [wire: Wire];
name, if non NIL, has precedence over props.
CreateWires: PROC [size: NAT, name: ROPENIL, props: Properties ← NIL] RETURNS [wire: Wire];
name, if non NIL, has precedence over props.
SubrangeWire: PROC [wire: Wire, start, size: NAT, name: ROPENIL, props: Properties ← NIL] RETURNS [sub: Wire];
name, if non NIL, has precedence over props.
CopyWire: PROC [wire: Wire] RETURNS [new: Wire];
Simple copy of a wire. Respects DAGness.
Only the name property is copied.
CopyWireUsingTable: PROC [old: Wire, oldToNew: RefTab.Ref, copyName: BOOLTRUE] RETURNS [new: Wire];
Fancy copy of a wire. Respects DAGness.
Table oldToNew maps old wires to new wires. As old DAG is visited, pairs are added into oldToNew.
If copyName, the name property is the only property copied, otherwise no property is copied.
UnionWire: PROC [wire1, wire2: Wire, name: ROPENIL, props: Properties ← NIL] RETURNS [union: Wire];
Creates a new structured wire of size wire1.size+wire2.size, with corresponding name and properties.
name, if non NIL, has precedence over props.
Wire Enumeration
EachWireProc: TYPE = PROC [wire: Wire] RETURNS [subWires: BOOLTRUE, quit: BOOLFALSE];
EachWirePairProc: TYPE = PROC [actualWire, publicWire: Wire] RETURNS [subWires: BOOLTRUE, quit: BOOLFALSE];
VisitWire: PROC [wire: Wire, eachWire: EachWireProc] RETURNS [quit: BOOL];
Returns quit iff eachWire did.
Visits the wire as a tree: each subwire reachable n ways is reached each of those n ways.
VisitWireSeq: PROC [seq: WireSeq, eachWire: EachWireProc] RETURNS [quit: BOOL];
Calls VisitWire on each element of the seq.
VisitRootAtomics: PROC [root: WireSeq, eachWire: PROC [Wire]];
Short for previous function, when only atomic wires should be enumerated, and when the quit argument is not needed.
Visits the wire as a tree: each subwire reachable n ways is reached each of those n ways.
VisitBinding: PROC [actual, public: Wire, eachWirePair: EachWirePairProc] RETURNS [quit: BOOL];
Visits two wires as trees in parallel. Aborts visit and returns quit=TRUE iff eachWirePair returns quit=TRUE or differing structure (viewed as trees) found.
VisitBindingSeq: PROC [actual, public: WireSeq, eachWirePair: EachWirePairProc] RETURNS [quit: BOOL];
Calls VisitBinding on each element of the two sequences.
Conform: PROC [actual, public: Wire] RETURNS [BOOL];
Works only for trees, not DAGs; checks that they have the same structure.
CorrectConform: PROC [actual, public: WireSeq] RETURNS [BOOL];
Works for DAGs, not just trees.
WireBits: PROC [wire: Wire] RETURNS [bits: NAT];
Computes the number of atomic wires reachable from wire.
WireSeqBits: PROC [seq: WireSeq] RETURNS [bits: NAT];
Guess what this does!
CreateBindingTable: PROC [wire1, wire2: Wire] RETURNS [table: RefTab.Ref];
Assumes that wire1 and wire2 conform.
table contains parts of wire1 as keys and corresponding parts of wire2 as values.
Wire Naming
Wires have attached 2 kinds of names: short names (at most one per wire) and full names, which are relative to a root wire (such as public or internal), and which are a list of ROPE since we have DAGs.
SetShortWireName: PROC [wire: Wire, name: ROPE] RETURNS [sameWire: Wire];
GetShortWireName: PROC [wire: Wire] RETURNS [name: ROPE];
GetWireIndex: PROC [wire: Wire, name: ROPE] RETURNS [n: INT ← -1];
If wire is not atomic, and wire[i] has short name "name" , then returns "i"; -1 if not found.
GetFullWireNames: PROC [root: WireSeq, wire: Wire] RETURNS [names: LIST OF ROPE];
Appends .name if a short name is on the wire otherwise appends [index]. Should only be called with root DAGs, e.g. a public wire. Full path names relative to the root DAG are cached (property on the root). A NIL list of names means that wire is not part of root or that wire is root and has no short name.
GetFullWireName: PROC [root: WireSeq, wire: Wire] RETURNS [name: ROPE];
Will return a random name amongst all the possible names obtained with GetFullWireNames, but consistently always the same one.
Will return NIL when called with a wire that has no full name.
Should only be called with root DAGs, e.g. a public wire.
IsFullWireName: PROC [root: WireSeq, wire: Wire, name: ROPE] RETURNS [BOOL];
FindWire: PROC [root: WireSeq, name: ROPE] RETURNS [wire: Wire ← NIL];
Fetches a wire part of root with full name name. NIL is returned if no wire is found.
ParseWireName: PROC [name: ROPE] RETURNS [base: ROPE, components: LIST OF ROPENIL];
Breaks apart a wire name into its components. Eg., given the name "foo.mumble[3].bar", base is "foo", and components is LIST["mumble", "3", "bar"].
PrintWire: PROC [wire: Wire, out: STREAMNIL, indent: NAT ← 0, level: NAT ← 2];
FlushNameCaches: PROC [root: WireSeq];
Various caches are stored on roots, and this function gets rid of them.
Wires Operations
Reverse: PROC [wires: Wires] RETURNS [revWires: Wires ← NIL];
Delete: PROC [wires: Wires, wire: Wire] RETURNS [newWires: Wires ← NIL];
Member: PROC [wires: Wires, wire: Wire] RETURNS [BOOL];
Searches for wire in the list wires.
ParentWires: PROC [root, candidate: Wire] RETURNS [parents: LIST OF Wire ← NIL];
Searches for the direct parents of candidate starting at root.
Implementation is slow, but allows easier interactive debugging.
RecursiveMember: PROC [wire, candidate: Wire] RETURNS [BOOL];
Searches for candidate in the structured wire wire.
Miscellaneous
Index: PROC [rope: ROPE, index: NAT] RETURNS [indexed: ROPE];
Creates a name of the form rope[index], with some degree of efficiency.
FixStupidRef: PROC [ref: REF ANY] RETURNS [rope: ROPE];
Converts a rope or ref text into a rope.
RopeDammit: PROC [ref: ROPE] RETURNS [rope: ROPE]
= INLINE {rope ← ref};
Stupid compiler.
Print: PROC [ref: REF, out: STREAMNIL, indent: NAT ← 0, level: NAT ← 2];
Works on NIL, Wire, Wires and CellType. User convenience only.
END.