CDSimpleRulesImpl.mesa (part of ChipNDale)
Copyright © 1985 by Xerox Corporation. All rights reserved.
by Christian Jacobi, July 5, 1985 4:58:37 pm PDT
Last Edited by Christian Jacobi, July 5, 1985 6:24:36 pm PDT
DIRECTORY
Atom, CD, CDExtras, CDRects, CDSimpleRules, CDValue, Rope, SymTab;
CDSimpleRulesImpl: CEDAR PROGRAM    
IMPORTS Atom, CD, CDExtras, CDRects, CDValue, SymTab
EXPORTS CDSimpleRules =
BEGIN
TechRec: TYPE = RECORD [
minWidth: PROC [layer: CD.Layer] RETURNS [CD.Number],
minDist: PROC [l1, l2: CD.Layer] RETURNS [CD.Number],
contact: PROC [l1, l2: CD.Layer] RETURNS [CD.Object],
layerTable: SymTab.Ref
];
NotKnown: PUBLIC ERROR = CODE;
techNames: SymTab.Ref ← SymTab.Create[case: FALSE];
LToTech: PROC [layer: CD.Layer] RETURNS [tech: CD.Technology] =
BEGIN
tech ← CD.LayerTechnology[layer ! CD.Error => GOTO bad];
IF tech=NIL THEN ERROR NotKnown;
EXITS bad => ERROR NotKnown;
END;
TToRep: PROC [tech: CD.Technology] RETURNS [REF TechRec] =
BEGIN
WITH CDValue.Fetch[boundTo: tech, key: techNames, propagation: technology] SELECT FROM
tr: REF TechRec => RETURN [tr];
ENDCASE => ERROR NotKnown;
END;
MinWidth: PUBLIC PROC [layer: CD.Layer] RETURNS [CD.Number] =
BEGIN
RETURN [ TToRep[LToTech[layer]].minWidth[layer] ]
END;
MinDist: PUBLIC PROC [l1, l2: CD.Layer] RETURNS [CD.Number] =
BEGIN
tech: CD.Technology ← LToTech[l1];
IF tech#LToTech[l2] THEN ERROR;
RETURN [ TToRep[tech].minDist[l1, l2] ]
END;
GetTechnology: PROC [x: REF] RETURNS [tech: CD.Technology ← NIL] =
--errors if not found
BEGIN
AToTech: PROC [a: ATOM] =
BEGIN
tech ← CD.FetchTechnology[a ! CD.Error => GOTO bad];
EXITS bad => tech ← NIL;
END;
WITH x SELECT FROM
t: CD.Technology => tech ← t;
d: CD.Design => tech ← d.technology;
a: ATOM => AToTech[a];
ENDCASE => NULL;
IF tech=NIL THEN
WITH SymTab.Fetch[techNames, CDExtras.ToRope[x]].val SELECT FROM
t: CD.Technology => tech ← t;
ENDCASE => NULL;
IF tech=NIL THEN ERROR NotKnown
END;
GetLayer: PUBLIC PROC [technology, layer: REF] RETURNS [CD.Layer] =
BEGIN
AToLayer: PROC [a: ATOM] =
BEGIN
ok ← TRUE;
lay ← CD.FetchLayer[tech, a ! CD.Error => {ok ← FALSE; CONTINUE}];
IF lay=CD.highLightError THEN ok ← FALSE;
END;
lay: CD.Layer;
ok: BOOLTRUE;
x: REFNIL;
tech: CD.Technology ← GetTechnology[technology];
tr: REF TechRec;
WITH layer SELECT FROM
a: ATOM => {
AToLayer[a];
IF ok THEN RETURN [lay]
};
ri: REF INT => RETURN [ri^];
rl: REF CD.Layer => RETURN [rl^];
ENDCASE => NULL;
tr ← TToRep[tech];
IF tr.layerTable#NIL THEN
x ← SymTab.Fetch[tr.layerTable, CDExtras.ToRope[layer]].val;
IF x#NIL AND x#layer THEN RETURN [GetLayer[tech, x]];
ERROR NotKnown
END;
Rect: PUBLIC PROC [size: CD.Position, layer: CD.Layer] RETURNS [CD.Object] =
BEGIN
RETURN [CDRects.CreateRect[size, layer]]
END;
Contact: PUBLIC PROC [l1, l2: CD.Layer] RETURNS [CD.Object] =
BEGIN
tech: CD.Technology ← LToTech[l1];
IF tech#LToTech[l2] THEN ERROR;
RETURN [ TToRep[tech].contact[l1, l2] ]
END;
ImplementTechnology: PUBLIC PROC [technology: CD.Technology,
minWidth: PROC [layer: CD.Layer] RETURNS [CD.Number],
minDist: PROC [l1, l2: CD.Layer] RETURNS [CD.Number],
contact: PROC [l1, l2: CD.Layer] RETURNS [CD.Object],
layerTable: SymTab.Ref←NIL,
technologyNames: LIST OF Rope.ROPENIL
] =
BEGIN
a: ATOM;
tr: REF TechRec ← NEW[TechRec ← [
minWidth: minWidth,
minDist: minDist,
contact: contact,
layerTable: layerTable
]];
IF technology=NIL THEN ERROR;
CDValue.Store[boundTo: technology, key: techNames, value: tr];
technologyNames ← CONS[
Atom.GetPName[technology.key],
CONS[technology.name, technologyNames]
];
FOR list: LIST OF Rope.ROPE ← technologyNames, list.rest WHILE list#NIL DO
[] ← SymTab.Insert[techNames, list.first, technology];
ENDLOOP;
FOR list: LIST OF CD.Layer ← technology.usedLayers, list.rest WHILE list#NIL DO
a ← CD.LayerKey[list.first];
[] ← SymTab.Insert[layerTable, Atom.GetPName[a], a];
ENDLOOP;
END;
END.