DIRECTORY AMTypes USING [Copy, TV, TVEqual], AMBridge USING [SomeRefFromTV, TVForFrame, TVForReferent], AMModel USING [Context], AMModelBridge USING [ContextForFrame], CD, CDCells, CDDirectory, CDEvents, CDImports, CDInstances, CDLayers, CDProperties, CDRects, CDRemote, CDSatellites, CDSequencer, CDSymbolicObjects, CDTexts, Core, CoreClasses, CoreOps, CoreProperties, CoreGeometry, HashTable, IO, Interpreter USING [Evaluate], PrincOpsUtils, PW, Rope, RopeList, Sinix, Sisyph, SymTab, TerminalIO; SisyphImpl: CEDAR PROGRAM IMPORTS AMBridge, AMModelBridge, AMTypes, CDCells, CDDirectory, CDEvents, CDImports, CDInstances, CDLayers, CDProperties, CDRects, CDRemote, CDSatellites, CDSequencer, CDTexts, CoreClasses, CoreOps, CoreProperties, CoreGeometry, HashTable, Interpreter, IO, PrincOpsUtils, PW, Rope, RopeList, Sinix, SymTab, TerminalIO EXPORTS Sisyph SHARES CDCells, CDImports, CDRects, CDRemote, CDTexts, Sinix = BEGIN OPEN Sisyph; expressionsProp: PUBLIC ATOM _ PW.RegisterProp[$SisyphExpressions, TRUE]; designRope: PRIVATE ROPE _ "design"; cellIconRope: PUBLIC ROPE _ "cI"; wireIconRope: PUBLIC ROPE _ "wI"; wireRope: PUBLIC ROPE _ "wire"; nameRope: PUBLIC ROPE _ "name"; globalNamesRope: PRIVATE ROPE _ "globalNames"; corePropsRope: PUBLIC ROPE _ "coreProps"; coreInstPropsRope: PUBLIC ROPE _ "coreInstProps"; cdObjRope: PRIVATE ROPE _ "cdObj"; localVariablesRopes: ROPES = LIST ["&", cellIconRope, wireIconRope, nameRope, wireRope, corePropsRope, coreInstPropsRope]; ignoreMeProp: PRIVATE ATOM _ PW.RegisterProp[$SisyphIgnoreMe, TRUE]; parmNamesProp: PUBLIC ATOM _ PW.RegisterProp[$SisyphParmNames, TRUE]; defaultGlobalNames: PUBLIC ROPES _ LIST ["Vdd", "Gnd"]; mode: PUBLIC Sinix.Mode _ NEW [Sinix.ModeRec _ [ extractProcProp: PW.RegisterProp[$SisyphExtractProc, TRUE], decoration: CoreGeometry.CreateDecoration["Sisyph"], equalProc: ResultEqual, instanceLayer: Sinix.DefaultInstanceLayer, userData: DefaultUserData, fusionByName: schematics, touchProc: Touch ]]; ExtractSchematic: Sinix.ExtractProc = { cx: Context; coreProps: Core.Properties; resultRope: ROPE; [cx, resultRope] _ EvaluateParameters[userData, obj, properties]; EvaluateResult[cx, resultRope]; coreProps _ GetCoreProps[cx]; props _ GetCoreInstProps[cx]; SELECT TRUE FROM Rope.Match["*cI*_*", resultRope] => { cellType: CellType _ ExtractCellIcon[obj, cx]; IF coreProps#NIL THEN cellType.properties _ PutCoreProps[cellType.properties, coreProps]; result _ cellType; }; Rope.Match["*wI*_*", resultRope] => { wire: Wire _ ExtractWireIcon[obj, cx]; IF coreProps#NIL THEN wire.properties _ PutCoreProps[wire.properties, coreProps]; result _ wire; }; Rope.Match["*wire*_*", resultRope] => ERROR; ENDCASE => { name: ROPE _ GetName[cx]; cellType: CellType; [result, props] _ Sinix.ExtractCell[obj, mode, properties, cx]; cellType _ NARROW [result]; ProcessGlobalNames[cellType, cx]; IF name=NIL THEN name _ CDNameToCTName[CDDirectory.Name[obj], ".sch"]; cellType _ CoreOps.SetCellTypeName[cellType, name]; IF coreProps#NIL THEN cellType.properties _ PutCoreProps[cellType.properties, coreProps]; }; }; ExtractWire: Sinix.ExtractProc = { wire: Wire; cx: Context; name: ROPE; resultRope: ROPE; coreInstProps: Core.Properties; IF obj.class#CDRects.bareRectClass OR obj.layer#CD.commentLayer THEN ERROR; [cx, resultRope] _ EvaluateParameters[userData, obj, properties]; EvaluateResult[cx, resultRope]; wire _ GetWireCore[cx]; name _ GetName[cx]; coreInstProps _ GetCoreInstProps[cx]; IF wire=NIL THEN wire _ CoreOps.CreateWire[name: name]; CoreGeometry.PutPin[mode.decoration, wire, CDInstances.NewInst[obj]]; IF coreInstProps#NIL THEN wire.properties _ PutCoreProps[wire.properties, coreInstProps]; result _ wire; }; ExtractImport: Sinix.ExtractProc = { cx: Context = NARROW [userData]; design: CD.Design _ GetDesign[cx]; importPtr: CDImports.ImportPtr = NARROW [obj.specificRef]; importDesign: CD.Design; importObj: Object; CDSequencer.CheckAborted[design]; IF importPtr.boundInstance=NIL AND NOT CDImports.Load[design, importPtr.designName, true, false] THEN {PW.WriteF["*** Error: Cannot load import %g[%g] which is unbound.\n", IO.rope[importPtr.objectName], IO.rope[importPtr.designName]]; ERROR}; importDesign _ CDRemote.FetchDesign[design, importPtr.designName]; importObj _ importPtr.boundInstance.ob; RETURN Sinix.Extract[obj: importObj, mode: mode, properties: properties, userData: Create[importDesign, cx]]; }; ES, ExtractSchematicByName: PUBLIC PROC [name: ROPE, cx: Context] RETURNS [CellType] = { design: CD.Design = GetDesign[cx]; obj: CD.Object = CDDirectory.Fetch[design, name].object; IF obj=NIL THEN {PW.WriteF["*** Error: ES cannot find object '%g' in design '%g'.\n", IO.rope[name], IO.rope[design.name]]; ERROR}; RETURN [NARROW [Sinix.Extract[obj: obj, mode: mode, properties: NIL, userData: cx].result]]; }; ExtractCellIcon: PROC [icon: Object, cx: Context] RETURNS [cellType: CellType] = { SmashPins: CoreOps.EachWireProc = {CoreGeometry.PutPins[mode.decoration, wire, NIL]}; iconCT: CellType; name: ROPE; iconCT _ NARROW [Sinix.ExtractCell[icon, mode, NIL, cx].result]; cellType _ GetCellIconCore[cx]; name _ GetName[cx]; IF cellType=NIL THEN { IF name=NIL THEN name _ CDNameToCTName[CDDirectory.Name[icon], ".icon"]; cellType _ CoreOps.CreateCellType[class: CoreClasses.unspecifiedCellClass, public: iconCT.public, name: name]; } ELSE { IF name=NIL THEN name _ CoreOps.GetCellTypeName[cellType]; IF name=NIL THEN name _ CDNameToCTName[CDDirectory.Name[icon], ".icon"]; cellType _ CreateIcon[cellType: cellType, name: name]; }; [] _ CoreOps.VisitWireSeq[cellType.public, SmashPins]; CoreGeometry.PutIR[mode.decoration, cellType, CoreGeometry.GetIR[mode.decoration, iconCT]]; IF NOT CheckAndDecorate[icon, iconCT.public, cellType.public, GetGlobalNames[cx]] THEN { PW.WriteF["*** Error: icon public and schematic public for cell icon %g do NOT conform\n", IO.rope[CDDirectory.Name[icon]]]; PW.WriteF["Icon public is:"]; CoreOps.PrintWire[wire: iconCT.public, out: TerminalIO.TOS[], level: LAST [NAT]]; PW.WriteF["\nSchematic public is:"]; CoreOps.PrintWire[wire: cellType.public, out: TerminalIO.TOS[], level: LAST [NAT]]; PW.WriteF["\n"]; ERROR } }; ExtractWireIcon: PROC [icon: Object, cx: Context] RETURNS [result: Wire] = { iconCT: CellType _ NARROW [Sinix.ExtractCell[icon, mode, NIL, cx].result]; result _ GetWireIconCore[cx]; IF result=NIL THEN ERROR; IF iconCT.public.size=1 THEN { CoreGeometry.PutPins[mode.decoration, result, CoreGeometry.GetPins[mode.decoration, iconCT.public[0]]]; RETURN; }; IF ~CheckAndDecorate[icon, iconCT.public, CoreOps.CreateWire[LIST [result]]] THEN { PW.WriteF["*** Error: icon wire and result wire for wire icon %g don't conform\n", IO.rope[CDDirectory.Name[icon]]]; PW.WriteF["Icon wire is:"]; CoreOps.PrintWire[wire: iconCT.public, out: TerminalIO.TOS[], level: LAST [NAT]]; PW.WriteF["\nResult wire is:"]; CoreOps.PrintWire[wire: result, out: TerminalIO.TOS[], level: LAST [NAT]]; PW.WriteF["\n"]; ERROR } }; InitLocalVariables: PUBLIC PROC [cx: Context, obj: Object] = { IF cx=NIL THEN ERROR; Store[cx, cellIconRope, NEW [CellType _ NIL]]; Store[cx, wireIconRope, NEW [Wire _ NIL]]; Store[cx, wireRope, NEW [Wire _ NIL]]; Store[cx, nameRope, NEW [ROPE _ NIL]]; Store[cx, corePropsRope, NEW [Core.Properties _ NIL]]; Store[cx, coreInstPropsRope, NEW [Core.Properties _ NIL]]; Store[cx, cdObjRope, NEW [Object _ obj]] }; Create: PUBLIC PROC [design: CD.Design, previousCx: Context _ NIL] RETURNS [cx: Context] = { cx _ IF previousCx=NIL THEN SymTab.Create[] ELSE Copy[previousCx]; Store[cx, designRope, NEW [CD.Design _ design]]; Insert[cx, globalNamesRope, NEW [ROPES _ defaultGlobalNames]]; Store[cx, "&", NEW [INT _ 0]]; FOR exprs: ROPES _ NARROW [CDProperties.GetDesignProp[design, expressionsProp]], exprs.rest WHILE exprs#NIL DO Eval[cx, exprs.first]; ENDLOOP; FOR satellites: ROPES _ CDSatellites.GetSatelliteRopes[design], satellites.rest WHILE satellites#NIL DO Eval[cx, satellites.first]; ENDLOOP; InitLocalVariables[cx, NIL]; }; Copy: PUBLIC PROC [cx: Context] RETURNS [newCx: Context] = { CopyItem: SymTab.EachPairAction = { tv: AMTypes.TV _ NARROW[val]; [] _ SymTab.Store[newCx, key, AMTypes.Copy[tv]]; quit _ FALSE}; IF cx=NIL THEN ERROR; newCx _ SymTab.Create[]; [] _ SymTab.Pairs[cx, CopyItem]; }; Insert: PUBLIC PROC [cx: Context, var: ROPE, value: REF _ NIL] = { [] _ SymTab.Insert[cx, var, TVFromRef[value]]; }; Store: PUBLIC PROC [cx: Context, var: ROPE, value: REF _ NIL] = { [] _ SymTab.Store[cx, var, TVFromRef[value]]; }; Eval: PUBLIC PROC [cx: Context, expr: ROPE, cedarCx: AMModel.Context _ NIL] = TRUSTED { result: AMTypes.TV; errorRope: ROPE; noResult: BOOL; IF cedarCx=NIL THEN cedarCx _ AMModelBridge.ContextForFrame[ AMBridge.TVForFrame[ PrincOpsUtils.GetReturnFrame[] ] ]; [result, errorRope, noResult] _ Interpreter.Evaluate[rope: expr, context: cedarCx, symTab: cx]; IF errorRope=NIL THEN RETURN; SIGNAL InterpreterError[cx, expr, errorRope]; ERROR; }; ContextEqual: PROC [cx1, cx2: Context, parmNames: ROPES] RETURNS [BOOL] = { IsDifferent: PROC [a, b: Context] RETURNS [BOOL] = { CheckAbsentInb: SymTab.EachPairAction = { found: BOOL; bVal: SymTab.Val; IF RopeList.Memb[localVariablesRopes, key] THEN RETURN [FALSE]; IF parmNames#NIL AND NOT RopeList.Memb[parmNames, key] THEN RETURN [FALSE]; [found, bVal] _ SymTab.Fetch[b, key]; IF ~found THEN RETURN [TRUE]; IF AMTypes.TVEqual[bVal, val] THEN RETURN [FALSE]; IF Rope.Equal[key, globalNamesRope] THEN RETURN [NOT EqualRopes[NARROW [RefFromTV[bVal], REF ROPES]^, NARROW [RefFromTV[val], REF ROPES]^]]; RETURN [TRUE]; }; RETURN [SymTab.Pairs[a, CheckAbsentInb]]; }; RETURN [cx1=cx2 OR (NOT IsDifferent[cx1, cx2] AND NOT IsDifferent[cx2, cx1])] }; ResultEqual: PROC [obj: Object, p1: CD.PropList, ud1: REF, p2: CD.PropList, ud2: REF] RETURNS [BOOL] = { cx1: Context _ NARROW [ud1]; cx2: Context _ NARROW [ud2]; instArgs1: ROPES _ NARROW [CDProperties.GetListProp[p1, expressionsProp]]; satArgs1: ROPES _ NARROW [CDProperties.GetListProp[p1, Sinix.satellitesProp]]; instArgs2: ROPES _ NARROW [CDProperties.GetListProp[p2, expressionsProp]]; satArgs2: ROPES _ NARROW [CDProperties.GetListProp[p2, Sinix.satellitesProp]]; parmNames: ROPES _ NARROW [CDProperties.GetObjectProp[obj, parmNamesProp]]; IF parmNames#NIL AND Rope.Equal[parmNames.first, "0"] THEN RETURN [TRUE]; RETURN [EqualRopes[instArgs1, instArgs2] AND EqualRopes[satArgs1, satArgs2] AND ContextEqual[cx1, cx2, parmNames]]; }; iconClass: PUBLIC Core.CellClass _ CoreOps.SetClassPrintProc[NEW [Core.CellClassRec _ [name: "Icon", recast: RecastIcon, layersProps: TRUE]], PrintIcon]; CreateIcon: PUBLIC PROC [cellType: CellType, name: ROPE _ NIL, props: Core.Properties _ NIL] RETURNS [icon: CellType] = { icon _ CoreOps.CreateCellType[ class: iconClass, public: CoreOps.CopyWire[cellType.public], data: cellType, name: name, props: props]; }; RecastIcon: Core.RecastProc = {new _ NARROW [me.data]}; PrintIcon: CoreOps.PrintClassProc = { ct: CellType _ NARROW [data]; CoreOps.PrintIndent[indent, out]; out.PutF["Icon of `%g':\n", IO.rope[CoreOps.GetCellTypeName[ct]]]; CoreOps.PrintCellType[cellType: ct, out: out, indent: indent, level: level]; }; EqualRopes: PUBLIC PROC [ropes1, ropes2: ROPES] RETURNS [BOOL] = { FOR r1: ROPES _ ropes1, r1.rest WHILE r1#NIL DO IF NOT RopeList.Memb[ropes2, r1.first] THEN RETURN [FALSE]; ENDLOOP; FOR r2: ROPES _ ropes2, r2.rest WHILE r2#NIL DO IF NOT RopeList.Memb[ropes1, r2.first] THEN RETURN [FALSE]; ENDLOOP; RETURN [TRUE]; }; Cons: PUBLIC PROC [r: ROPE, lor: ROPES] RETURNS [ROPES] = { RETURN [CONS [r, lor]]; }; List: PUBLIC PROC [r1, r2, r3, r4, r5, r6: ROPE _ NIL] RETURNS [lor: ROPES _ NIL] = { IF r6#NIL THEN lor _ CONS [r6, lor]; IF r5#NIL THEN lor _ CONS [r5, lor]; IF r4#NIL THEN lor _ CONS [r4, lor]; IF r3#NIL THEN lor _ CONS [r3, lor]; IF r2#NIL THEN lor _ CONS [r2, lor]; IF r1#NIL THEN lor _ CONS [r1, lor]; }; EvaluateResult: PROC [cx: Context, resultRope: ROPE] = { IF resultRope=NIL THEN RETURN; IF Rope.Match["cI _ ES[\"*\", cx]", resultRope] THEN { pos1: INT _ Rope.Find[s1: resultRope, s2: "\""]; pos2: INT _ Rope.Find[s1: resultRope, s2: "\"", pos1: pos1+1]; name: ROPE _ Rope.Substr[resultRope, pos1+1, pos2-pos1-1]; Store[cx, cellIconRope, NEW [CellType _ ES[name, cx]]]; RETURN }; Eval[cx, resultRope]; }; CheckAndDecorate: PROC [icon: Object, drawnPublic, resultPublic: Wire, globalNames: ROPES _ NIL] RETURNS [ok: BOOL _ TRUE] = { iconName: ROPE = CDDirectory.Name[icon]; resultToDrawn: HashTable.Table _ HashTable.Create[]; -- associates resultPublic to drawnPublic FOR i: NAT IN [0 .. drawnPublic.size) DO EachResultWire: CoreOps.EachWireProc = { resultName: ROPE _ CoreOps.GetShortWireName[wire]; IF NOT Rope.Equal[resultName, drawnName] THEN RETURN; IF wire=resultWire THEN RETURN; IF resultWire#NIL THEN {PW.WriteF["*** Cell %g: Drawn Icon has a wire %g whose name appears more than once in the schematic\n", IO.rope[iconName], IO.rope[drawnName]]; quit _ TRUE; ok _ FALSE; RETURN}; resultWire _ wire; }; drawnWire: Wire _ drawnPublic[i]; drawnName: ROPE _ CoreOps.GetShortWireName[drawnWire]; resultWire: Wire _ NIL; IF drawnName=NIL THEN {PW.WriteF["*** Cell %g: Drawn Icon has an unnamed wire\n", IO.rope[iconName]]; ok _ FALSE; LOOP}; IF CoreOps.VisitWire[resultPublic, EachResultWire] THEN LOOP; IF resultWire=NIL THEN {PW.WriteF["*** Cell %g: Drawn Icon has wire %g that doesn't correspond to any wire in the schematic\n", IO.rope[iconName], IO.rope[drawnName]]; ok _ FALSE; LOOP}; CoreGeometry.PutPins[mode.decoration, resultWire, CoreGeometry.GetPins[mode.decoration, drawnWire]]; [] _ HashTable.Store[resultToDrawn, resultWire, drawnWire]; ENDLOOP; FOR i: NAT IN [0 .. resultPublic.size) DO resultWire: Wire _ resultPublic[i]; resultName: ROPE _ CoreOps.GetShortWireName[resultWire]; drawnWire: Wire _ NARROW [HashTable.Fetch[resultToDrawn, resultWire].value]; IF resultName=NIL THEN LOOP; IF drawnWire#NIL THEN LOOP; IF RopeList.Memb[globalNames, resultName] THEN LOOP; PW.WriteF["*** Warning in Cell %g: schematic has wire %g that corresponds to no wire in the drawn Icon\n", IO.rope[iconName], IO.rope[resultName]]; ENDLOOP; }; MarkInvisibleInstances: CDEvents.EventProc = { MarkForEachCell: CDDirectory.EachEntryAction = { IF CDCells.IsCell[ob] THEN { cellPtr: CD.CellPtr _ NARROW [ob.specificRef]; FOR l: LIST OF CD.Instance _ cellPtr.contents, l.rest WHILE l#NIL DO IF CDProperties.GetListProp[l.first.properties, ignoreMeProp]#NIL THEN {CDProperties.PutProp[l.first, mode.extractProcProp, $ExtractNull]; CDProperties.PutProp[l.first, ignoreMeProp, NIL]}; ENDLOOP; } }; IF design=NIL THEN RETURN; -- design is sometimes NIL!! [] _ CDDirectory.Enumerate[design, MarkForEachCell]; }; ProcessGlobalName: PROC [record: CellType, name: ROPE] = { globals: Wires; ReplaceSeq: PROC [old: WireSeq] RETURNS [new: WireSeq] = { new _ old; FOR i: NAT IN [0 .. old.size) DO new[i] _ Replace[old[i]] ENDLOOP; }; Replace: PROC [old: Wire] RETURNS [new: Wire] = { IF old.size#0 THEN RETURN [ReplaceSeq[old]]; RETURN [IF CoreOps.Member[globals, old] THEN global ELSE old]; }; ReplaceAndCleanSeq: PROC [old: WireSeq] RETURNS [new: WireSeq] = { news: Wires _ LIST [global]; FOR i: NAT IN [0 .. old.size) DO new _ Replace[old[i]]; IF NOT CoreOps.Member[news, new] THEN news _ CONS [new, news]; ENDLOOP; new _ CoreOps.CreateWire[news]; }; InsertGlobal: PROC [wire: Wire] = { IF wire.size#0 THEN SIGNAL GlobalNonAtomic[record, name, wire]; IF NOT CoreOps.Member[globals, wire] THEN globals _ CONS [wire, globals]; }; FindGlobals: CoreOps.EachWirePairProc = { actualName: ROPE = CoreOps.GetShortWireName[actualWire]; publicName: ROPE = CoreOps.GetShortWireName[publicWire]; IF NOT Rope.Equal[publicName, name] THEN RETURN; -- not a sub global candidate IF actualName=NIL OR Rope.Equal[actualName, name] THEN InsertGlobal[actualWire]; }; FindWire: CoreOps.EachWireProc = { IF Rope.Equal[CoreOps.GetShortWireName[wire], name] THEN InsertGlobal[wire]; }; rct: CoreClasses.RecordCellType = NARROW [record.data]; global: Wire; FOR i: NAT IN [0..rct.size) DO [] _ CoreOps.VisitBindingSeq[rct[i].actual, rct[i].type.public, FindGlobals]; ENDLOOP; [] _ CoreOps.VisitWireSeq[rct.internal, FindWire]; IF globals=NIL THEN RETURN; global _ CoreOps.SetShortWireName[globals.first, name]; globals _ globals.rest; record.public _ ReplaceAndCleanSeq[record.public]; rct.internal _ ReplaceAndCleanSeq[rct.internal]; FOR i: NAT IN [0..rct.size) DO rct[i].actual _ ReplaceSeq[rct[i].actual] ENDLOOP; WHILE globals#NIL DO Sinix.FuseProperties[mode, globals.first, global, CoreOps.GetCellTypeName[record]]; globals _ globals.rest; ENDLOOP; }; Touch: CoreGeometry.TouchProc = { IF instance1.ob.class#CDRects.bareRectClass OR instance2.ob.class#CDRects.bareRectClass THEN ERROR; -- the only thing we know is Rectangles! IF ~SilTouchRect[CDInstances.InstRectO[instance1], CDInstances.InstRectO[instance2]] THEN RETURN; RETURN [CDLayers.AbstractToPaint[instance1.ob.layer]=CDLayers.AbstractToPaint[instance2.ob.layer]]; }; SilTouchRect: PROC [r1, r2: CD.Rect] RETURNS [BOOL] = INLINE { Intersect: PROC [i1min, i1max, i2min, i2max: CD.Number] RETURNS [BOOL] = INLINE { RETURN [(i1max >= i2min) AND (i2max >= i1min)]; }; Adjoin: PROC [i1min, i1max, i2min, i2max: CD.Number] RETURNS [BOOL] = INLINE { RETURN [(i2min >= i1min AND i2min <= i1max AND i2max >= i1max) OR (i1min >= i2min AND i1min <= i2max AND i1max >= i2max)]; }; RETURN [(Intersect[r1.x1, r1.x2, r2.x1, r2.x2] AND Adjoin[r1.y1, r1.y2, r2.y1, r2.y2]) OR (Intersect[r1.y1, r1.y2, r2.y1, r2.y2] AND Adjoin[r1.x1, r1.x2, r2.x1, r2.x2])] }; GetCoreProps: PROC [cx: Context] RETURNS [Core.Properties] = { found: BOOL; ref: SymTab.Val; [found, ref] _ SymTab.Fetch[cx, corePropsRope]; IF found THEN RETURN [NARROW [RefFromTV[ref], REF Core.Properties]^] ELSE ERROR }; GetCoreInstProps: PROC [cx: Context] RETURNS [Core.Properties] = { found: BOOL; ref: SymTab.Val; [found, ref] _ SymTab.Fetch[cx, coreInstPropsRope]; IF found THEN RETURN [NARROW [RefFromTV[ref], REF Core.Properties]^] ELSE ERROR }; GetCellIconCore: PROC [cx: Context] RETURNS [Core.CellType] = { found: BOOL; ref: SymTab.Val; [found, ref] _ SymTab.Fetch[cx, cellIconRope]; IF found THEN RETURN [NARROW [RefFromTV[ref], REF Core.CellType]^] ELSE ERROR }; GetWireIconCore: PROC [cx: Context] RETURNS [Core.Wire] = { found: BOOL; ref: SymTab.Val; [found, ref] _ SymTab.Fetch[cx, wireIconRope]; IF found THEN RETURN [NARROW [RefFromTV[ref], REF Core.Wire]^] ELSE ERROR }; GetWireCore: PROC [cx: Context] RETURNS [Core.Wire] = { found: BOOL; ref: SymTab.Val; [found, ref] _ SymTab.Fetch[cx, wireRope]; IF found THEN RETURN [NARROW [RefFromTV[ref], REF Core.Wire]^] ELSE ERROR }; GetName: PROC [cx: Context] RETURNS [ROPE] = { found: BOOL; ref: SymTab.Val; [found, ref] _ SymTab.Fetch[cx, nameRope]; IF found THEN RETURN [NARROW [RefFromTV[ref], REF ROPE]^] ELSE ERROR }; GetDesign: PUBLIC PROC [cx: Context] RETURNS [CD.Design] = { found: BOOL; ref: SymTab.Val; [found, ref] _ SymTab.Fetch[cx, designRope]; IF found THEN RETURN [NARROW [RefFromTV[ref], REF CD.Design]^] ELSE ERROR }; GetGlobalNames: PUBLIC PROC [cx: Context] RETURNS [ROPES] = { found: BOOL; ref: SymTab.Val; [found, ref] _ SymTab.Fetch[cx, globalNamesRope]; IF found THEN RETURN [NARROW [RefFromTV[ref], REF ROPES]^] ELSE ERROR }; GetCDObj: PUBLIC PROC [cx: Context] RETURNS [Object] = { found: BOOL; ref: SymTab.Val; [found, ref] _ SymTab.Fetch[cx, cdObjRope]; IF found THEN RETURN [NARROW [RefFromTV[ref], REF Object]^] ELSE ERROR }; RefFromTV: PROC [tv: REF] RETURNS [REF] = { IF tv=NIL THEN RETURN [NIL]; IF ~ISTYPE [tv, AMTypes.TV] THEN ERROR; TRUSTED {RETURN [AMBridge.SomeRefFromTV[tv]]}; }; TVFromRef: PROC [ref: REF] RETURNS [AMTypes.TV] = TRUSTED { RETURN [AMBridge.TVForReferent[ref]]; }; PutCoreProps: PROC [onto, from: Core.Properties] RETURNS [new: Core.Properties] = { PutProp: PROC [prop: ATOM, val: REF ANY] = { new _ CoreProperties.PutProp[new, prop, val]; }; new _ onto; CoreProperties.Enumerate[from, PutProp]; }; CDNameToCTName: PROC [cdName, dropPart: ROPE] RETURNS [ctName: ROPE] = { ctName _ Rope.Substr[cdName, 0, Rope.Index[cdName, 0, dropPart]]; }; DefaultUserData: PROC [design: CD.Design] RETURNS [REF] ~ { RETURN [Create[design]]; }; GlobalNonAtomic: PUBLIC SIGNAL [record: CellType, name: ROPE, wire: Wire] = CODE; InterpreterError: PUBLIC SIGNAL [cx: Context, expr, errorRope: ROPE] = CODE; IsResultExpression: PUBLIC PROC [expr: ROPE] RETURNS [BOOL] = { RETURN [ Rope.Match["*cI*_*", expr] OR Rope.Match["*wI*_*", expr] OR Rope.Match["*wire*_*", expr] ] }; EvaluateParameters: PUBLIC PROC [userData: REF, obj: Object, properties: CD.PropList] RETURNS [cx: Context, resultRope: ROPE] = { EvalExprs: PROC [exprs: ROPES, inst: BOOL] = { seenResult: BOOL _ FALSE; WHILE exprs#NIL DO expr: ROPE _ exprs.first; SELECT TRUE FROM Rope.Find[s1: expr, s2: "_"] # -1 => { SELECT TRUE FROM IsResultExpression[expr] => { IF seenResult THEN {PW.WriteF["*** Error: multiple result expressions encountered\n"]; ERROR}; seenResult _ TRUE; resultRope _ expr; }; inst AND Rope.Match["*name*_*", expr] => { expr _ Rope.Replace[expr, Rope.Find[expr, "name"], 4, "&"]; Eval[cx, expr]; Store[cx, coreInstPropsRope, NEW [Core.Properties _ CoreProperties.PutProp[GetCoreInstProps[cx], CoreOps.nameProp, NARROW [RefFromTV[SymTab.Fetch[cx, "&"].val], REF ROPE]^]]]; }; ENDCASE => Eval[cx, expr] }; Rope.Find[s1: expr, s2: ":"] # -1 => { atomRope: ROPE _ Rope.Substr[expr, 0, Rope.Find[s1: expr, s2: ":"]]; valueRope: ROPE _ Rope.Substr[expr, 1+Rope.Find[s1: expr, s2: ":"]]; IF inst THEN expr _ Rope.Cat["coreInstProps _ CoreProperties.PutProp[coreInstProps, $", atomRope, ", ", valueRope, "]"] ELSE expr _ Rope.Cat["coreProps _ CoreProperties.PutProp[coreProps, $", atomRope, ", ", valueRope, "]"]; Eval[cx, expr] }; ENDCASE => { IF inst THEN { previousProps: Core.Properties _ GetCoreInstProps[cx]; previousName: ROPE _ NARROW [CoreProperties.GetProp[previousProps, CoreOps.nameProp]]; IF previousName#NIL AND NOT Rope.Equal[previousName, expr] THEN { PW.WriteF["*** Error in object '%g': Conflicting names '%g' and '%g' [probably two satellites].\n", IO.rope[CDDirectory.Name[obj]], IO.rope[previousName], IO.rope[expr]]; ERROR; }; Store[cx, coreInstPropsRope, NEW [Core.Properties _ CoreProperties.PutProp[previousProps, CoreOps.nameProp, expr]]]; } ELSE Store[cx, nameRope, NEW [ROPE _ expr]] }; exprs _ exprs.rest; ENDLOOP; }; cx _ Copy[NARROW [userData]]; CDSequencer.CheckAborted[GetDesign[cx]]; InitLocalVariables[cx, obj]; EvalExprs[NARROW [CDProperties.GetObjectProp[obj, expressionsProp]], FALSE]; EvalExprs[NARROW [CDProperties.GetObjectProp[obj, Sinix.satellitesProp]], FALSE]; EvalExprs[NARROW [CDProperties.GetListProp[properties, expressionsProp]], TRUE]; EvalExprs[NARROW [CDProperties.GetListProp[properties, Sinix.satellitesProp]], TRUE]; }; ProcessGlobalNames: PUBLIC PROC [record: CellType, cx: Context] = { FOR names: ROPES _ GetGlobalNames[cx], names.rest WHILE names#NIL DO ProcessGlobalName[record, names.first]; ENDLOOP; }; Sinix.RegisterExtractProc[$SisyphExtractSchematic, ExtractSchematic]; Sinix.RegisterExtractProc[$SisyphExtractWire, ExtractWire]; Sinix.RegisterExtractProc[$SisyphExtractImport, ExtractImport]; CDProperties.PutProp[CDCells.cellClass, mode.extractProcProp, $SisyphExtractSchematic]; CDProperties.PutProp[CDRects.bareRectClass, mode.extractProcProp, $SisyphExtractWire]; CDProperties.PutProp[CDTexts.textClass, mode.extractProcProp, $ExtractNull]; CDProperties.PutProp[CDImports.importsClass, mode.extractProcProp, $SisyphExtractImport]; CDEvents.RegisterEventProc[$AfterInput, MarkInvisibleInstances]; END. ΈSisyphImpl.mesa Copyright c 1985, 1986 by Xerox Corporation. All rights reserved. Created by Sindhu and Serlet, November 27, 1985 9:11:39 pm PDT Pradeep Sindhu January 13, 1987 9:37:32 am PST Barth, October 15, 1986 10:25:34 am PDT Bertrand Serlet, December 11, 1986 11:29:37 pm PST Jean-Marc Frailong June 20, 1986 8:10:12 pm PDT Christian Jacobi, July 15, 1986 6:24:40 pm PDT Constants and Variables name of Sisyph variable that holds the ChipNDale design. name of Sisyph variable that represents a list of names of global wires. name of Sisyph variable that holds the CD object being extracted. property whose presence indicates that the instance should be ignored during extraction. Present for backward compatibility only. Use $ExtractNull instead. We should get rid of it one day. ExtractProcs This is the top-level extract proc. It evaluates the arguments to the schematic and then calls either ExtractCellIcon or Sinix.ExtractCell to do its job. This proc is called for cell icons. If a core definition is found then it is returned, otherwise a core cell of class Unspecified is returned. Compute core for the schematic We smash the pins decoration that could sit on cellType Check public This proc is called for wire icons. If a core definition is found it is returned, otherwise an error is signalled. As for cell icons, pins provide the attatchment points to the wire. Check wire special case Context Handling Procedures Returns FALSE iff a is a subset of b If its a local variable then return right away If its not a parameter then return right away also It is a parameter. Check if its there in the context and equal Handle zero parameters as a special case Icon class Conveniences Utilities for the implementation SpeedUp Hack -- avoids evaluating expressions containing ExtractSchematicByName Construct the association by searching in resultPublic for every name found in drawnPublic We decorate the resultWire with the pins of drawnWire Ensure that each resultPublic corresponds to some iconic Wire (apart may be from the wires in globalNames). Warning only for those. All this code is there only to be backward compatible. To be deleted soon Exceptions Semi-public Utilities Module Initialization ΚΦ˜šœ™Jšœ Οmœ7™BIcodešœ;Οk™>Kšœ.™.Kšœ$ž™'Kšœ2™2Kšœ,ž™/Kšœ+ž™.J˜—šž ˜ Kšœžœžœ ˜"Kšœ žœ,˜:Kšœžœ ˜Kšœžœ˜&Kšžœ›˜K˜+K˜ Kšœ žœ˜Kšœ žœ ˜Kšœ˜Kšžœ˜K˜K˜ Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ —J˜šΟn œžœžœ˜Jšžœφžœžœ,˜ΎJšžœ˜Jšžœ9˜?Jšžœžœ ˜—head™š œžœžœžœ"žœ˜IK˜—šœ žœžœ ˜$K™8—Kšœžœžœ˜!Kšœžœžœ˜!Kšœ žœžœ ˜Kšœ žœžœ ˜šœžœžœ˜.K™H—Kšœžœžœ˜)Kšœžœžœ˜1šœ žœžœ ˜"Kšœ'žœ™AK˜—šœžœžœY˜zK˜—š œžœžœžœžœ˜DKšœΏ™Ώ—Kš œžœžœžœ žœ˜Ešœžœžœžœ˜7J˜—šœžœžœ˜0Jšœžœ"žœ˜;Jšœ4˜4J˜Jšœ*˜*Jšœ˜Jšœ˜Jšœ˜J˜——šœ ™ Jšœš™ššŸœ˜'Jšœ ˜ J˜Jšœ žœ˜JšœA˜AJšœ˜Jšœ˜J˜šžœžœž˜šœ%˜%Jšœ/˜/Jšžœ žœžœD˜YJšœ˜J˜—šœ%˜%Jšœ'˜'Jšžœ žœžœ<˜QJšœ˜J˜—Jšœ&žœ˜,šžœ˜ Jšœžœ˜Jšœ˜Jšœ?˜?Jšœ žœ ˜Jšœ!˜!Jšžœžœžœ6˜FJšœ3˜3Jšžœ žœžœD˜YJšœ˜——Jšœ˜J˜—šŸ œ˜"J˜ Jšœ ˜ Jšœžœ˜ Jšœ žœ˜J˜J˜Jš žœ!žœ žœžœžœ˜LJšœB˜BJšœ˜Jšœ˜Jšœ˜Jšœ%˜%Jšžœžœžœ'˜7JšœE˜EJšžœžœžœ@˜YJ˜Jšœ˜J™—šŸ œ˜$Kšœžœ ˜ Kšœžœ˜"Kšœ!žœ˜:Kšœžœ˜Kšœ˜Jšœ!˜!Kšžœžœžœžœ;žœžœDžœžœžœ˜σKšœB˜BKšœ'˜'Kšžœg˜mK˜K˜—š ΠbkœŸœžœžœžœžœ˜XKšœžœ˜"Kšœžœ1˜8KšžœžœžœžœCžœ žœžœ˜ƒKšžœžœ2žœ˜\Kšœ˜K˜—J™ŽšŸœžœžœ˜RJšŸ œFžœ˜UJšœ˜Jšœžœ˜ J˜Jšœ žœ žœ˜@J˜J™Jšœ˜J˜šžœ žœ˜šžœ˜Jšžœžœžœ8˜HJšœn˜nJšœ˜—šžœ˜Jšžœžœžœ*˜:Jšžœžœžœ8˜HJšœ6˜6J˜——Jšœ7™7Jšœ6˜6Jšœ[˜[J™ šžœžœLžœ˜XJšžœYžœ˜|Jšžœ˜Jšœ7žœ žœžœ˜QJšžœ"˜$Jšœ9žœ žœžœ˜SJšžœ˜Jšž˜J˜—Jšœ˜K˜—J™ΆšŸœžœžœ˜LJšœžœ žœ˜JJšœ˜Jšžœžœžœžœ˜J™J™ šžœžœ˜Jšœ ™ Kšœg˜gJšžœ˜J˜—šžœ;žœ žœ˜SJšžœQžœ˜tJšžœ˜Jšœ7žœ žœžœ˜QJšžœ˜Jšœ0žœ žœžœ˜JJšžœ˜Jšž˜J˜—Jšœ˜——™šŸœžœžœ˜>Kšžœžœžœžœ˜Kšœžœ žœ˜.Kšœžœ žœ˜*Kšœžœ žœ˜&Kšœžœžœžœ˜&Kšœžœžœ˜6Kšœžœžœ˜:Kšœžœ˜(Kšœ˜K˜—š Ÿœžœžœ žœžœžœ˜\Kš œžœ žœžœžœ˜BKšœžœžœ˜0Kšœžœžœ˜>Kšœžœžœ˜š žœžœžœCžœžœž˜nKšœ˜Kšžœ˜—š žœ žœ;žœ žœž˜gKšœ˜Kšžœ˜—Kšœžœ˜Kšœ˜K˜—šŸœžœžœžœ˜<šΠbnœ˜#Kšœ žœžœ˜Kšœ8žœ˜?—Kšžœžœžœžœ˜Kšœ˜Kšœ ˜ Kšœ˜K˜—š Ÿœžœžœžœ žœžœ˜BKšœ.˜.Kšœ˜—K˜š Ÿœžœžœžœ žœžœ˜AKšœ-˜-Kšœ˜—K˜š Ÿœžœžœžœžœžœ˜WKšœžœ˜Kšœ žœ˜Kšœ žœ˜K˜šžœ žœžœ)˜<šœ˜Kšœ˜Kšœ˜—Kšœ˜—Kšœ_˜_Kšžœ žœžœžœ˜Kšžœ'˜-Kšžœ˜Kšœ˜K˜—š Ÿ œžœ žœžœžœ˜KKšœžœ™$šŸ œžœžœžœ˜4šŸœ˜)Kšœžœ˜ K˜K™K™.Kšžœ)žœžœžœ˜?K™2Jšžœ žœžœžœžœžœžœ˜KK™>K˜%Jšžœžœžœžœ˜Kšžœžœžœžœ˜2Kšžœ"žœžœžœ žœžœžœžœžœžœ˜ŒJšžœžœ˜K˜—K˜Kšžœ#˜)Kšœ˜—K˜Kš žœ žœžœžœžœ˜Mšœ˜K˜——šŸ œžœžœžœžœžœžœžœ˜hKšœžœ˜Kšœžœ˜Kšœ žœžœ1˜JKšœ žœžœ6˜NKšœ žœžœ1˜JKšœ žœžœ6˜NKšœ žœžœ2˜KK˜K™(Kš žœ žœžœ"žœžœžœ˜IKšžœ#žœ žœ$˜sKšœ˜——™ šœ žœ,žœFžœ˜™K˜—šŸ œžœžœžœžœžœžœ˜yšœ˜Kšœ˜Kšœ*˜*Kšœ˜Kšœ ˜ Kšœ˜—Kšœ˜—K˜šŸ œžœ ˜7K˜—šŸ œ˜%Jšœžœ˜Kšœ!˜!Jšœžœ$˜BKšœL˜LJšœ˜——™ š Ÿ œžœžœžœžœžœ˜Bš žœžœžœžœž˜/Kš žœžœ!žœžœžœ˜;Kšžœ˜ —š žœžœžœžœž˜/Kš žœžœ!žœžœžœ˜;Kšžœ˜ —Kšžœžœ˜˜K˜——šŸœžœžœžœžœžœžœ˜;Kšžœžœ ˜Kšœ˜K˜—šŸœžœžœžœžœžœžœžœ˜UKšžœžœžœžœ ˜$Kšžœžœžœžœ ˜$Kšžœžœžœžœ ˜$Kšžœžœžœžœ ˜$Kšžœžœžœžœ ˜$Kšžœžœžœžœ ˜$J˜——™ šŸœžœžœ˜8Kšžœ žœžœžœ˜Kšœ ΟcB™Ošžœ-˜/šžœ˜Kšœžœ'˜0Kšœžœ5˜>Kšœžœ0˜:Kšœžœ žœ ˜7Kšž˜K˜——Kšœ˜K˜J˜—š‘œžœ>žœžœžœžœžœ˜~Kšœ žœ˜(Kšœ5’)˜^KšœZ™Zšžœžœžœž˜(šŸœ˜(Kšœ žœ"˜2Kšžœžœ#žœžœ˜5Kšžœžœžœ˜Kšžœ žœžœžœfžœžœžœžœžœ˜ΙKšœ˜K˜—Jšœ!˜!Kšœ žœ'˜6Kšœžœ˜Jšžœ žœžœžœ9žœžœžœ˜xKšžœ1žœžœ˜=Kšžœ žœžœžœfžœžœžœžœ˜ΊKšœ5™5Kšœd˜dKšœ;˜;Jšžœ˜—Kšœ„™„šžœžœžœž˜)Jšœ#˜#Kšœ žœ(˜8Kšœžœ4˜LJšžœ žœžœžœ˜Jšžœ žœžœžœ˜Jšžœ(žœžœ˜4Jšžœižœžœ˜”Jšžœ˜—K˜K˜—š‘œ˜.šŸœ!˜0šžœžœ˜Jšœ žœ žœ˜.JšœJ™Jš žœžœžœžœ%žœžœž˜Dšžœ<ž˜AJšžœqžœ˜{—Jšžœ˜—J˜—J˜—Jš žœžœžœžœ’˜7Jšœ4˜4Jšœ˜J˜—šŸœžœžœ˜:Jšœ˜šŸ œžœžœ˜:Jšœ ˜ Jš žœžœžœžœžœ˜BJ˜—šŸœžœ žœ˜1Jšžœ žœžœ˜,Jšžœžœžœžœ˜>J˜—šŸœžœžœ˜BJšœžœ ˜šžœžœžœž˜ Jšœ˜Jšžœžœžœžœ ˜>Jšžœ˜—Jšœ˜J˜—šŸ œžœ˜#Jšžœ žœžœ%˜?Jšžœžœžœ žœ˜IJ˜—šŸ œ˜)Jšœ žœ(˜8Jšœ žœ(˜8Jš žœžœžœžœ’˜NJšžœ žœžœžœ˜PJ˜—šŸœ˜"Jšžœ2žœ˜LJ˜—Jšœ"žœ˜7Jšœ ˜ šžœžœžœž˜JšœM˜MJšžœ˜—Jšœ2˜2Jšžœ žœžœžœ˜Jšœ7˜7Jšœ˜Jšœ2˜2Jšœ0˜0Jš žœžœžœžœ+žœ˜Qšžœ žœž˜JšœS˜SJ˜Jšžœ˜—J˜J˜—š‘œ˜!Jš žœ*žœ*žœžœ’(˜ŒJšžœSžœžœ˜aJšžœ]˜cJšœ˜J˜—š Ÿ œžœ žœžœžœžœ˜>š Ÿ œžœžœ žœžœžœ˜QJšžœžœ˜/J˜—š Ÿœžœžœ žœžœžœ˜Nšžœžœžœž˜AJšœžœžœ˜9—J˜—Jšžœ)žœ%žœ(žœ%˜©Jšœ˜K˜—šŸ œžœžœ˜>Kšœžœ˜ Kšœ˜Kšœ/˜/šžœ˜Kšžœžœžœžœ˜;Kšžœž˜ —K˜K˜—šŸœžœžœ˜BKšœžœ˜ Kšœ˜Kšœ3˜3šžœ˜Kšžœžœžœžœ˜;Kšžœž˜ —K˜K˜—šŸœžœžœ˜?Kšœžœ˜ Kšœ˜Kšœ.˜.šžœ˜Kšžœžœžœžœ˜9Kšžœž˜ —K˜K˜—šŸœžœžœ˜;Kšœžœ˜ Kšœ˜Kšœ.˜.šžœ˜Kšžœžœžœžœ ˜5Kšžœž˜ —K˜K˜—šŸ œžœžœ˜7Kšœžœ˜ Kšœ˜Kšœ*˜*šžœ˜Kšžœžœžœžœ ˜5Kšžœž˜ —K˜K˜—šŸœžœžœžœ˜.Kšœžœ˜ Kšœ˜Kšœ*˜*šžœ˜Kš žœžœžœžœžœ˜0Kšžœž˜ —K˜K˜—š Ÿ œžœžœžœžœ ˜