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