RoseWiringImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Barth, September 5, 1985 7:17:02 pm PDT
Spreitzer, November 18, 1985 10:29:16 pm PST
DIRECTORY Basics, CoreOps, CoreProperties, RedBlackTree, Rope, RoseBind, RoseWireClasses, RoseWireTypes, RoseWiring;
RoseWiringImpl: CEDAR PROGRAM
IMPORTS CoreOps, CP: CoreProperties, RedBlackTree, Rope, RoseBind, RoseWireClasses, RoseWireTypes
EXPORTS RoseWiring =
BEGIN OPEN CO: CoreOps, RoseWireClasses, RoseWiring;
ROPE: TYPE = Rope.ROPE;
Wire: TYPE = RoseWireTypes.Wire;
StructureOfWire: PROC [Wire] RETURNS [RoseWireTypes.CoreWireStructure] = RoseWireTypes.StructureOfWire;
protoToRWC: ARRAY RoseWireTypes.WireFlavor OF ATOM = [
simple: CP.RegisterProperty[$RoseWiringImplProtoToSimpleRWC],
switch: CP.RegisterProperty[$RoseWiringImplProtoToSwitchRWC],
drive: CP.RegisterProperty[$RoseWiringImplProtoToDriveRWC]
];
Derivation: TYPE = REF DerivationRec;
DerivationRec: TYPE = RECORD [
prototype: Wire,
class: RoseWireTypes.RoseWireClass
];
classes: ARRAY RoseWireTypes.WireFlavor OF RoseWireTypes.SymbolTable ← [
simple: RedBlackTree.Create[GetRWCKey, RWCCompareSimple],
switch: RedBlackTree.Create[GetRWCKey, RWCCompareSwitch],
drive: RedBlackTree.Create[GetRWCKey, RWCCompareDrive]
];
nameOverride: ATOMCP.RegisterProperty[$RoseWireNameOverride];
ComputeWiring: PUBLIC PROC [publicWirePrototype: Wire, betterName: ROPENIL] RETURNS [cw: RoseWireTypes.BehaviorClassWiring] = {
OverrideName[publicWirePrototype, betterName];
cw ← NEW [RoseWireTypes.BehaviorClassWiringRep ← [
simple: GetWiring[publicWirePrototype, simple],
switch: GetWiring[publicWirePrototype, switch],
drive: GetWiring[publicWirePrototype, drive]
]];
};
GetWiring: PUBLIC PROC [proto: Wire, flavor: RoseWireTypes.WireFlavor] RETURNS [rwc: RoseWireTypes.RoseWireClass] = {
drv: Derivation;
rwc ← NARROW[PV[proto, protoToRWC[flavor]]];
IF rwc # NIL THEN RETURN;
drv ← NARROW[classes[flavor].Lookup[proto]];
IF drv = NIL THEN {
SELECT TRUE FROM
StructureOfWire[proto] = atom
=> rwc ← SELECT flavor FROM
simple => GetBool[],
switch => GetBit[],
drive => GetDrive[],
ENDCASE => ERROR;
flavor=drive AND PV[proto, RoseBind.simpleDrive] # NIL
=> rwc ← GetDrive[];
StructureOfWire[proto] = record
=> rwc ← GetRecord[proto, flavor];
StructureOfWire[proto] = sequence AND StructureOfWire[proto.elements[0]] = atom AND flavor = drive AND PV[proto, RoseBind.complexDrive] = NIL
=> rwc ← GetDrive[];
StructureOfWire[proto] = sequence AND PV[proto, RoseBind.variableWire] # NIL
=> rwc ← GetVariableSequence[proto, flavor];
StructureOfWire[proto] = sequence AND StructureOfWire[proto.elements[0]] = atom AND flavor = simple
=> rwc ← GetBasicSequence[proto];
StructureOfWire[proto] = sequence
=> rwc ← GetFixedSequence[proto, flavor];
ENDCASE => ERROR;
drv ← NEW[DerivationRec ← [prototype: proto, class: rwc]];
classes[flavor].Insert[drv, proto];
}
ELSE rwc ← drv.class;
CP.PutWireProp[proto, protoToRWC[flavor], rwc];
};
OverrideName: PROC [w: Wire, name: ROPE] = {
CP.PutWireProp[w, nameOverride, name];
};
WireName: PUBLIC PROC [w: Wire] RETURNS [name: ROPE] = {
name ← NARROW[CP.GetWireProp[w, nameOverride]];
IF name = NIL THEN name ← CO.GetWireName[w];
};
GetRWCKey: PROC [data: REF ANY] RETURNS [proto: Wire] --RedBlackTree.GetKey-- = {
drv: Derivation ← NARROW[data];
proto ← drv.prototype;
};
RWCCompareSimple: PROC [k, data: REF ANY] RETURNS [c: Basics.Comparison] --RedBlackTree.Compare-- = {
k1: Wire ← NARROW[k];
k2: Wire ← GetRWCKey[data];
c ← WireCompare[k1, k2, TRUE, FALSE, TRUE];
};
RWCCompareSwitch: PROC [k, data: REF ANY] RETURNS [c: Basics.Comparison] --RedBlackTree.Compare-- = {
k1: Wire ← NARROW[k];
k2: Wire ← GetRWCKey[data];
c ← WireCompare[k1, k2, TRUE, FALSE, TRUE];
};
RWCCompareDrive: PROC [k, data: REF ANY] RETURNS [c: Basics.Comparison] --RedBlackTree.Compare-- = {
k1: Wire ← NARROW[k];
k2: Wire ← GetRWCKey[data];
c ← WireCompare[k1, k2, TRUE, TRUE, TRUE];
};
WireCompare: PROC [w1, w2: Wire, name, drive, variable: BOOL] RETURNS [c: Basics.Comparison] = {
IF name AND (c ← WireName[w1].Compare[WireName[w2]]) # equal THEN RETURN;
IF (c ← INTCompare[ORD[StructureOfWire[w1]], ORD[StructureOfWire[w2]]]) # equal THEN RETURN;
IF StructureOfWire[w1] = atom THEN RETURN;
IF drive AND (c ← BoolCompare[SimpleDrive[w1], SimpleDrive[w2]]) # equal THEN RETURN;
SELECT StructureOfWire[w1] FROM
record => {
IF (c ← INTCompare[w1.elements.size, w2.elements.size]) # equal THEN RETURN;
FOR i: INT IN [0 .. w1.elements.size) DO
e1: Wire ← w1.elements[i];
e2: Wire ← w2.elements[i];
IF (c ← WireCompare[e1, e2, TRUE, drive, variable]) # equal THEN RETURN;
ENDLOOP;
c ← equal;
};
sequence => {
IF variable AND (c ← BoolCompare[IsVariable[w1], IsVariable[w2]]) # equal THEN RETURN;
IF (c ← WireCompare[w1.elements[0], w2.elements[0], FALSE, drive, variable]) # equal THEN RETURN;
IF NOT (variable AND IsVariable[w1]) THEN c ← INTCompare[w1.elements.size, w2.elements.size];
};
ENDCASE => ERROR;
};
SimpleDrive: PROC [w: Wire] RETURNS [BOOL] = {
simple: BOOL = TRUE;
complex: BOOL = FALSE;
IF PV[w, RoseBind.simpleDrive] # NIL THEN RETURN [simple];
IF PV[w, RoseBind.complexDrive] # NIL THEN RETURN [complex];
IF StructureOfWire[w] = sequence AND StructureOfWire[w.elements[0]] = atom THEN RETURN [simple];
RETURN [complex];
};
IsVariable: PUBLIC PROC [w: Wire] RETURNS [BOOL] =
{RETURN [PV[w, RoseBind.variableWire] # NIL]};
PV: PROC [w: Wire, prop: ATOM] RETURNS [val: REF ANY] =
{val ← CP.GetWireProp[w, prop]};
INTCompare: PROC [i1, i2: INT] RETURNS [c: Basics.Comparison] = {
c ← SELECT i1 FROM
< i2 => less,
= i2 => equal,
> i2 => greater,
ENDCASE => ERROR;
};
BoolCompare: PROC [i1, i2: BOOL] RETURNS [c: Basics.Comparison] = {
c ← SELECT i1 FROM
< i2 => less,
= i2 => equal,
> i2 => greater,
ENDCASE => ERROR;
};
END.