RegisterRuleSet:
PUBLIC
PROC [rules: Rules] = {
ruleValueTab: RefTab.Ref ← RefTab.Create[];
IF NOT RefTab.Store[x: ruleSets, key: rules.id, val: rules] THEN SIGNAL DesignRuleError["Not a unique rule set"];
FOR rvl: RuleValueList ← rules.values, rvl.rest
UNTIL rvl=
NIL
DO
IF NOT RefTab.Store[x: ruleValueTab, key: rvl.first.id, val: rvl.first.id] THEN SIGNAL DesignRuleError["Not a unique rule value id"];
[] ← CheckAndScale[rules, rvl.first];
ENDLOOP;
};
CopyRuleSet:
PUBLIC
PROC [rules: Rules]
RETURNS [newRules: Rules] = {
layerTable: RefTab.Ref ← RefTab.Create[];
ruleValueTable: RefTab.Ref ← RefTab.Create[];
newRules ← NEW[RulesRec ← rules^];
newRules.layers ← NIL;
newRules.holes ← NIL;
newRules.mosTransistors ← NIL;
newRules.values ← NIL;
FOR layerList: LayerList ← rules.layers, layerList.rest
UNTIL layerList=
NIL
DO
l: Layer ← NEW[LayerRec ← layerList.first^];
newRules.layers ← CONS[l, newRules.layers];
IF NOT RefTab.Store[x: layerTable, key: layerList.first, val: l] THEN ERROR;
ENDLOOP;
FOR ruleValueList: RuleValueList ← rules.values, ruleValueList.rest
UNTIL ruleValueList=
NIL
DO
v: RuleValue ← NEW[RuleValueRec ← ruleValueList.first^];
v.layer1 ← NARROW[RefTab.Fetch[x: layerTable, key: v.layer1].val];
v.layer2 ← NARROW[RefTab.Fetch[x: layerTable, key: v.layer2].val];
newRules.values ← CONS[v, newRules.values];
IF NOT RefTab.Store[x: ruleValueTable, key: ruleValueList.first, val: v] THEN ERROR;
ENDLOOP;
FOR layerList: LayerList ← newRules.layers, layerList.rest
UNTIL layerList=
NIL
DO
oill: ImplicitLayerList ← layerList.first.implicitLayers;
layerList.first.implicitLayers ← NIL;
FOR ill: ImplicitLayerList ← oill, ill.rest
UNTIL ill=
NIL
DO
il: ImplicitLayer ← NEW[ImplicitLayerRec];
il.layer ← NARROW[RefTab.Fetch[x: layerTable, key: ill.first.layer].val];
il.surround ← NARROW[RefTab.Fetch[x: ruleValueTable, key: ill.first.surround].val];
layerList.first.implicitLayers ← CONS[il, layerList.first.implicitLayers];
ENDLOOP;
ENDLOOP;
FOR holeList: HoleTypeList ← rules.holes, holeList.rest
UNTIL holeList=
NIL
DO
h: HoleType ← NEW[HoleTypeRec ← holeList.first^];
h.layer1 ← NARROW[RefTab.Fetch[x: layerTable, key: h.layer1].val];
h.layer2 ← NARROW[RefTab.Fetch[x: layerTable, key: h.layer2].val];
h.cutLayer ← NARROW[RefTab.Fetch[x: layerTable, key: h.cutLayer].val];
h.layer1Surround ← NARROW[RefTab.Fetch[x: ruleValueTable, key: h.layer1Surround].val];
h.layer2Surround ← NARROW[RefTab.Fetch[x: ruleValueTable, key: h.layer2Surround].val];
newRules.holes ← CONS[h, newRules.holes];
ENDLOOP;
FOR mosTranList: MOSTransistorTypeList ← rules.mosTransistors, mosTranList.rest
UNTIL mosTranList=
NIL
DO
t: MOSTransistorType ← NEW[MOSTransistorTypeRec ← mosTranList.first^];
t.gate ← NARROW[RefTab.Fetch[x: layerTable, key: t.gate].val];
t.sourceDrain ← NARROW[RefTab.Fetch[x: layerTable, key: t.sourceDrain].val];
t.bulk ← NARROW[RefTab.Fetch[x: layerTable, key: t.bulk].val];
t.gateExtension ← NARROW[RefTab.Fetch[x: ruleValueTable, key: t.gateExtension].val];
t.sourceDrainExtension ← NARROW[RefTab.Fetch[x: ruleValueTable, key: t.sourceDrainExtension].val];
t.bulkSurround ← NARROW[RefTab.Fetch[x: ruleValueTable, key: t.bulkSurround].val];
newRules.mosTransistors ← CONS[t, newRules.mosTransistors];
ENDLOOP;
};
FillInTemplate:
PUBLIC
PROC [rules: Rules, template: Rope.
ROPE, filled: Rope.
ROPE] = {
in: IO.STREAM ← FS.StreamOpen[template];
out: IO.STREAM ← FS.StreamOpen[filled, $create];
{
ENABLE
UNWIND => {
IO.Close[in];
IO.Close[out];
};
UNTIL
IO.EndOf[in]
DO
c: CHAR ← IO.GetChar[in];
IF c='$
THEN {
id: Rope.ROPE ← IO.GetID[in];
ruleValue: RuleValue ← FindRuleValue[rules, Atom.MakeAtom[id]];
IF ruleValue=NIL THEN ERROR DesignRuleError["Rule not found"];
IO.PutF[out, "%g", IF ruleValue.scale=1 THEN IO.int[ruleValue.value] ELSE IO.real[Real.Float[ruleValue.value] / Real.Float[ruleValue.scale]]];
}
ELSE IO.PutChar[out, c];
ENDLOOP;
IO.Close[in];
IO.Close[out];
};
};