<> <> <> <> <> <> <> <> DIRECTORY Atom, Basics, CD, CDBasics, CDCells, CDDirectory, CDInstances, CDOrient, CDProperties, CDRects, Commander, Core, CoreClasses, CoreGeometry, CoreIO, CoreOps, CoreProperties, CMosB, HashTable, IO, PW, PWObjects, PWC, PWPins, Rope, Sinix, SinixOps; PWCImpl: CEDAR PROGRAM IMPORTS Atom, Basics, CD, CDBasics, CDCells, CDDirectory, CDInstances, CDProperties, CDRects, CoreClasses, CoreGeometry, CoreIO, CoreOps, CoreProperties, HashTable, IO, PW, PWObjects, Rope, Sinix, SinixOps EXPORTS PWC SHARES CDCells, CDDirectory = BEGIN OPEN PWC; <<>> VisitAtomicPairs: PROC [wire1, wire2: Wire, eachPair: PROC [Wire, Wire]] = { VisitInternal: PROC [wire1, wire2: Wire] = { IF wire1.size#wire2.size THEN ERROR; IF wire1.size=0 THEN eachPair[wire1, wire2] ELSE FOR i: NAT IN [0 .. wire1.size) DO VisitInternal[wire1[i], wire2[i]] ENDLOOP}; IF wire1.size#wire2.size THEN ERROR; FOR i: NAT IN [0 .. wire1.size) DO VisitInternal[wire1[i], wire2[i]] ENDLOOP}; <<>> <> Error: PUBLIC ERROR [type: ATOM, message: ROPE, cellType: CellType] = CODE; GeometryCorrespondingToSeveralPublics: PUBLIC SIGNAL [cellType: CellType, obj: Object, publics: Wires, geometry: LIST OF CD.Instance] = CODE; NoGeometryOnAtomicPublics: PUBLIC SIGNAL [cellType: CellType, obj: Object, publics: Wires, message: ROPE _ NIL] = CODE; <<>> <> layoutAtomsTable: HashTable.Table _ HashTable.Create[]; LayoutAtomData: TYPE = REF LayoutAtomDataRec; LayoutAtomDataRec: TYPE = RECORD [layoutProc: LayoutProc, decorateProc: DecorateProc]; RegisterLayoutAtom: PUBLIC PROC [layoutAtom: ATOM, layoutProc: LayoutProc, decorateProc: DecorateProc] RETURNS [sameAtom: ATOM] = { sameAtom _ layoutAtom; IF ~HashTable.Store[layoutAtomsTable, layoutAtom, NEW [LayoutAtomDataRec _ [layoutProc: layoutProc, decorateProc: decorateProc]]] THEN PW.WriteF["LayoutProc and DecorateProc for %g overwritten\n", IO.atom[layoutAtom]]}; <<>> <> layoutAtomProp: PUBLIC ATOM _ CoreProperties.RegisterProperty[$Layout]; GetLayoutAtom: PUBLIC PROC [cellType: CellType] RETURNS [layoutAtom: ATOM _ NIL] = { layoutAtom _ NARROW [CoreProperties.GetCellTypeProp[cellType, layoutAtomProp]]; IF layoutAtom#NIL THEN RETURN; layoutAtom _ NARROW [CoreProperties.GetCellClassProp[cellType.class, layoutAtomProp]]}; <> layoutProp: PRIVATE ATOM _ CoreProperties.RegisterProperty[$PWCLayout]; FakeExtract: Sinix.ExtractProc = {result _ CDProperties.GetObjectProp[obj, $PWCCellType]}; SetExtractCell: PUBLIC PROC [obj: CD.Object, cellType: CellType] = { CDProperties.PutObjectProp[obj, $PWCCellType, cellType]; CDProperties.PutObjectProp[obj, extractMode.extractProcProp, $FakeExtract]}; SetLayoutObj: PUBLIC PROC [cellType: CellType, obj: CD.Object] = {CoreProperties.PutCellTypeProp[cellType, layoutProp, obj]}; <<{SetLayout[cellType, $ValueNoDecorate, $PWCValue, obj]};>> Layout: PUBLIC PROC [cellType: CellType] RETURNS [obj: Object] = { obj _ NARROW [CoreProperties.GetCellTypeProp[cellType, layoutProp]]; IF obj#NIL THEN RETURN; BEGIN CopyDecorations: PROC [wire1, wire2: Wire] = { SourcePinsFromExtracted[cellType, obj, wire2, wire1]}; publicsWithoutPin: Wires; layoutAtom: ATOM _ GetLayoutAtom[cellType]; layoutAtomData: LayoutAtomData; <<>> <> <> IF layoutAtom=NIL THEN Error[$NoLayoutAtom, "Impossible to find a layoutAtom for this cellType", cellType]; layoutAtomData _ NARROW [HashTable.Fetch[layoutAtomsTable, layoutAtom].value]; IF layoutAtomData=NIL THEN Error[$NoRegistration, IO.PutFR["LayoutAtom %g has not been registered", IO.atom[layoutAtom]], cellType]; obj _ layoutAtomData.layoutProc[cellType]; <<>> <> <> <<>> <> IF layoutAtomData.decorateProc#NIL THEN layoutAtomData.decorateProc[cellType, obj]; IF NOT CoreGeometry.HasIR[extractMode.decoration, cellType] THEN ERROR; <<>> <> publicsWithoutPin _ AtomicWithoutPin[cellType.public]; IF publicsWithoutPin#NIL THEN NoGeometryOnAtomicPublics[cellType, obj, publicsWithoutPin]; <<>> <> <> <> <> <<>> SetExtractCell[obj, cellType]; SetLayoutObj[cellType, obj]; IF CoreOps.GetCellTypeName[cellType]#NIL AND CDDirectory.Name[obj]=NIL THEN SetObjName[obj, CoreOps.GetCellTypeName[cellType]]; <<>> <> IF Sinix.Extract[obj, extractMode].result#cellType THEN Error[$InternalBug, "Internal invariant failed", cellType]; <> <> END }; SetObjName: PUBLIC PROC [obj: CD.Object, name: ROPE] = { NARROW[obj.class.directoryProcs, REF CDDirectory.DirectoryProcs].setName[obj, name]}; CountTransistors: PUBLIC PROC[cell: CellType] RETURNS[count: INT _ 0] = { refInt: REF INT; IF cell=NIL THEN RETURN[0]; refInt _ NARROW[CoreProperties.GetCellTypeProp[cell, transistorCount].value]; IF refInt#NIL THEN RETURN[refInt^]; SELECT cell.class FROM CoreClasses.sequenceCellClass => { data: CoreClasses.SequenceCellType _ NARROW[cell.data]; count _ data.count*CountTransistors[data.base]}; CoreClasses.recordCellClass => { data: CoreClasses.RecordCellType _ NARROW[cell.data]; FOR child: NAT IN [0..data.size) DO count _ count + CountTransistors[ data.instances[child].type ] ENDLOOP }; CoreClasses.transistorCellClass => RETURN[1]; rotatedCellClass => count _ CountTransistors[NARROW[cell.data]]; CoreIO.importCellClass => { PW.WriteF["\nSkipping Imported Transistors: %g\n", IO.rope[CoreOps.GetCellTypeName[cell] ] ]}; ENDCASE => IF ISTYPE[cell.data, CellType] THEN count _ CountTransistors[NARROW[cell.data]] ELSE PW.WriteF["\nSkipping transistor count: %g\n", IO.rope[CoreOps.GetCellTypeName[cell] ] ]; CoreProperties.PutCellTypeProp[cell, transistorCount, NEW[INT _ count]] }; transistorCount: PUBLIC ATOM _ CoreIO.RegisterProperty[ CoreProperties.RegisterProperty[ $TransistorCount, CoreProperties.Props[ [CoreProperties.propPrint, NEW[CoreProperties.PropPrintProc _ PrintTCnt ]] ] ], WriteTCnt, ReadTCnt ]; WriteTCnt: CoreIO.PropWriteProc = {CoreIO.WriteInt[h, NARROW[value, REF INT]^]}; ReadTCnt: CoreIO.PropReadProc = {RETURN[ NEW[INT _ CoreIO.ReadInt[h] ] ]}; PrintTCnt: CoreProperties.PropPrintProc = {to.PutF[" Transistor Count: %g", IO.int[NARROW[val, REF INT]^]]}; InterestRect: PUBLIC PROC [cellType: CellType] RETURNS [ir: CD.Rect] = { IF NOT CoreGeometry.HasIR[extractMode.decoration, cellType] THEN [] _ Layout[cellType]; ir _ CoreGeometry.GetIR[extractMode.decoration, cellType]}; <<>> InterestSize: PUBLIC PROC [cellType: CellType] RETURNS [size: CD.Position] = {RETURN[ CDBasics.SizeOfRect[ InterestRect[ cellType]]]}; <<>> Extract: PUBLIC PROC [obj: Object] RETURNS [cellType: CellType] = { cellType _ NARROW [Sinix.Extract[obj, extractMode].result]; SetLayoutObj[cellType, obj]}; <<>> <> extractMode: PUBLIC Sinix.Mode _ SinixOps.GetExtractMode[$cmosB]; <<>> <> AtomicWithoutPin: PROC [public: Wire] RETURNS [publicsWithoutPin: Wires _ NIL] = { CheckPinsNonNil: PROC [wire: Wire] = { IF CoreGeometry.GetPins[extractMode.decoration, wire]=NIL THEN publicsWithoutPin _ CONS [wire, publicsWithoutPin]}; FOR i: NAT IN [0 .. public.size) DO CoreOps.VisitRootAtomics[public[i], CheckPinsNonNil] ENDLOOP}; <> <> <> <> <> <<>> <> SourcePinsFromExtracted: PROC [cellType: CellType, obj: Object, source, extracted: Wire] = { IF NOT CoreGeometry.HasPins[extractMode.decoration, extracted] THEN NoGeometryOnAtomicPublics[cellType, obj, LIST [source]]; CoreGeometry.AddIndirectLazyPins[extractMode.decoration, source, extracted]}; <<>> <<$Get, $GetAndFlatten, $Value and $ValueNoDecorate>> maskSuffix: PUBLIC ROPE _ ".mask"; GetAndAddSuffix: PROC [source: CD.Design, name: ROPE] RETURNS [obj: Object] = { obj _ PW.Get[source, IO.PutR[IO.rope[name], IO.rope[maskSuffix]]]}; Get: LayoutProc = { source: CD.Design _ NARROW [CoreProperties.GetCellTypeProp[cellType, $PWCSourceDesign]]; obj _ GetAndAddSuffix[source, CoreOps.GetCellTypeName[cellType]]}; GetAndFlatten: LayoutProc = { source: CD.Design _ NARROW [CoreProperties.GetCellTypeProp[cellType, $PWCSourceDesign]]; obj _ PW.Flatten[GetAndAddSuffix[source, CoreOps.GetCellTypeName[cellType]]]}; Value: LayoutProc = { obj _ NARROW [CoreProperties.GetCellTypeProp[cellType, $PWCValue]]}; NoDecorate: DecorateProc = {}; DecorateValue: PUBLIC DecorateProc = { extractedCT: CellType _ NARROW [Sinix.Extract[obj, extractMode].result]; extractedToSource: HashTable.Table _ HashTable.Create[extractedCT.public.size]; FindInExtractedPublic: CoreOps.EachWireProc = { FOR names: LIST OF ROPE _ CoreOps.GetFullWireNames[cellType.public, wire], names.rest WHILE names#NIL DO name: ROPE _ names.first; extractedWire: Wire _ CoreOps.FindWire[extractedCT.public, name]; previousSourceWire: Wire _ NARROW [HashTable.Fetch[extractedToSource, extractedWire].value]; IF extractedWire=NIL OR extractedWire.size#0 THEN LOOP; IF previousSourceWire#NIL AND previousSourceWire#wire THEN GeometryCorrespondingToSeveralPublics[cellType, obj, LIST [previousSourceWire, wire], CoreGeometry.GetPins[extractMode.decoration, extractedWire]]; SourcePinsFromExtracted[cellType, obj, wire, extractedWire]; [] _ HashTable.Store[extractedToSource, extractedWire, wire]; ENDLOOP }; CoreGeometry.PutIR[extractMode.decoration, cellType, CD.InterestRect[obj]]; [] _ CoreOps.VisitWire[cellType.public, FindInExtractedPublic] }; <<>> <> AbutX: LayoutProc = { data: CoreClasses.RecordCellType _ NARROW [cellType.data]; subObjects: LIST OF Object _ NIL; FOR i: NAT DECREASING IN [0 .. data.size) DO subObjects _ CONS [Layout[data[i].type], subObjects]; ENDLOOP; obj _ PW.AbutListX[subObjects]}; AbutY: LayoutProc = { data: CoreClasses.RecordCellType _ NARROW [cellType.data]; subObjects: LIST OF Object _ NIL; FOR i: NAT DECREASING IN [0 .. data.size) DO subObjects _ CONS [Layout[data[i].type], subObjects]; ENDLOOP; obj _ PW.AbutListY[subObjects]}; ReverseAbutX: LayoutProc = { data: CoreClasses.RecordCellType _ NARROW [cellType.data]; subObjects: LIST OF Object _ NIL; FOR i: NAT IN [0 .. data.size) DO subObjects _ CONS [Layout[data[i].type], subObjects]; ENDLOOP; obj _ PW.AbutListX[subObjects]}; ReverseAbutY: LayoutProc = { data: CoreClasses.RecordCellType _ NARROW [cellType.data]; subObjects: LIST OF Object _ NIL; FOR i: NAT IN [0 .. data.size) DO subObjects _ CONS [Layout[data[i].type], subObjects]; ENDLOOP; obj _ PW.AbutListY[subObjects]}; ArrayX: LayoutProc = { recasted: CellType _ CoreOps.Recast[cellType]; SetLayout[recasted, $AbutX]; obj _ Layout[recasted]}; ArrayY: LayoutProc = { recasted: CellType _ CoreOps.Recast[cellType]; SetLayout[recasted, $AbutY]; obj _ Layout[recasted]}; ReverseArrayX: LayoutProc = { recasted: CellType _ CoreOps.Recast[cellType]; SetLayout[recasted, $ReverseAbutX]; obj _ Layout[recasted]}; ReverseArrayY: LayoutProc = { recasted: CellType _ CoreOps.Recast[cellType]; SetLayout[recasted, $ReverseAbutY]; obj _ Layout[recasted]}; Recast: LayoutProc = { obj _ PWObjects.CreateIndirect[Layout[CoreOps.Recast[cellType]]]}; DecorateAbut: PUBLIC PROC [cellType: CellType, obj: Object, sort: SortProc] = { InsertInOrder: PROC [element: CD.Instance, sorted: LIST OF CD.Instance] RETURNS [new: LIST OF CD.Instance] = { IF element.orientation#0 THEN Error[$CallerBug, "DecorateAbut is only applicable for CD Cells without rotations", cellType]; IF sorted=NIL THEN RETURN [LIST [element]]; IF sort[CDBasics.BaseOfRect[CDInstances.InstRectO[element]], CDBasics.BaseOfRect[CDInstances.InstRectO[sorted.first]]] THEN RETURN [CONS [element, sorted]]; RETURN [CONS [sorted.first, InsertInOrder[element, sorted.rest]]]}; SetLazyPins: PROC [wire: Wire] = {CoreGeometry.PutRecordLazyPins[extractMode.decoration, wire, cellType]}; instances: LIST OF CD.Instance; recordData: CoreClasses.RecordCellType _ NARROW [cellType.data]; WHILE obj.class#CDCells.cellClass DO obj _ CDDirectory.Expand[obj].new ENDLOOP; CoreGeometry.PutIR[extractMode.decoration, cellType, CD.InterestRect[obj]]; FOR list: LIST OF CD.Instance _ NARROW [obj.specificRef, CD.CellPtr].contents, list.rest WHILE list#NIL DO instances _ InsertInOrder[list.first, instances]; ENDLOOP; <> FOR i: NAT IN [0 .. recordData.size) DO CoreGeometry.PutTransf[extractMode.decoration, recordData[i], instances.first]; instances _ instances.rest; ENDLOOP; IF instances#NIL THEN Error[$CallerBug, "DecorateAbut assumption not valid: CD cell has more instances than record CellType", cellType]; FOR i: NAT IN [0 .. cellType.public.size) DO CoreOps.VisitRootAtomics[cellType.public[i], SetLazyPins] ENDLOOP }; DecorateAbutX: PUBLIC DecorateProc = {DecorateAbut[cellType, obj, SortInX] }; DecorateAbutY: PUBLIC DecorateProc = {DecorateAbut[cellType, obj, SortInY] }; DecorateReverseAbutX: PUBLIC DecorateProc = {DecorateAbut[cellType, obj, ReverseSortInX] }; DecorateReverseAbutY: PUBLIC DecorateProc = {DecorateAbut[cellType, obj, ReverseSortInY]}; SmashPins: PROC [wire: Wire] = {CoreGeometry.PutPins[extractMode.decoration, wire, NIL]}; DecorateRecasted: PUBLIC DecorateProc = { recastedCT: CellType _ CoreOps.Recast[cellType]; CopySourcePinsFromRecasted: PROC [wire1, wire2: Wire] = { SourcePinsFromExtracted[cellType, obj, wire1, wire2]}; <> CoreOps.VisitRootAtomics[cellType.public, SmashPins]; CoreGeometry.PutIR[extractMode.decoration, cellType, CD.InterestRect[obj]]; VisitAtomicPairs[cellType.public, recastedCT.public, CopySourcePinsFromRecasted]}; <<>> <> rotatedCellClass: PUBLIC Core.CellClass _ CoreOps.SetClassPrintProc [NEW [Core.CellClassRec _ [name: "Rotated", recast: RecastRotated, layersProps: FALSE]], PrintRotated]; RecastRotated: Core.RecastProc = {RETURN[ NARROW[me.data, CellType] ]}; PrintRotated: CoreOps.PrintClassProc = { CoreOps.PrintIndent[indent, out]; out.PutF["Rotation of: %g", IO.rope[CoreOps.GetCellTypeName[NARROW [data, CellType]]]]}; RotateCellType: PUBLIC PROC[cellType: CellType, orientation: ATOM] RETURNS [rotatedCellType: CellType] = { name: ROPE _ Rope.Cat [Atom.GetPName[orientation], "-", CoreOps.GetCellTypeName[cellType]]; rotatedCellType _ CoreOps.CreateCellType[ class: rotatedCellClass, public: CoreOps.CopyWire[cellType.public], data: cellType, name: name]; SetLayout[rotatedCellType, orientation]}; AtomOrientation: PROC[atom: ATOM] RETURNS[orientation: CDOrient.Orientation] = { RETURN[SELECT atom FROM $Rot0 => CDOrient.original, $Rot0X => CDOrient.mirrorX, $Rot90 => CDOrient.rotate90, $Rot90X => CDOrient.rotate90X, $Rot180 => CDOrient.rotate180, $Rot180X => CDOrient.rotate180X, $Rot270 => CDOrient.rotate270, $Rot270X => CDOrient.rotate270X, $FlipX => CDOrient.mirrorX, $FlipY => CDOrient.mirrorY, ENDCASE => ERROR]}; Rotate: LayoutProc = { layoutAtom: ATOM _ GetLayoutAtom[cellType]; orientation: CDOrient.Orientation _ AtomOrientation[layoutAtom]; IF cellType.class#rotatedCellClass THEN Error[$CallerBug, "Rotated CellType expected", cellType]; obj _ PW.ChangeOrientation[Layout[NARROW [cellType.data]], orientation]}; DecorateRotated: PUBLIC DecorateProc = { recastedCT: CellType _ CoreOps.Recast[cellType]; transf: CD.Instance; CopyPinsFromRotated: PROC [wire1, wire2: Wire] = { CoreGeometry.PutTransfWireIRLazyPins[ decoration: extractMode.decoration, public: wire1, indirect: wire2, transf: transf, ir: ir]}; instances: LIST OF CD.Instance; ir: CD.Rect = CD.InterestRect[obj]; WHILE obj.class#CDCells.cellClass DO obj _ CDDirectory.Expand[obj].new ENDLOOP; CoreGeometry.PutIR[extractMode.decoration, cellType, ir]; instances _ NARROW [obj.specificRef, CD.CellPtr].contents; IF instances=NIL OR instances.rest#NIL THEN ERROR Error[$CallerBug, "DecorateRotated is not supposed to be called with an obj that does not expand into a one instance cell", cellType]; transf _ instances.first; <> VisitAtomicPairs[cellType.public, recastedCT.public, CopyPinsFromRotated]; }; <<>> <> SortInX: PUBLIC PROC [pos1, pos2: CD.Position] RETURNS [BOOL] = {RETURN [pos1.xpos2.x]}; ReverseSortInY: PUBLIC PROC [pos1, pos2: CD.Position] RETURNS [BOOL] = {RETURN [pos1.y>pos2.y]}; <> SetLayout: PUBLIC PROC [cellType: CellType, layoutAtom: ATOM, userDataProp: ATOM _ NIL, userData: REF _ NIL] = { CoreProperties.PutCellTypeProp[cellType, layoutAtomProp, layoutAtom]; IF userDataProp#NIL THEN CoreProperties.PutCellTypeProp[cellType, userDataProp, userData]}; <<>> <> AbutList: PUBLIC PROC [cellTypes: LIST OF CellType, inX: BOOL] RETURNS [recordCell: CellType] = { lobj: LIST OF CD.Object _ NIL; WHILE cellTypes#NIL DO ct: CellType _ cellTypes.first; obj: CD.Object _ CDCells.CreateEmptyCell[]; CDCells.SetInterestRect[obj, InterestRect[ct]]; CDProperties.PutObjectProp[obj, $PWCCellType, ct]; CDProperties.PutObjectProp[obj, extractMode.extractProcProp, $FakeExtract]; lobj _ CONS [obj, lobj]; cellTypes _ cellTypes.rest; ENDLOOP; recordCell _ NARROW [Sinix.Extract[(IF inX THEN PW.AbutListX ELSE PW.AbutListY)[PW.Reverse[lobj]], extractMode].result]; SetLayout[recordCell, IF inX THEN $AbutListXNoDecorate ELSE $AbutListYNoDecorate]}; <<>> CellShell: PUBLIC PROC[cell: CellType] RETURNS[shell: CD.Object] = { iSize: CD.Position _ InterestSize[cell]; list: LIST OF NWMML; minW: INT = CMosB.lambda; shell _ CDCells.CreateEmptyCell[]; FOR side: Side IN Side DO FOR list _ SidePinList[cell, side], list.rest WHILE list#NIL DO wireName: ROPE _ CoreOps.GetFullWireName[cell.public, list.first.wire]; pos: CD.Position _ SELECT side FROM left => [0, list.first.min], right => [iSize.x-minW, list.first.min], top => [list.first.min, iSize.y-minW], bottom => [list.first.min, 0], ENDCASE => ERROR; size: CD.Position _ SELECT side FROM top, bottom => [list.first.max - list.first.min, minW] ENDCASE => [minW, list.first.max - list.first.min]; inst: CD.Instance _ PW.IncludeInCell[shell, CDRects.CreateRect[size, list.first.layer], pos]; IF wireName.Length[]=0 THEN ERROR; CDProperties.PutInstanceProp[inst, $InstanceName, wireName]; ENDLOOP; ENDLOOP; PW.SetInterestRect[shell, iSize]; PW.RepositionCell[shell]}; SidePinList: PUBLIC PROC [cellType: CellType, side: Side] RETURNS [list: LIST OF NWMML _ NIL] = { thisSide: Side _ side; EachWirePin: CoreGeometry.EachWirePinProc = { name: ROPE _ CoreOps.GetShortWireName[wire]; IF side#thisSide THEN RETURN; IF name=NIL THEN RETURN; list _ AddMergeNWMMLs[[name, wire, min, max, layer], list]}; [] _ CoreGeometry.EnumerateWireSides[extractMode.decoration, cellType, EachWirePin]; PosSortNWMMLs[list]}; <> AddMergeNWMMLs: PUBLIC PROC[item: NWMML, lst: LIST OF NWMML] RETURNS[LIST OF NWMML] = { NameCompare: PROC[item1, item2: NWMML] RETURNS[comp: Basics.Comparison] = { IV: PROC[w: Core.Wire] RETURNS[int: INT] = {int _ LOOPHOLE[w]}; comp _ IF item1.name=NIL AND item2.name = NIL THEN Basics.CompareINT[IV[ item1.wire], IV[ item2.wire]] ELSE Rope.Compare[ item1.name, item2.name]}; dummy: NWMML _ []; head: LIST OF NWMML _ CONS[dummy, lst]; l: LIST OF NWMML _ head; IF lst=NIL THEN RETURN[CONS[item, NIL]]; WHILE l.rest#NIL DO SELECT NameCompare[l.rest.first, item] FROM greater => EXIT; equal => IF l.rest.first.layer = item.layer AND l.rest.first.max >= item.min AND l.rest.first.min <= item.max THEN { item.max _ MAX[ l.rest.first.max, item.max]; item.min _ MIN[ l.rest.first.min, item.min]; l.rest _ l.rest.rest; LOOP}; ENDCASE; l _ l.rest; ENDLOOP; l _ head; FOR l _ l, l.rest WHILE l.rest#NIL DO cpr: Basics.Comparison _ NameCompare[l.rest.first, item]; IF cpr = greater OR cpr = equal AND ( l.rest.first.layer > item.layer OR l.rest.first.layer = item.layer AND l.rest.first.min > item.max) THEN {l.rest _ CONS[item, l.rest]; EXIT}; REPEAT FINISHED => l.rest _ CONS[item, NIL] ENDLOOP; RETURN[head.rest]}; PosSortNWMMLs: PUBLIC PROC[lst: LIST OF NWMML] = { DO ok: BOOL _ TRUE; FOR l: LIST OF NWMML _ lst, l.rest WHILE l#NIL AND l.rest#NIL DO IF l.first.min > l.rest.first.min OR l.first.min = l.rest.first.min AND l.first.max > l.rest.first.max THEN {temp: NWMML _ l.first; l.first _ l.rest.first; l.rest.first _ temp; ok _ FALSE} ENDLOOP; IF ok THEN EXIT; ENDLOOP}; <> Sinix.RegisterExtractProc[$FakeExtract, FakeExtract]; [] _ RegisterLayoutAtom[$Get, Get, DecorateValue]; [] _ RegisterLayoutAtom[$GetAndFlatten, GetAndFlatten, DecorateValue]; [] _ RegisterLayoutAtom[$Value, Value, DecorateValue]; [] _ RegisterLayoutAtom[$ValueNoDecorate, Value, NoDecorate]; [] _ RegisterLayoutAtom[$AbutListXNoDecorate, AbutX, NoDecorate]; [] _ RegisterLayoutAtom[$AbutListYNoDecorate, AbutY, NoDecorate]; [] _ RegisterLayoutAtom[$AbutX, AbutX, DecorateAbutX]; [] _ RegisterLayoutAtom[$AbutY, AbutY, DecorateAbutY]; [] _ RegisterLayoutAtom[$ReverseAbutX, ReverseAbutX, DecorateReverseAbutX]; [] _ RegisterLayoutAtom[$ReverseAbutY, ReverseAbutY, DecorateReverseAbutY]; [] _ RegisterLayoutAtom[$ArrayX, ArrayX, DecorateRecasted]; [] _ RegisterLayoutAtom[$ArrayY, ArrayY, DecorateRecasted]; [] _ RegisterLayoutAtom[$ReverseArrayX, ReverseArrayX, DecorateRecasted]; [] _ RegisterLayoutAtom[$ReverseArrayY, ReverseArrayY, DecorateRecasted]; [] _ RegisterLayoutAtom[$Recast, Recast, DecorateRecasted]; [] _ RegisterLayoutAtom[$FlipX, Rotate, DecorateRotated]; [] _ RegisterLayoutAtom[$FlipY, Rotate, DecorateRotated]; [] _ RegisterLayoutAtom[$Rot0, Rotate, DecorateRotated]; [] _ RegisterLayoutAtom[$Rot0X, Rotate, DecorateRotated]; [] _ RegisterLayoutAtom[$Rot90, Rotate, DecorateRotated]; [] _ RegisterLayoutAtom[$Rot90X, Rotate, DecorateRotated]; [] _ RegisterLayoutAtom[$Rot180, Rotate, DecorateRotated]; [] _ RegisterLayoutAtom[$Rot180X, Rotate, DecorateRotated]; [] _ RegisterLayoutAtom[$Rot270, Rotate, DecorateRotated]; [] _ RegisterLayoutAtom[$Rot270X, Rotate, DecorateRotated]; <> END. <<>>