LichenNameInheritence.Mesa
Last tweaked by Mike Spreitzer on April 12, 1989 3:16:02 pm PDT
DIRECTORY AbSets, AMBridge, AMTypes, BiRelBasics, BiRels, Convert, FS, Interpreter, IntStuff, IO, LichenDataOps, LichenDataStructure, Rope, SetBasics, SymTab;
LichenNameInheritence: CEDAR PROGRAM
IMPORTS AMBridge, AMTypes, BiRelBasics, BiRels, Convert, FS, Interpreter, IO, LichenDataStructure, Rope, SetBasics, SymTab
EXPORTS LichenDataOps
=
BEGIN OPEN IS:IntStuff, Sets:AbSets, LichenDataStructure, LichenDataOps;
Break: SIGNAL ~ CODE;
LoopDataList: TYPE ~ LIST OF LoopData;
LoopData: TYPE ~ REF LoopDataPrivate;
StringData: TYPE ~ REF LoopDataPrivate[string];
NumData: TYPE ~ REF LoopDataPrivate[number];
LoopDataPrivate: TYPE ~ RECORD [
index: ROPE,
tv: AMTypes.TV,
variant: SELECT kind: * FROM
number => [min, max: INT, ri: REF INTNEW [INT]],
string => [vals: Seq, rr: REF ROPENEW [ROPE], i: INT ← 0],
ENDCASE];
breakICT: CellType ← NIL;
breakPortName: SteppyName ← noName;
RenBrk: PROC [char: CHAR] RETURNS [IO.CharClass] --IO.BreakProc-- ~ {
RETURN [SELECT char FROM
IN [0C .. ' ] => sepr,
':, ',, '{, '} => break,
ENDCASE => other]};
OpenBrk: PROC [char: CHAR] RETURNS [IO.CharClass] --IO.BreakProc-- ~ {
RETURN [SELECT char FROM
IN [0C .. ' ] => sepr,
':, ',, '{, '}, '[, '], '= => break,
ENDCASE => other]};
ReadRenames: PUBLIC PROC [d: Design, fileName: ROPE] RETURNS [renames: Fn--CellType b Fn(old steppy b new)--, renamesCount: INT ← 0] ~ {
in: IO.STREAM ~ FS.StreamOpen[fileName];
tab: SymTab.Ref ~ SymTab.Create[];
symbolsList: Interpreter.SymbolsList ~ LIST[tab];
i2d: Fn ~ BiRels.CreateHashTable[[SetBasics.ropes[TRUE], SetBasics.refs]];
refRes: REF INT ~ NEW [INT];
tvRes: AMTypes.TV;
TRUSTED {tvRes ← AMBridge.TVForReferent[refRes]};
renames ← BiRels.CreateHashTable[[d.eSpace, BiRelBasics.CreateBiRelSpace[ALL[steppyNameSpace]] ]];
FOR ctName: ROPE ← in.GetTokenRope[RenBrk].token, in.GetTokenRope[RenBrk].token UNTIL ctName.Equal["."] DO
ct: CellType ~ d.FetchCellType[ctName];
open: ROPE ~ in.GetTokenRope[RenBrk].token;
rns: Fn ~ BiRels.CreateHashTable[ALL[steppyNameSpace]];
IF NOT open.Equal["{"] THEN ERROR;
DO
oldR: ROPE ~ in.GetTokenRope[RenBrk].token;
assoc: ROPE ~ in.GetTokenRope[RenBrk].token;
newR: ROPE ~ in.GetTokenRope[RenBrk].token;
old: SteppyName ~ ParseSteppyName[oldR];
new: SteppyName ~ ParseSteppyName[newR];
lds: LoopDataList ← NIL;
sep: ROPE;
DoLoop: PROC [ldl: LoopDataList, nil: BOOL] ~ {
IF ldl#NIL THEN WITH ldl.first SELECT FROM
sd: StringData => {
PerVal: PROC [i: INT, v: REF ANY] ~ {
sd.i ← i; sd.rr^ ← NARROW[v];
DoLoop[ldl.rest, FALSE];
RETURN};
sd.vals.EnumIA[PerVal]};
nd: NumData => FOR i: INT IN [nd.min .. nd.max] DO
nd.ri^ ← i;
DoLoop[ldl.rest, FALSE];
ENDLOOP;
ENDCASE => ERROR
ELSE IF nil THEN rns.AddNewPair[[SnV[old], SnV[new]]]
ELSE {
realOld: SteppyName ~ LSn[EvalSteps[old.steps]];
realNew: SteppyName ~ LSn[EvalSteps[new.steps]];
rns.AddNewPair[[SnV[realOld], SnV[realNew]]];
};
RETURN};
EvalSteps: PROC [exp: NameStepList] RETURNS [NameStepList] ~ {
rest: NameStepList ~ IF exp.rest#NIL THEN EvalSteps[exp.rest] ELSE NIL;
expr: ROPEWITH exp.first SELECT FROM
x: ROPE => x,
x: REF INT => NIL,
ENDCASE => ERROR;
dot: INT;
result: AMTypes.TV;
errorRope: ROPE;
noResult: BOOL;
IF expr=NIL THEN RETURN [CONS[exp.first, rest]];
FOR ldl: LoopDataList ← lds, ldl.rest WHILE ldl#NIL DO
IF expr.Find[ldl.first.index]>=0 THEN EXIT;
REPEAT FINISHED => RETURN [CONS[exp.first, rest]];
ENDLOOP;
WHILE (dot ← expr.Find[".ORD"])>0 DO
name: ROPE ~ expr.Substr[start: dot-1, len: 1];
sd: StringData ~ NARROW[i2d.ApplyA[name].MA];
expr ← expr.Replace[start: dot-1, len: 5, with: Convert.RopeFromInt[sd.i]];
ENDLOOP;
[result, errorRope, noResult] ← Interpreter.Evaluate[rope: expr, symbolsList: symbolsList];
IF noResult OR errorRope.Length#0 THEN ERROR;
SELECT AMTypes.TypeClass[AMTypes.TVType[result]] FROM
rope => {res: ROPE ~ AMTypes.TVToName[result];
RETURN [CONS[res, rest]]};
longInteger => {AMTypes.Assign[tvRes, result];
RETURN [CONS[NewInt[refRes^], rest]]};
ENDCASE => ERROR};
IF NOT assoc.Equal[":"] THEN ERROR;
WHILE (sep ← in.GetTokenRope[RenBrk].token).Equal["for"] DO
varName: ROPE ~ in.GetTokenRope[OpenBrk].token;
eq: ROPE ~ in.GetTokenRope[OpenBrk].token;
open: ROPE ~ in.GetTokenRope[OpenBrk].token;
ld: LoopData ← NIL;
IF NOT eq.Equal["="] THEN ERROR;
IF open.Equal["{"] THEN {
sd: StringData ~ NEW [LoopDataPrivate[string] ← [varName, NIL, string[CreateSeq[oneToOne: TRUE, dense: TRUE, rightSpace: SetBasics.ropes[TRUE]] ]]];
TRUSTED {sd.tv ← AMBridge.TVForReferent[sd.rr]};
DO
close: ROPE ← in.GetTokenRope[RenBrk].token;
sd.vals.AppendA[close];
IF (close ← in.GetTokenRope[RenBrk].token).Equal[","] THEN NULL
ELSE IF close.Equal["}"] THEN EXIT
ELSE ERROR;
ENDLOOP;
ld ← sd}
ELSE IF open.Equal["["] THEN {
first: INT ~ in.GetInt[];
rr: ROPE ~ in.GetTokenRope[RenBrk].token;
last: INT ~ in.GetInt[];
close: ROPE ~ in.GetTokenRope[RenBrk].token;
nd: NumData ~ NEW [LoopDataPrivate[number] ← [varName, NIL, number[first, last]]];
TRUSTED {nd.tv ← AMBridge.TVForReferent[nd.ri]};
IF NOT (rr.Equal[".."] AND close.Equal["]"]) THEN ERROR;
ld ← nd;
}
ELSE ERROR;
lds ← CONS[ld, lds];
i2d.AddNewAA[varName, ld];
IF NOT tab.Store[varName, ld.tv] THEN ERROR;
ENDLOOP;
DoLoop[lds, TRUE];
IF lds#NIL THEN {
tab.Erase[];
i2d.Erase[]};
renamesCount ← renamesCount+1;
IF sep.Equal["}"] THEN EXIT;
IF NOT sep.Equal[","] THEN ERROR;
ENDLOOP;
IF ct#NIL THEN renames.AddNewAA[ct, rns.Refify];
ENDLOOP;
in.Close[];
RETURN};
END.