CoreFlattenImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Barth, March 28, 1986 6:24:07 pm PST
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
rct.class.recast = NIL exactly when rct is a record or atomic.
NULL;
ENDLOOP;
};
Path ::= (start) ?(/ (sawSlash) ?( (instanceRemove) Remove | ROOT ) (expectInstanceNameOrNumber) ?(( Name | Number ) (sawInstanceNameOrNumber) /...) .) (sawDot) ?(((PUBLIC | INTERNAL | ACTUAL ) (sawWireRoot) . ) | (wireRemove) Remove ) (expectWireNameOrNumber) ( Name | Number ) (sawWireNameOrNumber) ....
PathParseStates: TYPE = {start, sawSlash, instanceRemove, expectInstanceNameOrNumber, sawInstanceNameOrNumber, sawDot, sawWireRoot, wireRemove, expectWireNameOrNumber, sawWireNameOrNumber};
ParseError: PUBLIC ERROR [msg: Core.ROPENIL] = 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.ROPENIL] = {
IF m=NIL THEN m ← "parse failed";
ERROR ParseError[m];
};
state: PathParseStates ← start;
visitingActual: BOOLTRUE;
s: IO.STREAMIO.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.