<> <> <> <> <> DIRECTORY AMTypes USING [TV, TVEqual], AMBridge USING [SomeRefFromTV, TVForFrame, TVForReferent], AMModel USING [Context], AMModelBridge USING [ContextForFrame], CD, CDCells, CDDirectory, CDEvents, CDInstances, CDLayers, CDProperties, CDRects, CDSatellites, CDSymbolicObjects, CDTexts, Core, CoreClasses, CoreOps, CoreProperties, IO, Interpreter USING [Evaluate], List, PrincOpsUtils, PW, PWPins, Rope, RopeList, Sinix, Sisyph, SymTab, TerminalIO; SisyphImpl: CEDAR PROGRAM IMPORTS AMBridge, AMModelBridge, AMTypes, CDCells, CDDirectory, CDEvents, CDInstances, CDLayers, CDProperties, CDRects, CDSatellites, CDSymbolicObjects, CDTexts, CoreClasses, CoreOps, CoreProperties, Interpreter, IO, List, PrincOpsUtils, PW, PWPins, Rope, RopeList, Sinix, SymTab, TerminalIO EXPORTS Sisyph SHARES CDCells, CDRects, CDSymbolicObjects, CDTexts = BEGIN OPEN Sisyph; <> <, where obj is the object corresponding to the instance, and propList is the property list of the instance. An instance may have arguments that control the result of the extraction. These arguments may appear in any one of three places: (1) as "satellites" (or text objects) attatched to the instance, (2) as text inside the instance property $SisyphArguments, or (3) as text inside the object property $SisyphArguments.>> < pairs, while the interpreter context is the local frame of the caller of Eval. The evaluation always looks first at the Sisyph context and then at the interpreter context. Note that the interpreter context includes in it a definition of all variables that are visible (statically) from within Eval, and all global frames and interface records currently loaded in the Cedar world.>> <> <> <<(1) For each symbolic object (pin) inside IC there must be a wire in C.public one of whose full names is the same as the symbolic object's name.>> <<(2) C.public must satisfy the property P(w): the wire w has a symbolic object (pin) in IC whose name is the same as one of w's full names, or each of w's sons satisfies P.>> <> <<(1) For each symbolic object (pin) inside IW there must be a wire in W one of whose full names is the same as the symbolic object's name.>> <<(2) W must satisfy the property P(w): the wire w has a symbolic object (pin) in IC whose name is the same as one of w's full names, or each of w's sons satisfies P.>> <> expressionsProp: PUBLIC ATOM _ PW.RegisterProp[$SisyphExpressions, TRUE]; designRope: PUBLIC ROPE _ "design"; cellIconRope: PUBLIC ROPE _ "cI"; wireIconRope: PUBLIC ROPE _ "wI"; wireRope: PUBLIC ROPE _ "wire"; nameRope: PUBLIC ROPE _ "name"; globalNamesRope: PUBLIC ROPE _ "globalNames"; corePropsRope: PUBLIC ROPE _ "coreProps"; coreInstPropsRope: PUBLIC ROPE _ "coreInstProps"; cdObjRope: PUBLIC ROPE _ "cdObj"; iconicProp: PUBLIC ATOM _ PW.RegisterProp[$SisyphIcon, TRUE]; iconicCell: PUBLIC ATOM _ $SisyphIconicCell; iconicWire: PUBLIC ATOM _ $SisyphIconicWire; ignoreMeProp: PRIVATE ATOM _ PW.RegisterProp[$SisyphIgnoreMe, TRUE]; <> parmNamesProp: PUBLIC ATOM _ PW.RegisterProp[$SisyphParmNames, TRUE]; cacheProp: PUBLIC ATOM _ PW.RegisterProp[$SisyphCache, FALSE, TRUE]; cachePropsProp: ATOM _ PW.RegisterProp[$SisyphCacheProps, FALSE, TRUE]; defaultGlobalNames: PUBLIC LIST OF ROPE _ LIST["Vdd", "Gnd"]; sisyphMode: PUBLIC Sinix.Mode _ NEW [Sinix.ModeRec _ [ name: "Sisyph", extractProcProp: PW.RegisterProp[$SisyphExtractProc, TRUE, TRUE], pinsProp: CoreProperties.RegisterProperty[$SisyphPins, CoreProperties.Props[[CoreProperties.propPrint, CoreProperties.PropDontPrint]]], wireGeometryProp: CoreProperties.RegisterProperty[$SisyphWireGeometry, CoreProperties.Props[[CoreProperties.propCopy, CoreProperties.PropDoCopy], [CoreProperties.propPrint, CoreProperties.PropDontPrint]]], instanceProp: CoreProperties.RegisterProperty[$SisyphInstance, CoreProperties.Props[[CoreProperties.propCopy, CoreProperties.PropDoCopy], [CoreProperties.propPrint, CoreProperties.PropDontPrint]]], equalProc: ResultEqual, cacheProp: cacheProp, cachePropsProp: cachePropsProp ]]; <> ExtractSchematic: Sinix.ExtractProc = BEGIN inheritedContext: Context _ NARROW [userData]; cx: Context _ Copy[inheritedContext]; coreProps: Core.Properties; resultRope: ROPE; InitLocalVariables[cx, obj]; resultRope _ EvaluateParameters[cx, 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 => { cellType: CellType; name: ROPE _ GetName[cx]; globalWires: Wires _ GlobalWires[cx]; [result] _ Sinix.ExtractCell[obj, sisyphMode, properties, cx]; cellType _ NARROW [result]; ProcessGlobalWires[cellType, globalWires]; 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]; SortInstances[cellType, mode, obj]; }; END; ExtractWire: Sinix.ExtractProc = BEGIN wire: Wire; inheritedContext: Context _ NARROW [userData]; cx: Context _ Copy[inheritedContext]; name: ROPE; coreInstProps: Core.Properties; geometry: CD.Instance _ PWPins.NewInstance[obj]; IF obj.class#CDRects.bareRectClass THEN ERROR; IF obj.layer#CD.commentLayer THEN ERROR; InitLocalVariables[cx, obj]; EvaluateResult[cx, EvaluateParameters[cx, obj, properties]]; wire _ GetWireCore[cx]; name _ GetName[cx]; coreInstProps _ GetCoreInstProps[cx]; IF wire=NIL THEN wire _ CoreOps.CreateWire[name: name]; CDProperties.PutInstanceProp[geometry, Sinix.touchProcProp, NEW [Sinix.TouchProc _ TouchRect]]; Sinix.AddPinsProp[mode, wire, geometry]; IF coreInstProps#NIL THEN wire.properties _ PutCoreProps[wire.properties, coreInstProps]; result _ wire; END; <<>> <<>> ES, ExtractSchematicByName: PUBLIC PROC [name: ROPE, cx: Context] RETURNS [CellType] = { design: CD.Design _ GetDesign[cx]; RETURN [NARROW [Sinix.Extract[ obj: CDDirectory.Fetch[design, name].object, mode: sisyphMode, properties: NIL, userData: cx ].result]]; }; IsResultExpression: PUBLIC PROC [expr: ROPE] RETURNS [BOOL] = { RETURN [ Rope.Match["*cI*_*", expr] OR Rope.Match["*wI*_*", expr] OR Rope.Match["*wire*_*", expr] ] }; <> ExtractCellIcon: PROC [icon: Object, cx: Context] RETURNS [cellType: CellType] = BEGIN iconCT: CellType; name: ROPE; iconCT _ NARROW [Sinix.ExtractCell[icon, sisyphMode, 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 _ CoreClasses.CreateIdentity[cellType: cellType, name: name]; }; <<>> <> IF ~CheckAndDecorate[iconCT.public, cellType.public, iconCT.public, GlobalWires[cx]] THEN { TerminalIO.WriteF["\n** Error: drawn public and result public for cell icon %g don't conform\n", IO.rope[CDDirectory.Name[icon]]]; TerminalIO.WriteF["Drawn public is:"]; CoreOps.PrintWire[wire: iconCT.public, out: TerminalIO.TOS[], level: LAST [NAT]]; TerminalIO.WriteF["\n\nResult public is:"]; CoreOps.PrintWire[wire: cellType.public, out: TerminalIO.TOS[], level: LAST [NAT]]; ERROR } END; <> ExtractWireIcon: PROC [icon: Object, cx: Context] RETURNS [result: Wire] = BEGIN iconCT: CellType; iconWire: Wire; iconCT _ NARROW [Sinix.ExtractCell[icon, sisyphMode, NIL, cx].result]; iconWire _ iconCT.public[0]; result _ GetWireIconCore[cx]; IF result=NIL THEN ERROR; <<>> <> IF ~CheckAndDecorate[iconWire, result, iconWire] THEN { TerminalIO.WriteF["\n** Error: drawn wire and result wire for wire icon %g don't conform\n", IO.rope[CDDirectory.Name[icon]]]; TerminalIO.WriteF["Drawn wire is:"]; CoreOps.PrintWire[wire: iconWire, out: TerminalIO.TOS[], level: LAST [NAT]]; TerminalIO.WriteF["\n\nResult wire is:"]; CoreOps.PrintWire[wire: result, out: TerminalIO.TOS[], level: LAST [NAT]]; ERROR } END; <> InitLocalVariables: PUBLIC PROC [cx: Context, obj: CD.Object] = BEGIN 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 [CD.Object _ obj]] END; Create: PUBLIC PROC [design: CD.Design, globalNames: LIST OF ROPE _ defaultGlobalNames] RETURNS [cx: Context] = BEGIN cx _ SymTab.Create[]; Store[cx, designRope, NEW [CD.Design _ design]]; Store[cx, globalNamesRope, NEW [LIST OF ROPE _ globalNames]]; Store[cx, "&", NEW [INT _ 0]]; InitLocalVariables[cx, NIL]; END; Copy: PUBLIC PROC [cx: Context] RETURNS [newCx: Context] = BEGIN CopyItem: SymTab.EachPairAction = { [] _ SymTab.Store[newCx, key, val]; quit _ FALSE; }; IF cx=NIL THEN ERROR; newCx _ SymTab.Create[]; [] _ SymTab.Pairs[cx, CopyItem]; END; Store: PUBLIC PROC [cx: Context, var: ROPE, value: REF _ NIL] = BEGIN [] _ SymTab.Store[cx, var, TVFromRef[value]]; END; Eval: PUBLIC PROC [cx: Context, expr: ROPE, cedarCx: AMModel.Context _ NIL] = TRUSTED BEGIN 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 ERROR; END; ContextEqual: PROC [cx1, cx2: Context, parmNames: LIST OF ROPE] RETURNS [BOOL] = { <> IsASubset: PROC [a, b: Context] RETURNS [isASubset: BOOL] = { CheckExistenceInb: SymTab.EachPairAction = { found: BOOL; bVal: SymTab.Val; quit _ FALSE; <<>> <> IF Rope.Equal[key, "&"] OR Rope.Equal[key, cellIconRope] OR Rope.Equal[key, wireIconRope] OR Rope.Equal[key, wireRope] OR Rope.Equal[key, nameRope] OR Rope.Equal[key, corePropsRope] OR Rope.Equal[key, coreInstPropsRope] THEN RETURN; <> IF parmNames#NIL THEN { isAParm: BOOL _ FALSE; FOR l: LIST OF ROPE _ parmNames, l.rest WHILE l#NIL DO IF Rope.Equal[key, l.first] THEN isAParm _ TRUE; ENDLOOP; IF ~isAParm THEN RETURN; }; <> [found, bVal] _ SymTab.Fetch[b, key]; IF ~found THEN {isASubset _ FALSE; RETURN}; IF ~AMTypes.TVEqual[bVal, val] THEN isASubset _ FALSE; }; isASubset _ TRUE; [] _ SymTab.Pairs[a, CheckExistenceInb] }; IF IsASubset[cx1, cx2] AND IsASubset[cx2, cx1] THEN RETURN [TRUE] ELSE RETURN [FALSE] }; ResultEqual: PROC [obj: CD.Object, p1: CD.PropList, ud1: REF, p2: CD.PropList, ud2: REF] RETURNS [BOOL] = { cx1: Context _ NARROW [ud1]; cx2: Context _ NARROW [ud2]; instArgs1: LIST OF ROPE _ NARROW[CDProperties.GetListProp[p1, expressionsProp]]; satArgs1: LIST OF ROPE _ CDSatellites.GetSatelliteRopes[p1]; instArgs2: LIST OF ROPE _ NARROW[CDProperties.GetListProp[p2, expressionsProp]]; satArgs2: LIST OF ROPE _ CDSatellites.GetSatelliteRopes[p2]; parmNames: LIST OF ROPE _ NARROW[CDProperties.GetObjectProp[obj, parmNamesProp]]; <> IF parmNames#NIL AND Rope.Equal[parmNames.first, "0"] THEN RETURN [TRUE]; IF RopeList.EqualLists[instArgs1, instArgs2] AND RopeList.EqualLists[satArgs1, satArgs2] AND ContextEqual[cx1, cx2, parmNames] THEN RETURN [TRUE] ELSE RETURN [FALSE]; }; <> <> EvaluateParameters: PROC [cx: Context, obj: CD.Object, propList: CD.PropList] RETURNS [resultRope: ROPE] = { objExprs: LIST OF ROPE _ NARROW[CDProperties.GetObjectProp[obj, expressionsProp]]; objSats: LIST OF ROPE _ CDSatellites.GetSatelliteRopes[obj]; instExprs: LIST OF ROPE _ NARROW[CDProperties.GetListProp[propList, expressionsProp]]; instSats: LIST OF ROPE _ CDSatellites.GetSatelliteRopes[propList]; EvalExprs: PROC [exprs: LIST OF ROPE, 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 {TerminalIO.WriteRope["\n** Error: multiple result expressions encountered"]; 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 Store[cx, coreInstPropsRope, NEW [Core.Properties _ CoreProperties.PutProp[GetCoreInstProps[cx], CoreOps.nameProp, expr]]] ELSE Store[cx, nameRope, NEW [ROPE _ expr]] }; exprs _ exprs.rest; ENDLOOP; }; EvalExprs[objExprs, FALSE]; EvalExprs[objSats, FALSE]; EvalExprs[instExprs, TRUE]; EvalExprs[instSats, TRUE]; }; EvaluateResult: PROC [cx: Context, resultRope: ROPE] = { IF resultRope#NIL THEN { <> 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 [dp, rp, dpRoot: Wire, globalWires: Wires _ NIL] RETURNS [BOOL]= { dpInterfaceGeometry: LIST OF CD.Instance; WireToLORA: PROC [wire: Wire] RETURNS [lora: List.LORA] = { lora _ NIL; FOR i: NAT IN [0..wire.size) DO lora _ CONS [wire.elements[i], lora]; ENDLOOP; }; CompareWires: List.CompareProc = { w1: Wire _ NARROW [ref1]; w2: Wire _ NARROW [ref2]; RETURN [Rope.Compare[CoreOps.GetShortWireName[w1], CoreOps.GetShortWireName[w2]]] }; dpName: ROPE _ CoreOps.GetShortWireName[dp]; rpName: ROPE _ CoreOps.GetShortWireName[rp]; IF ~Rope.Equal[dpName, rpName] OR (dpName=NIL AND dp#dpRoot) THEN RETURN [FALSE]; IF dp.size > 0 THEN { dpElements: List.LORA _ List.Sort[WireToLORA[dp], CompareWires]; rpElements: List.LORA _ List.Sort[WireToLORA[rp], CompareWires]; IF rp.size> FOR i: NAT IN [0..dp.size) DO dpWire: Wire _ NARROW [dpElements.first]; rpWire: Wire _ NARROW [rpElements.first]; WHILE ~CheckAndDecorate[dpWire, rpWire, dpRoot] DO name: ROPE _ CoreOps.GetShortWireName[NARROW[rpElements.first, Wire]]; IF FindGlobalWire[name, globalWires]=NIL THEN RETURN [FALSE]; IF rpElements.rest=NIL THEN RETURN [FALSE] ELSE {rpElements _ rpElements.rest; rpWire _ NARROW [rpElements.first]} ENDLOOP; IF ~CheckAndDecorate[dpWire, rpWire, dpRoot] THEN RETURN [FALSE]; dpElements _ dpElements.rest; rpElements _ rpElements.rest ENDLOOP; }; dpInterfaceGeometry _ Sinix.GetPinsProp[sisyphMode, dp]; Sinix.PutPinsProp[sisyphMode, rp, dpInterfaceGeometry]; RETURN [TRUE]; }; 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, sisyphMode.extractProcProp, $ExtractNull]; CDProperties.PutProp[l.first, ignoreMeProp, NIL]}; ENDLOOP; } }; IF design=NIL THEN RETURN; -- design is sometimes NIL!! [] _ CDDirectory.Enumerate[design, MarkForEachCell]; }; <> ProcessGlobalWires: PROC [cellType: CellType, globalWires: Wires] = BEGIN recordCell: CoreClasses.RecordCellType _ NARROW [cellType.data]; toBeMadePublic: Wires _ NIL; toBeDeleted: Wires _ NIL; NewActual: PROC [rootPublic, instActual, instPublic: Wire] RETURNS [Wire] = BEGIN IF instActual.size#instPublic.size THEN ERROR; FOR i: NAT IN [0..instActual.size) DO instActual[i] _ NewActual[rootPublic, instActual[i], instPublic[i]]; ENDLOOP; FOR nl: LIST OF ROPE _ CoreOps.GetFullWireNames[rootPublic, instPublic], nl.rest WHILE nl#NIL DO globalWithInstPublicName: Wire _ FindGlobalWire[nl.first, globalWires]; IF globalWithInstPublicName#NIL AND Sinix.GetPinsProp[sisyphMode, instActual]=NIL THEN { publicWithInstPublicName: Wire _ CoreOps.FindWire[cellType.public, nl.first]; IF publicWithInstPublicName=NIL THEN { internalWithInstPublicName: Wire _ CoreOps.FindWire[recordCell.internal, nl.first]; IF internalWithInstPublicName#NIL THEN { IF ~CoreOps.Member[toBeMadePublic, internalWithInstPublicName] THEN toBeMadePublic _ CONS [internalWithInstPublicName, toBeMadePublic]; toBeDeleted _ CONS[instActual, toBeDeleted]; RETURN [internalWithInstPublicName] } ELSE { IF ~CoreOps.Member[toBeMadePublic, globalWithInstPublicName] THEN toBeMadePublic _ CONS [globalWithInstPublicName, toBeMadePublic]; recordCell.internal _ CoreOps.UnionWire[recordCell.internal, CoreOps.CreateWire[LIST [globalWithInstPublicName]]]; toBeDeleted _ CONS[instActual, toBeDeleted]; RETURN [globalWithInstPublicName] } } ELSE { toBeDeleted _ CONS[instActual, toBeDeleted]; RETURN [publicWithInstPublicName] } }; ENDLOOP; RETURN [instActual] END; CheckIfWireIsToBeMadePublic: CoreOps.EachWireProc = BEGIN FOR nl: LIST OF ROPE _ CoreOps.GetFullWireNames[recordCell.internal, wire], nl.rest WHILE nl#NIL DO IF FindGlobalWire[nl.first, globalWires]#NIL AND CoreOps.FindWire[cellType.public, nl.first]=NIL THEN {IF ~CoreOps.Member[toBeMadePublic, wire] THEN toBeMadePublic _ CONS [wire, toBeMadePublic]; RETURN} ENDLOOP; END; <> FOR i: NAT IN [0..recordCell.size) DO inst: CoreClasses.CellInstance _ recordCell.instances[i]; inst.actual _ NewActual[inst.type.public, inst.actual, inst.type.public]; ENDLOOP; <> recordCell.internal _ DeleteWires[recordCell.internal, toBeDeleted]; <> [] _ CoreOps.VisitWire[recordCell.internal, CheckIfWireIsToBeMadePublic]; <> FOR w: Wires _ toBeMadePublic, w.rest WHILE w#NIL DO Sinix.PutPinsProp[sisyphMode, w.first, NIL] ENDLOOP; cellType.public _ CoreOps.UnionWire[cellType.public, CoreOps.CreateWire[toBeMadePublic]]; END; SortInstances: PROC [cellType: Core.CellType, mode: Sinix.Mode, obj: CD.Object] = { layoutProp: ATOM _ NARROW [CoreProperties.GetCellTypeProp[cellType, $Layout]]; recordCell: CoreClasses.RecordCellType _ NARROW[cellType.data]; LessThan: PROC [i1, i2: CoreClasses.CellInstance] RETURNS [BOOL] = { cdi1: CD.Instance _ NARROW[CoreProperties.GetCellInstanceProp[i1, mode.instanceProp]]; cdi2: CD.Instance _ NARROW[CoreProperties.GetCellInstanceProp[i2, mode.instanceProp]]; ir1Loc: CD.Position _ PW.GetLocation[cdi1, obj]; ir2Loc: CD.Position _ PW.GetLocation[cdi2, obj]; RETURN [(layoutProp=$AbutX AND ir1Loc.x> FindGlobalWire: PROC [name: ROPE, globalWires: Wires] RETURNS [Wire _ NIL] = BEGIN FOR l: Wires _ globalWires, l.rest WHILE l#NIL DO IF Rope.Equal[name, CoreOps.GetShortWireName[l.first]] THEN RETURN [l.first]; ENDLOOP; END; GlobalWires: PROC [cx: Context] RETURNS [wires: Wires _ NIL] = BEGIN globalNames: LIST OF ROPE _ GetGlobalNames[cx]; FOR names: LIST OF ROPE _ globalNames, names.rest WHILE names#NIL DO wires _ CONS[CoreOps.CreateWire[name: names.first], wires]; ENDLOOP; END; <<>> TouchRect: Sinix.TouchProc = { IF instance2.ob.class#CDRects.bareRectClass THEN RETURN [Sinix.TouchRectObject[mode, instance2, CDInstances.InstRectO[instance1], instance1.ob.layer]]; 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 }; GetGlobalNames: PROC [cx: Context] RETURNS [LIST OF ROPE] = { found: BOOL; ref: SymTab.Val; [found, ref] _ SymTab.Fetch[cx, globalNamesRope]; IF found THEN RETURN [NARROW [RefFromTV[ref], REF LIST OF ROPE]^] ELSE ERROR }; GetDesign: 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 }; GetCDObj: PROC [cx: Context] RETURNS [CD.Object] = { found: BOOL; ref: SymTab.Val; [found, ref] _ SymTab.Fetch[cx, cdObjRope]; IF found THEN RETURN [NARROW [RefFromTV[ref], REF CD.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]]; }; <> Sinix.RegisterExtractProc[$SisyphExtractSchematic, ExtractSchematic]; Sinix.RegisterExtractProc[$SisyphExtractWire, ExtractWire]; CDProperties.PutProp[CDCells.cellClass, sisyphMode.extractProcProp, $SisyphExtractSchematic]; CDProperties.PutProp[CDCells.cellClass, Sinix.touchProcProp, NEW [Sinix.TouchProc _ Sinix.TouchCell]]; CDProperties.PutProp[CDSymbolicObjects.pinClass, sisyphMode.extractProcProp, $ExtractError]; CDProperties.PutProp[CDSymbolicObjects.segmentClass, sisyphMode.extractProcProp, $ExtractError]; CDProperties.PutProp[CDSymbolicObjects.markClass, sisyphMode.extractProcProp, $ExtractError]; CDProperties.PutProp[CDRects.bareRectClass, sisyphMode.extractProcProp, $SisyphExtractWire]; CDProperties.PutProp[CDTexts.textClass, sisyphMode.extractProcProp, $ExtractNull]; CDEvents.RegisterEventProc[$AfterInput, MarkInvisibleInstances]; END.