DIRECTORY Convert, Core, CoreClasses, CoreFlatten, CoreOps, IO, Rope;

CoreFlattenImpl: CEDAR PROGRAM
IMPORTS Convert, CoreClasses, CoreOps, IO, Rope
EXPORTS CoreFlatten
= BEGIN

Recordify: PUBLIC PROC [ct: Core.CellType] RETURNS [rc: Core.CellType] = {
FOR rc _ ct, CoreOps.Recast[rc] UNTIL rc.class.recast = NIL DO 
NULL;
ENDLOOP;
};

PathParseStates: TYPE = {start, sawSlash, instanceRemove, expectInstanceNameOrNumber, sawInstanceNameOrNumber, sawDot, sawWireRoot, wireRemove, expectWireNameOrNumber, sawWireNameOrNumber};

ParseError: PUBLIC ERROR [msg: Core.ROPE _ NIL] = CODE;

GetNewPath: PUBLIC PROC [rootCellType: Core.CellType, newPath: Core.ROPE, currentInstancePath: CoreClasses.CellInstances _ NIL, currentWirePath: Core.Wires _ NIL] RETURNS [newInstancePath: CoreClasses.CellInstances, newWirePath: Core.Wires] = {

RemoveInstance: PROC = {
IF newInstancePath=NIL THEN MakeError["Underflowed instance path"];
state _ instanceRemove;
newInstancePath _ newInstancePath.rest;
};

AppendNameInstance: PROC = {
ct: Core.CellType _ Recordify[newInstancePath.first.type];
rct: CoreClasses.RecordCellType _ NARROW[ct.data];
instance: CoreClasses.CellInstance _ NIL;
IF Rope.Equal[token, "ROOT", FALSE] THEN ERROR;
state _ sawInstanceNameOrNumber;
FOR inst: CARDINAL IN [0..rct.size) DO
IF Rope.Equal[token, CoreClasses.GetCellInstanceName[rct[inst]]] THEN {
instance _ rct[inst];
EXIT;
};
REPEAT FINISHED => FOR inst: CARDINAL IN [0..rct.size) DO
IF Rope.Equal[token, CoreOps.GetCellTypeName[rct[inst].type]] THEN {
IF instance#NIL THEN MakeError["Append by cell type name is ambiguous"];
instance _ rct[inst];
};
ENDLOOP;
ENDLOOP;
IF instance=NIL THEN MakeError["Can't find instance or cell type"];
newInstancePath _ CONS[instance, newInstancePath];
};

AppendNumberInstance: PROC = {
ct: Core.CellType _ Recordify[newInstancePath.first.type];
rct: CoreClasses.RecordCellType _ NARROW[ct.data];
inst: CARDINAL _ Convert.CardFromRope[token];
state _ sawInstanceNameOrNumber;
IF inst>rct.size THEN MakeError["No such instance"];
newInstancePath _ CONS[rct[inst], newInstancePath];
};

RemoveWire: PROC = {
IF newWirePath=NIL THEN MakeError["Underflowed wire path"];
state _ wireRemove;
newWirePath _ newWirePath.rest;
};

AppendNameWire: PROC = {
parent: Core.Wire _ NIL;
child: Core.Wire _ NIL;
state _ sawWireNameOrNumber;
IF RootWire[]#none THEN MakeError["Cannot name a wire actual, internal, or public"];
IF newWirePath=NIL THEN MakeError["No wire root"];
parent _ newWirePath.first;
IF visitingActual THEN {
ERROR; -- not implemented
}
ELSE {
FOR subWire: CARDINAL IN [0..parent.size) DO
IF Rope.Equal[token, CoreOps.GetShortWireName[parent[subWire]]] THEN {
child _ parent[subWire];
EXIT;
};
ENDLOOP;
IF child=NIL THEN MakeError["Can't find wire"];
newWirePath _ CONS[child, newWirePath];
};
};

AppendNumberWire: PROC = {
subWire: CARDINAL _ Convert.CardFromRope[token];
state _ sawWireNameOrNumber;
IF newWirePath=NIL THEN MakeError["No wire root"];
IF subWire>newWirePath.first.size THEN MakeError["No such wire"];
newWirePath _ CONS[newWirePath.first[subWire], newWirePath];
};

PossibleRootWire: PROC = {
SELECT RootWire[] FROM
public => {
state _ sawWireRoot;
newWirePath _ IF newInstancePath=NIL THEN LIST[rootCellType.public]
ELSE LIST[newInstancePath.first.type.public];
};
internal => {
ct: Core.CellType _ Recordify[IF newInstancePath=NIL THEN rootCellType ELSE newInstancePath.first.type];
rct: CoreClasses.RecordCellType _ NARROW[ct.data];
state _ sawWireRoot;
newWirePath _ LIST[rct.internal];
};
actual => {
state _ sawWireRoot;
IF newInstancePath=NIL THEN MakeError["No instance for actual"];
newWirePath _ LIST[newInstancePath.first.actual];
visitingActual _ TRUE;
};
none => AppendNameWire[];
ENDCASE => ERROR;
 
};

RootWireType: TYPE = {public, internal, actual, none};

RootWire: PROC RETURNS [RootWireType] = {
RETURN [SELECT TRUE FROM
Rope.Equal[token, "PUBLIC", FALSE] => public,
Rope.Equal[token, "INTERNAL", FALSE] => internal,
Rope.Equal[token, "ACTUAL", FALSE] => actual,
ENDCASE => none];
};

MakeError: PROC [m: Core.ROPE _ NIL] = {
IF m=NIL THEN m _ "parse failed";
ERROR ParseError[m];
};

state: PathParseStates _ start;
visitingActual: BOOL _ TRUE;
s: IO.STREAM _ IO.RIS[newPath];
tokenKind: IO.TokenKind;
token: Core.ROPE;
newInstancePath _ currentInstancePath;
newWirePath _ currentWirePath;
DO
[tokenKind, token] _ IO.GetCedarTokenRope[s ! IO.EndOfStream => EXIT];
SELECT state FROM
start => SELECT tokenKind FROM
tokenSINGLE => SELECT Rope.Fetch[token] FROM
'/ => state _ sawSlash;
'- => RemoveWire[];
ENDCASE => MakeError[];
tokenID => PossibleRootWire[];
tokenDECIMAL => AppendNumberWire[];
ENDCASE => MakeError[];
sawSlash => SELECT tokenKind FROM
tokenSINGLE => SELECT Rope.Fetch[token] FROM
'- => RemoveInstance[];
'. => state _ sawDot;
ENDCASE => MakeError[];
tokenID => {
state _ sawInstanceNameOrNumber;
IF Rope.Equal[token, "ROOT", FALSE] THEN newInstancePath _ NIL
ELSE AppendNameInstance[];
};
tokenDECIMAL => AppendNumberInstance[];
ENDCASE => MakeError[];
instanceRemove => SELECT tokenKind FROM
tokenSINGLE => SELECT Rope.Fetch[token] FROM
'- => RemoveInstance[];
'. => state _ sawDot;
ENDCASE => MakeError[];
tokenID => AppendNameInstance[];
tokenDECIMAL => AppendNumberInstance[];
ENDCASE => MakeError[];
expectInstanceNameOrNumber => SELECT tokenKind FROM
tokenID => AppendNameInstance[];
tokenDECIMAL => AppendNumberInstance[];
ENDCASE => MakeError[];
sawInstanceNameOrNumber => SELECT tokenKind FROM
tokenSINGLE => SELECT Rope.Fetch[token] FROM
'/ => state _ expectInstanceNameOrNumber;
'. => state _ sawDot;
ENDCASE => MakeError[];
ENDCASE => MakeError[];
sawDot => SELECT tokenKind FROM
tokenSINGLE => SELECT Rope.Fetch[token] FROM
'- => RemoveWire[];
ENDCASE => MakeError[];
tokenID => PossibleRootWire[];
tokenDECIMAL => AppendNumberWire[];
ENDCASE => MakeError[];
sawWireRoot => SELECT tokenKind FROM
tokenSINGLE => SELECT Rope.Fetch[token] FROM
'. => state _ expectWireNameOrNumber;
ENDCASE => MakeError[];
ENDCASE => MakeError[];
wireRemove => SELECT tokenKind FROM
tokenSINGLE => SELECT Rope.Fetch[token] FROM
'- => RemoveWire[];
ENDCASE => MakeError[];
tokenID => AppendNameWire[];
tokenDECIMAL => AppendNumberWire[];
ENDCASE => MakeError[];
expectWireNameOrNumber => SELECT tokenKind FROM
tokenID => AppendNameWire[];
tokenDECIMAL => {state _ sawWireNameOrNumber; AppendNumberWire[]};
ENDCASE => MakeError[];
sawWireNameOrNumber => SELECT tokenKind FROM
tokenSINGLE => SELECT Rope.Fetch[token] FROM
'. => state _ expectWireNameOrNumber;
ENDCASE => MakeError[];
ENDCASE => MakeError[];
ENDCASE => MakeError[];
ENDLOOP;
};

END.
��ò��CoreFlattenImpl.mesa
Copyright c 1985 by Xerox Corporation.  All rights reserved.
Barth, March 28, 1986 6:24:07 pm PST

rct.class.recast = NIL exactly when rct is a record or atomic.
Path ::= (start) ?(/ (sawSlash) ?( (instanceRemove) Remove  | ROOT ) (expectInstanceNameOrNumber) ?(( Name | Number ) (sawInstanceNameOrNumber) /...) .) (sawDot) ?(((PUBLIC | INTERNAL | ACTUAL ) (sawWireRoot) . ) | (wireRemove) Remove ) (expectWireNameOrNumber) ( Name | Number ) (sawWireNameOrNumber) ....

�Ê	)��–
"cedar" style˜�codešœ™Kšœ
Ïmœ1™<K™$K™�—KšÏk	œ3žœ˜EK˜�•StartOfExpansion[]šÏbœžœž˜Kšžœ žœ˜/Kšžœ˜Kšœž˜—K˜�šÏn	œžœžœžœ˜Jšžœžœžœžœ˜?Kšœžœ(™>Kšžœ˜Kšžœ˜—Kšœ˜K˜�—Kš.ŸœŸœ
ŸœŸœžœŸœŸœŸœŸœŸœŸœ
ŸžœŸœžœŸœžœŸœŸœŸœŸœŸœŸœŸ™²K™�Kšœžœ¨˜½K˜�Kšœžœžœžœžœžœ˜7K˜�š 
œžœžœ-žœ3žœ žœžœJ˜ôK˜�š œžœ˜Kšžœžœžœ(˜CKšœ˜Kšœ'˜'Kšœ˜K˜�—š œžœ˜Kšœ:˜:Kšœ"žœ
˜2Kšœ%žœ˜)Kšžœžœžœžœ˜/Kšœ ˜ šžœžœžœž˜&šžœ?žœ˜GKšœ˜Kšžœ˜K˜—šžœžœžœžœžœž˜9šžœ<žœ˜DKšžœ
žœžœ4˜HKšœ˜K˜—Kšžœ˜—Kšžœ˜—Kšžœ
žœžœ/˜CKšœžœ˜2K˜K˜�—š œžœ˜Kšœ:˜:Kšœ"žœ
˜2Kšœžœ˜-Kšœ ˜ Kšžœžœ˜4Kšœžœ˜3Kšœ˜K˜�—š 
œžœ˜Kšžœ
žœžœ$˜;Kšœ˜Kšœ˜K˜K˜�—š œžœ˜Kšœžœ˜Kšœžœ˜Kšœ˜Kšžœžœ=˜TKšžœ
žœžœ˜2Kšœ˜šžœžœ˜KšžœÏc˜K˜—šžœ˜šžœ
žœžœž˜,šžœ>žœ˜FKšœ˜Kšžœ˜K˜—Kšžœ˜—Kšžœžœžœ˜/Kšœžœ˜'K˜—K˜K˜�—š œžœ˜Kšœ	žœ˜0Kšœ˜Kšžœ
žœžœ˜2Kšžœ žœ˜AKšœžœ*˜<Kšœ˜K˜�—š œžœ˜šžœž˜šœ˜Kšœ˜Kš	œžœžœžœžœ˜CKšžœžœ$˜-K˜—šœ
˜
Kš	œžœžœžœžœ˜hKšœ"žœ
˜2Kšœ˜Kšœžœ˜!K˜—šœ˜Kšœ˜Kšžœžœžœ%˜@Kšœžœ˜1Kšœžœ˜K˜—Kšœ˜Kšžœžœ˜Kšœ˜—K˜K˜�—Kšœžœ$˜6K˜�š œžœžœ˜)šžœžœžœž˜Kšœžœ˜-Kšœžœ˜1Kšœžœ˜-Kšžœ
˜—K˜K˜�—š 	œžœ
žœžœ˜(Kšžœžœžœ˜!Kšžœ˜K˜K˜�—Kšœ˜Kšœžœžœ˜Kš	œžœžœžœžœ
˜Kšœžœ˜Kšœžœ˜Kšœ&˜&Kšœ˜šž˜Kšœžœžœžœ˜Fšžœž˜šœ	žœž˜šœžœž˜,Kšœ˜Kšœ˜Kšžœ˜—Kšœ˜Kšœ#˜#Kšžœ˜—šœžœž˜!šœžœž˜,Kšœ˜Kšœ˜Kšžœ˜—šœ˜Kšœ ˜ Kšžœžœžœž˜>Kšžœ˜Kšœ˜—Kšœ'˜'Kšžœ˜—šœžœž˜'šœžœž˜,Kšœ˜Kšœ˜Kšžœ˜—Kšœ ˜ Kšœ'˜'Kšžœ˜—šœžœž˜3Kšœ ˜ Kšœ'˜'Kšžœ˜—šœžœž˜0šœžœž˜,Kšœ)˜)Kšœ˜Kšžœ˜—Kšžœ˜—šœ
žœž˜šœžœž˜,Kšœ˜Kšžœ˜—Kšœ˜Kšœ#˜#Kšžœ˜—šœžœž˜$šœžœž˜,Kšœ%˜%Kšžœ˜—Kšžœ˜—šœžœž˜#šœžœž˜,Kšœ˜Kšžœ˜—Kšœ˜Kšœ#˜#Kšžœ˜—šœžœž˜/Kšœ˜KšœB˜BKšžœ˜—šœžœž˜,šœžœž˜,Kšœ%˜%Kšžœ˜—Kšžœ˜—Kšžœ˜—Kšžœ˜—K˜K˜�—Kšžœ˜—�…—����Ð��$ë��