DIRECTORY Atom, CD, CDEnvironment, CDProperties, CDRects, CDSimpleRules, CDSimpleRulesBackdoor, CDValue, RefTab, Rope, SymTab; CDSimpleRulesImpl: CEDAR MONITOR IMPORTS Atom, CD, CDEnvironment, CDProperties, CDRects, CDValue, RefTab, Rope, SymTab EXPORTS CDSimpleRules, CDSimpleRulesBackdoor = BEGIN OPEN CDSimpleRulesBackdoor, CDSimpleRules; NotKnown: PUBLIC ERROR = CODE; techTables: REF TablePair _ NEW[TablePair_[names: SymTab.Create[mod: 3, case: FALSE], keys: RefTab.Create[3]]]; rulesTable: CD.PropRef _ CD.InitPropRef[]; TablePair: TYPE = RECORD [ names: SymTab.Ref, keys: RefTab.Ref ]; StoreInTablePair: PROC [table: REF TablePair, key: REF, data: REF] = { [] _ RefTab.Store[table.keys, key, data]; WITH key SELECT FROM r: Rope.ROPE => [] _ SymTab.Store[table.names, r, data]; rt: REF TEXT => [] _ SymTab.Store[table.names, Rope.FromRefText[rt], data]; a: ATOM => [] _ SymTab.Store[table.names, Atom.GetPName[a], data]; ENDCASE => NULL; }; FindInTablePair: PROC [table: REF TablePair, hint: REF] RETURNS [data: REF_NIL] = { tryAlso: Rope.ROPE _ NIL; IF table=NIL THEN RETURN; data _ RefTab.Fetch[table.keys, hint].val; IF data=NIL THEN { tryAlso: Rope.ROPE _ NIL; WITH hint SELECT FROM r: Rope.ROPE => tryAlso _ r; rt: REF TEXT => tryAlso _ Rope.FromRefText[rt]; ENDCASE => NULL; IF tryAlso#NIL THEN RETURN [SymTab.Fetch[table.names, tryAlso].val] }; }; GetRulesRep: PUBLIC PROC [rules: Rules] RETURNS [IRules] = { WITH rules SELECT FROM r: IRules => RETURN [r]; ENDCASE => NULL; WITH CDProperties.GetPRefProp[rulesTable, rules] SELECT FROM r: IRules => RETURN [r]; ENDCASE => NULL; WITH rules SELECT FROM a: ATOM => { CDEnvironment.ExecFileEntry[key: Atom.GetPName[a]]; WITH CDProperties.GetPRefProp[rulesTable, a] SELECT FROM r: IRules => RETURN [r]; ENDCASE => ERROR NotKnown; }; ENDCASE => ERROR NotKnown; }; InternalRules: PROC [rules: Rules, layer: CD.Layer] RETURNS [IRules] = { WITH rules SELECT FROM r: IRules => RETURN [r]; ENDCASE => NULL; IF rules=NIL THEN { tech: CD.Technology _ CD.LayerTechnology[layer]; IF tech=NIL THEN ERROR NotKnown; RETURN [GetRulesRep[tech]] }; WITH CDProperties.GetPRefProp[rulesTable, rules] SELECT FROM r: IRules => RETURN [r]; ENDCASE => NULL; WITH rules SELECT FROM a: ATOM => { CDEnvironment.ExecFileEntry[key: Atom.GetPName[a]]; RETURN [GetRulesRep[a]]; }; ENDCASE => ERROR NotKnown; }; MinWidth: PUBLIC PROC [rules: Rules, layer: CD.Layer] RETURNS [CD.Number] = { r: IRules ~ InternalRules[rules, layer]; RETURN [ IF r.minWidth=NIL THEN 0 ELSE r.minWidth[r, layer] ] }; MaxWidth: PUBLIC PROC [rules: Rules, layer: CD.Layer] RETURNS [CD.Number] = { r: IRules ~ InternalRules[rules, layer]; RETURN [ IF r.maxWidth=NIL THEN 0 ELSE r.maxWidth[r, layer] ] }; MinSpace: PUBLIC PROC [rules: Rules, l1, l2: CD.Layer] RETURNS [CD.Number] = { r: IRules ~ InternalRules[rules, l1]; RETURN [ IF r.minSpace=NIL THEN 0 ELSE r.minSpace[r, l1, l2] ] }; GetValue: PUBLIC PROC [rules: Rules, id: ATOM] RETURNS [v: CD.Number] = { r: IRules ~ InternalRules[rules, CD.errorLayer]; IF r.getValue=NIL THEN ERROR NotKnown; RETURN [ r.getValue[rules, id] ]; }; GetRuleDescription: PUBLIC PROC [rules: Rules, id: ATOM] RETURNS [r: Rope.ROPE_NIL] = { rul: IRules ~ InternalRules[rules, CD.errorLayer]; IF rul.getRuleDescription#NIL THEN r _ rul.getRuleDescription[rules, id]; }; GetLayer: PUBLIC PROC [technology, layer: REF] RETURNS [l: CD.Layer_CD.errorLayer] = { tech: CD.Technology _ GetTechnology[technology]; IF tech=NIL AND technology#NIL THEN ERROR NotKnown; WITH layer SELECT FROM a: ATOM => { l _ CD.FetchLayer[tech, a]; IF l#CD.errorLayer OR a=$errorLayer THEN RETURN [l]; }; rl: REF CD.Layer => RETURN [rl^]; ri: REF INT => RETURN [ri^]; ENDCASE => NULL; WITH FindInTablePair[GetLayerReg[tech], layer] SELECT FROM a: ATOM => RETURN [CD.FetchLayer[tech, a]]; ENDCASE => ERROR NotKnown; }; GetLayerReg: PROC [tech: CD.Technology] RETURNS [REF TablePair] = { WITH CDValue.Fetch[tech, techTables] SELECT FROM tp: REF TablePair => RETURN [tp]; ENDCASE => [] _ CDValue.StoreConditional[tech, techTables, NEW[TablePair_[names: SymTab.Create[mod: 7, case: FALSE], keys: RefTab.Create[7]]]]; RETURN [GetLayerReg[tech]]; }; Rect: PUBLIC PROC [size: CD.Position, layer: CD.Layer] RETURNS [CD.Object] = { RETURN [CDRects.CreateRect[size, layer]] }; Contact: PUBLIC PROC [rules: Rules, l1, l2: CD.Layer] RETURNS [CD.Object] = { r: IRules ~ InternalRules[rules, l1]; RETURN [ IF r.contact=NIL THEN NIL ELSE r.contact[r, l1, l2] ] }; LargeContact: PUBLIC PROC [rules: Rules, design: CD.Design, size: CD.Position, l1, l2: CD.Layer] RETURNS [CD.Object] = { r: IRules ~ InternalRules[rules, l1]; IF design#NIL AND design.technology#r.technology THEN ERROR; RETURN [ IF r.largeContact=NIL THEN NIL ELSE r.largeContact[r, design, size, l1, l2] ] }; GetTechnology: PUBLIC PROC [hint: REF] RETURNS [t: CD.Technology_NIL] = { WITH hint SELECT FROM tech: CD.Technology => RETURN [tech]; r: IRules => RETURN [r.technology]; ENDCASE => NULL; t _ CDEnvironment.GetTechnology[hint]; IF t=NIL THEN { WITH FindInTablePair[techTables, hint] SELECT FROM t: CD.Technology => RETURN [t]; ENDCASE => NULL; WITH CDProperties.GetPRefProp[rulesTable, hint] SELECT FROM r: IRules => RETURN [r.technology]; ENDCASE => NULL; WITH hint SELECT FROM a: ATOM => { CDEnvironment.ExecFileEntry[key: Atom.GetPName[a]]; WITH CDProperties.GetPRefProp[rulesTable, hint] SELECT FROM r: IRules => RETURN [r.technology]; ENDCASE => NULL; }; ENDCASE => NULL; }; }; GetRulesKey: PUBLIC PROC [rules: Rules] RETURNS [ATOM_NIL] = { r: IRules ~ InternalRules[rules, 0]; RETURN [r.key] }; GetRulesProp: PUBLIC PROC [rules: Rules, key: REF] RETURNS [x: REF] = { r: IRules _ InternalRules[rules, 0]; x _ CDProperties.GetPRefProp[r.properties, key]; WHILE x=NIL AND r.inherit#NIL DO r _ InternalRules[r.inherit, 0]; x _ CDProperties.GetPRefProp[r.properties, key]; ENDLOOP; }; RegisterRules: PUBLIC PROC [r: RulesRep] = { rule: IRules _ WITH CDProperties.GetPRefProp[rulesTable, IF r.key#NIL THEN r.key ELSE r.technology] SELECT FROM r: IRules => r, ENDCASE => NEW[RulesRep_r]; IF r.technology#NIL THEN { IF rule.technology#NIL AND rule.technology#r.technology THEN RETURN WITH ERROR CD.Error[calling, "tech missmatch"]; rule.technology _ r.technology; }; IF r.minWidth#NIL THEN rule.minWidth _ r.minWidth; IF r.minSpace#NIL THEN rule.minSpace _ r.minSpace; IF r.maxWidth#NIL THEN rule.minSpace _ r.minSpace; IF r.getValue#NIL THEN rule.getValue _ r.getValue; IF r.getRuleDescription#NIL THEN rule.getRuleDescription _ r.getRuleDescription; IF r.contact#NIL THEN rule.contact _ r.contact; IF r.largeContact#NIL THEN rule.largeContact _ r.largeContact; IF r.data#NIL THEN rule.data _ r.data; WITH CDProperties.GetPRefProp[rulesTable, r.inherit] SELECT FROM in: IRules => { IF rule.technology=NIL THEN rule.technology _ in.technology; IF rule.minWidth=NIL THEN rule.minWidth _ in.minWidth; IF rule.minSpace=NIL THEN rule.minSpace _ in.minSpace; IF rule.maxWidth=NIL THEN rule.maxWidth _ in.maxWidth; IF rule.getValue=NIL THEN rule.getValue _ in.getValue; IF rule.getRuleDescription=NIL THEN rule.getRuleDescription _ in.getRuleDescription; IF rule.contact=NIL THEN rule.contact _ in.contact; IF rule.largeContact=NIL THEN rule.largeContact _ in.largeContact; }; ENDCASE => NULL; IF rule.technology=NIL THEN ERROR CD.Error[calling, "NIL tech"]; IF rule.properties=NIL THEN rule.properties _ CD.InitPropRef[]; IF rule.key=NIL THEN { rule.key _ rule.technology.key; CDProperties.PutPRefProp[rulesTable, rule.technology, rule]; }; CDProperties.PutPRefProp[rulesTable, rule.key, rule]; }; RegisterLayerName: PUBLIC PROC [name: REF, layer: CD.Layer, technology: CD.Technology] = { t: CD.Technology _ CD.LayerTechnology[layer]; IF t#NIL THEN { IF technology#NIL AND technology#t THEN ERROR; technology _ t; }; StoreInTablePair[GetLayerReg[technology], name, CD.LayerKey[layer]] }; RegisterTechnologyName: PUBLIC PROC [name: REF, technology: CD.Technology] = { IF technology=NIL THEN ERROR; StoreInTablePair[techTables, name, technology]; }; FetchRules: PUBLIC PROC [design: CD.Design] RETURNS [rules: ATOM] = { x: REF _ CDProperties.GetProp[design, $DesignRules]; IF x=NIL THEN x _ design.technology; rules _ GetRulesKey[x]; }; [] _ CDProperties.RegisterProperty[$DesignRules, $chj]; END. ψCDSimpleRulesImpl.mesa (part of ChipNDale) Copyright c 1985, 1986, 1987 by Xerox Corporation. All rights reserved. Created by Christian Jacobi, July 5, 1985 4:58:37 pm PDT Last edited by: Christian Jacobi, April 20, 1987 7:06:20 pm PDT --actual assignments --inheritance --registrations --storing 2 refs is a small danger: --to prevent errors, either stored rules are not changed (but they will), or, the technology --registers rules with the NIL key first, before it ever uses technology.key Κ Α˜codešœ*™*Kšœ Οmœ=™HKšœ8™8K™?—K˜šΟk œ˜ Kšœžœl˜t—K˜šΟnœžœžœ˜$KšžœžœE˜UKšžœ'˜.—Kšž˜Kšžœ'˜+K™Kšœ žœžœžœ˜K˜šœ žœ ˜Kšžœ/žœ˜S—Kšœ žœ žœ˜*K˜šœ žœžœ˜Kšœ˜Kšœ˜Kšœ˜—K˜š Ÿœžœ žœžœžœ˜FKšœ)˜)šžœžœž˜Kšœžœ,˜8Kšœžœžœ?˜KKšœžœ;˜BKšžœžœ˜—K˜—K˜šŸœžœ žœžœžœžœžœ˜SKšœžœžœ˜Kšžœžœžœžœ˜Kšœ*˜*šžœžœžœ˜Kšœžœžœ˜šžœžœž˜Kšœžœ˜Kšœžœžœ#˜/Kšžœžœ˜—Kšžœ žœžœžœ)˜CK˜—K˜—K˜šŸ œžœžœžœ ˜<šžœžœžœ˜Kšœ žœ˜Kšžœžœ˜—šžœ-žœž˜Kšœ˜—K˜š Ÿœž œžœžœžœ ˜IKšœ!žœ ˜0Kšžœ žœžœžœ ˜&Kšžœ˜!K˜K™—š Ÿœž œžœžœ žœžœ˜WKšœ#žœ ˜2Kšžœžœžœ'˜IK˜—K˜šŸœžœžœžœžœžœžœ˜VKšœžœ(˜0Kš žœžœžœ žœžœžœ ˜3šžœžœž˜šœžœ˜ Kšœžœ˜Kš žœžœ žœžœžœ˜5Kšœ˜—Kšœžœžœ žœ˜!Kšœžœžœžœ˜Kšžœžœ˜—šžœ+žœž˜:Kšœžœžœžœ˜+Kšžœžœ ˜—Kšœ˜—K˜š Ÿ œžœžœ žœžœ˜Cšžœ!žœž˜0Kšœžœžœ˜!šžœ˜ Kšœ0žœ/žœ˜„——Jšžœ˜K˜—K˜šŸœžœžœžœžœžœžœ ˜NKšžœ"˜(Kšœ˜—K˜š Ÿœžœžœžœžœžœ ˜MKšœ%˜%Kš žœžœ žœžœžœžœ˜>Kšœ˜—K˜šŸ œžœžœžœžœžœžœžœ ˜xKšœ%˜%Kš žœžœžœ žœžœ˜Kšœ$˜$Jšžœ˜K˜—K˜š Ÿ œžœžœžœžœžœ˜GKšœ$˜$Jšœ0˜0š žœžœžœ žœž˜ Jšœ ˜ Jšœ0˜0Jšžœ˜—Kšœ˜—K˜šŸ œžœžœ˜,šœ˜š žœ&žœžœžœžœžœž˜`Kšœ˜Kšžœžœ ˜——KšΟc™šžœžœžœ˜šžœžœžœžœ˜=Kšžœžœžœžœ"˜6—Kšœ˜K˜—Kšžœ žœžœ˜2Kšžœ žœžœ˜2Kšžœ žœžœ˜2Kšžœ žœžœ˜2Kšžœžœžœ0˜PKšžœ žœžœ˜/Kšžœžœžœ$˜>Kšžœžœžœ˜&Kš  ™ šžœ1žœž˜@šœ˜Kšžœžœžœ!˜