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, September 19, 1985 8:39:11 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: BOOL ← TRUE;
x: REF ← NIL;
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;
Implement
Technology:
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.ROPE ← NIL
] =
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.