CoreOps.mesa 
Copyright © 1985, 1986 by Xerox Corporation. All rights reserved.
Barth, October 31, 1986 9:44:19 am PST
Bertrand Serlet, October 17, 1986 5:36:43 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 November 18, 1986 2:28:13 pm PST
DIRECTORY Core, HashTable;
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: HashTable.Table];
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];
Only the name 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.
CreateBindingTable: PROC [wire1, wire2: Wire] RETURNS [table: HashTable.Table];
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.