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;
 
};