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˜—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šžœ˜—šœžœ ž˜'šœžœž˜,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šžœ˜—…—Π$λ