DIRECTORY Asserting, Atom, Basics, Buttons, Collections, Containers, FS, Icons, IO, LichenArrayStuff, LichenDataOps, LichenDataStructure, LichenFromExtPrivate, List, PairCollections, PieViewers, Process, ProcessProps, RefTab, RefText, Rope, RopeHash, ViewerClasses, ViewerOps, ViewerTools; LichenFromExt1Impl: CEDAR MONITOR LOCKS dr USING dr: DesignReading IMPORTS Asserting, Atom, Buttons, Collections, Containers, FS, Icons, IO, LichenArrayStuff, LichenDataOps, LichenDataStructure, LichenFromExtPrivate, List, PairCollections, PieViewers, Process, ProcessProps, RefTab, RefText, Rope, RopeHash, ViewerOps, ViewerTools EXPORTS LichenFromExtPrivate = BEGIN OPEN Asserting, LichenDataOps, LichenArrayStuff, LichenDataStructure, LichenFromExtPrivate, Colls:Collections, PairColls:PairCollections; readers: VarFunction _ PairColls.CreateHashDictionary[TRUE]; pacifierIcon: Icons.IconFlavor _ Icons.NewIconFromFile["Lichen.icons", 0]; pacifyPeriod: Process.Milliseconds _ 2500; labelHeight: INTEGER _ 17; pauseWidth: INTEGER _ 60; pieDiameter: INTEGER _ 50; ReadDesign: PROC [rootCellFileName: ROPE, oldDR: DesignReading _ NIL] RETURNS [dr: DesignReading] = BEGIN Doit: PROC = { dr.stack _ NIL; [] _ ReadCellType[dr.design, rootCellFileName, dr]}; IF oldDR = NIL THEN { cp: FS.ComponentPositions; fullFName, designName: ROPE; [fullFName, cp, ] _ FS.ExpandName[rootCellFileName]; designName _ fullFName.Substr[start: cp.base.start, len: cp.base.length]; dr _ NEW [DesignReadingRep _ [ design: NEW [DesignPrivate _ [ cellTypes: Colls.CreateHashSet[], other: Assert1[nameReln, designName, NIL] ]], wDir: fullFName.Substr[len: cp.base.start], cellTypesByName: PairColls.CreateHashDictionary[TRUE], fetTypes: RefTab.Create[hash: HashFetType, equal: CompareFetTypes], unkosherArrays: Colls.CreateHashSet[], toMerge: PairColls.CreateHashFn[spaces: [paths, Colls.refs], invable: FALSE], buffer: RefText.New[200], pacifier: Containers.Create[info: [name: designName.Cat[" pacifier"], icon: pacifierIcon]], pie: NIL, label: NIL, pause: NIL ]]; TRUSTED { Process.InitializeCondition[@dr.change, Process.SecondsToTicks[60]]; Process.EnableAborts[@dr.change]}; dr.pause _ Buttons.Create[info: [name: "Pause", parent: dr.pacifier, wx: 0, wy: 0, ww: pauseWidth, wh: labelHeight], proc: TogglePause, clientData: dr]; dr.label _ ViewerTools.MakeNewTextViewer[info: [parent: dr.pacifier, wx: dr.pause.wx+dr.pause.ww, wy: 0, ww: 100, wh: labelHeight]]; Containers.ChildXBound[container: dr.pacifier, child: dr.label]; dr.pie _ PieViewers.Create[parent: dr.pacifier, x: 0, y: dr.label.wy+dr.label.wh, diameter: pieDiameter, total: 1.0, divisions: 100]; Containers.ChildXBound[container: dr.pacifier, child: dr.pie]; Containers.ChildYBound[container: dr.pacifier, child: dr.pie]; ViewerOps.SetOpenHeight[dr.pacifier, dr.pie.wy+dr.pie.wh]; TRUSTED {Process.Detach[FORK Pacify[dr]]}; } ELSE { dr _ oldDR; }; ProcessProps.PushPropList[List.PutAssoc[$WorkingDirectory, dr.wDir, NIL], Doit]; END; Wait: ENTRY PROC [dr: DesignReading] = { ENABLE UNWIND => NULL; WHILE dr.stop DO WAIT dr.change ENDLOOP}; Pacify: PROC [dr: DesignReading] = { lastStack: SourceList _ NIL; lastIndex: INT _ 0; ViewerOps.OpenIcon[icon: dr.pacifier, bottom: FALSE]; WHILE NOT dr.pacifier.destroyed DO WithLock: ENTRY PROC [dr: DesignReading] = { ENABLE UNWIND => NULL; IF dr.stack = NIL THEN { IF dr.stack # lastStack THEN { lastStack _ dr.stack; ViewerTools.SetContents[dr.label, "Idle"]; PieViewers.Set[dr.pie, 0]; }; } ELSE { index: INT = dr.stack.first.stream.GetIndex[]; IF dr.stack # lastStack OR index # lastIndex THEN { lastStack _ dr.stack; lastIndex _ index; ViewerTools.SetContents[dr.label, IO.PutFR["%g%g%g[%g]", [rope[dr.prefix]], [rope[dr.curCellTypeName]], [rope[IF dr.curArray THEN ".aext" ELSE ""]], [integer[index]]]]; PieViewers.Set[dr.pie, index/dr.curCellFileLength]; }; }; }; Process.Pause[Process.MsecToTicks[pacifyPeriod]]; WithLock[dr]; ENDLOOP; RETURN}; TogglePause: Buttons.ButtonProc = { dr: DesignReading = NARROW[clientData]; Flip: ENTRY PROC [dr: DesignReading] = { ENABLE UNWIND => NULL; dr.stop _ NOT dr.stop; BROADCAST dr.change}; Flip[dr]; Buttons.ReLabel[dr.pause, IF dr.stop THEN "Continue" ELSE "Pause"]; }; DoPushed: PROC [dr: DesignReading, cellTypeName: ROPE, array: BOOL, s: Source, Proc: PROC [Source]] = { cooler: SourceList = dr.stack; oldCellTypeName: ROPE = dr.curCellTypeName; oldArray: BOOL = dr.curArray; oldPrefix: ROPE = dr.prefix; oldCellFileLength: REAL = dr.curCellFileLength; newPrefix: ROPE = FmtStack[cooler]; newCellFileLength: INT = MAX[s.stream.GetLength[], 1]; Push: ENTRY PROC [dr: DesignReading] = { ENABLE UNWIND => NULL; dr.stack _ CONS[s, dr.stack]; dr.curCellTypeName _ cellTypeName; dr.curArray _ array; dr.prefix _ newPrefix; dr.curCellFileLength _ newCellFileLength; }; Pop: ENTRY PROC [dr: DesignReading] = { ENABLE UNWIND => NULL; dr.stack _ cooler; dr.curCellTypeName _ oldCellTypeName; dr.curArray _ oldArray; dr.prefix _ oldPrefix; dr.curCellFileLength _ oldCellFileLength; }; Push[dr]; Proc[s !UNWIND => Pop[dr]]; Pop[dr]; }; ReadCellType: PUBLIC PROC [design: Design, cellFileName: ROPE, dr: DesignReading] RETURNS [ct: CellType] = { cp: FS.ComponentPositions; fullFName, cellTypeName: ROPE; from: IO.STREAM; s: Source; cr: CellReading; Pushed: PROC [s: Source] = {PushedRead[dr, cr, s, FALSE]}; [fullFName, cp] _ ExpandName[cellFileName, "ext"]; cellTypeName _ fullFName.Substr[start: cp.base.start, len: cp.base.length]; ct _ LocalCreateCellType[design, dr, cellTypeName, TRUE, NIL, NIL]; cr _ NEW[CellReadingRep _ [dr: dr, ct: ct, name: cellTypeName, newArrays: Colls.CreateHashSet[]]]; s _ [from _ FS.StreamOpen[fullFName], fullFName]; DoPushed[dr, cellTypeName, FALSE, s, Pushed]; from.Close[]; RETURN}; TryArrayFile: PUBLIC PROC [cr: CellReading] = { fullFName: ROPE = ExpandName[cr.name, "aext"].fullFName; s: Source = [FS.StreamOpen[fullFName], fullFName]; Pushed: PROC [s: Source] = { PushedRead[cr.dr, cr, s, TRUE]; FinishWaitingMerges[cr]; RETURN}; FinishArray: PROC [ra: REF ANY] ~ { act: CellType ~ NARROW[ra]; FinishedMakingArrayConnections[act]; RETURN}; IF (NOT cr.dr.toMerge.Empty[]) OR cr.waitingMerges # NIL THEN ERROR; DoPushed[cr.dr, cr.name, TRUE, s, Pushed]; s.stream.Close[]; cr.newArrays.Enumerate[FinishArray]; RETURN}; PushedRead: PROC [dr: DesignReading, cr: CellReading, s: Source, nested: BOOL] = { from: IO.STREAM = s.stream; ct: CellType = cr.ct; DO keyword: ROPE; reader: Reader; Process.CheckForAbort[]; [] _ from.SkipWhitespace[]; IF from.EndOf[] THEN EXIT; IF dr.stop THEN Wait[dr]; keyword _ from.GetTokenRope[TokenBreak].token; reader _ NARROW[readers.Apply[keyword].DVal]; IF reader # NIL THEN reader.read[s, reader, cr] ELSE { terms: Terms _ GetLineTerms[from]; reln: ATOM _ Atom.MakeAtom[keyword]; ct.otherPublic _ Assert[reln, terms, ct.otherPublic]; }; ENDLOOP; IF (NOT dr.toMerge.Empty[]) THEN { IF cr.firstMerge THEN ERROR; DoMerges[s, cr]; } ELSE IF cr.firstMerge THEN {cr.firstMerge _ FALSE; TryArrayFile[cr]}; IF nested THEN RETURN; ct.publicKnown _ TRUE; ct.privateKnown _ TRUE; {CleanupChild: PROC [ra: REF ANY] = { ci: CellInstance = NARROW[ra]; childType: CellType = ci.type; IF childType.asArray # NIL THEN { IF childType.useCount # 1 THEN ERROR; }; }; ct.asUnorganized.containedInstances.Enumerate[CleanupChild]; }}; FmtStack: PROC [stack: SourceList] RETURNS [prefix: ROPE] = { prefix _ NIL; FOR stack _ stack, stack.rest WHILE stack # NIL DO full: ROPE; cp: FS.ComponentPositions; [full, cp, ] _ FS.ExpandName[stack.first.name]; prefix _ IO.PutFR["%g[%g], %g", [rope[full.Substr[cp.base.start, cp.base.length]]], [integer[IO.GetIndex[stack.first.stream]]], [rope[prefix]]]; ENDLOOP; RETURN}; paths: PUBLIC Colls.Space ~ NEW [Colls.SpacePrivate _ [ Equal: PathEqual, Hash: PathHash, Compare: PathCompare, other: List.PutAssoc[$Name, "paths", NIL] ]]; PathEqual: PROC [data, elt1, elt2: REF ANY] RETURNS [BOOL] --Colls.EqualProc-- ~ { p1: Path ~ NARROW[elt1]; p2: Path ~ NARROW[elt2]; RETURN [ComparePaths[p1, p2]=equal]}; PathHash: PROC [data, elt: REF ANY _ ] RETURNS [CARDINAL] --Colls.HashProc-- ~ { RETURN [HashPath[NARROW[elt]]]}; PathCompare: PROC [data, elt1, elt2: REF ANY _ ] RETURNS [c: Basics.Comparison] --Colls.CompareProc-- ~ { p1: Path ~ NARROW[elt1]; p2: Path ~ NARROW[elt2]; RETURN ComparePaths[p1, p2]}; ComparePaths: PUBLIC PROC [path1, path2: Path] RETURNS [c: Basics.Comparison] = { DO IF path1 = path2 THEN RETURN [equal]; IF path1 = NIL THEN RETURN [less]; IF path2 = NIL THEN RETURN [greater]; WITH path1.first SELECT FROM r1: ROPE => WITH path2.first SELECT FROM r2: ROPE => c _ r1.Compare[r2]; x2: REF Range2 => c _ less; ENDCASE => ERROR; s1: REF Range2 => WITH path2.first SELECT FROM r2: ROPE => c _ greater; s2: REF Range2 => IF (c _ IntCompare[s1[Foo].min, s2[Foo].min]) = equal THEN IF (c _ IntCompare[s1[Foo].maxPlusOne, s2[Foo].maxPlusOne]) = equal THEN IF (c _ IntCompare[s1[Bar].min, s2[Bar].min]) = equal THEN c _ IntCompare[s1[Bar].maxPlusOne, s2[Bar].maxPlusOne]; ENDCASE => ERROR; ENDCASE => ERROR; IF c # equal THEN RETURN; path1 _ path1.rest; path2 _ path2.rest; ENDLOOP; }; HashPath: PROC [path: Path] RETURNS [hash: CARDINAL] = { hash _ 0; FOR path _ path, path.rest WHILE path # NIL DO WITH path.first SELECT FROM r: ROPE => hash _ hash + RopeHash.FromRope[r]; x: REF Range2 => hash _ hash + Colls.HashIntI[x[Foo].min] + Colls.HashIntI[x[Foo].maxPlusOne] + Colls.HashIntI[x[Bar].min] + Colls.HashIntI[x[Bar].maxPlusOne]; ENDCASE => ERROR; ENDLOOP; }; IntCompare: PROC [i1, i2: INT] RETURNS [c: Basics.Comparison] = { c _ SELECT i1 - i2 FROM >0 => greater, =0 => equal, <0 => less, ENDCASE => ERROR; }; CompareFetTypes: PROC [key1, key2: REF ANY] RETURNS [equal: BOOL] --RefTab.EqualProc-- = { k1: FetType = NARROW[key1]; k2: FetType = NARROW[key2]; equal _ k1.className.Equal[k2.className] AND k1.area = k2.area AND k1.perim = k2.perim AND k1.twiceLength = k2.twiceLength; }; HashFetType: PROC [ra: REF ANY] RETURNS [hash: CARDINAL] --RefTab.HashProc-- = { ft: FetType = NARROW[ra]; hash _ RopeHash.FromRope[ft.className]; hash _ (hash + 3*ft.area + 11*ft.perim + 101*ft.twiceLength) MOD 65536; }; Register: PUBLIC PROC [keyword: ROPE, read: PROC [s: Source, reader: Reader, cr: CellReading], data: REF ANY _ NIL] = { r: Reader _ NEW [ReaderRep _ [keyword, read, data]]; readers.AddNewPair[[keyword, r]]; }; Start: PROC = { }; Start[]; END. `LichenFromExt1Impl.Mesa Last tweaked by Mike Spreitzer on October 14, 1987 3:41:54 pm PDT Κα– "cedar" style˜code™KšœA™A—K˜KšΟk œ<œ œΟ˜‘K˜šΡbnxœœ˜!Kšœœ˜ Kšœ4œ œΏ˜‡Kšœ˜Kšœ˜—K˜KšœœXΟnœŸ œ˜K˜Kšœ6œ˜K–B[container: Containers.Container, child: ViewerClasses.Viewer]˜>K˜:Kšœœ˜*K˜—šœ˜K˜ K˜—KšœDœ ˜PKšœ˜—K˜šŸœœœ˜(Kšœœœ˜Kšœ œœ œ˜)—K˜šŸœœ˜$Kšœœ˜Kšœ œ˜K–h[icon: ViewerClasses.Viewer, closeOthers: BOOL _ FALSE, bottom: BOOL _ TRUE, paint: BOOL _ TRUE]šœ.œ˜5šœœ˜"šŸœœœ˜,Kšœœœ˜šœ œœ˜šœœ˜Kšœ˜Kšœ*˜*Kšœ˜K˜—K˜—šœ˜Kšœœ$˜.šœœœ˜3Kšœ˜K˜Kš œ"œJœ œ œ˜¨Kšœ3˜3K˜—K˜—K˜—Kšœ1˜1Kšœ ˜ Kšœ˜—Kšœ˜—K˜šŸ œ˜#Kšœœ ˜'šŸœœœ˜(Kšœœœ˜Kšœ œ ˜Kš œ ˜—K˜ Kšœœ œ œ ˜CK˜—K˜š Ÿœœ#œ œ Ÿœœ˜gK˜Kšœœ˜+Kšœ œ˜Kšœ œ ˜Kšœœ˜/Kšœ œ˜#Kšœœœ˜6šŸœœœ˜(Kšœœœ˜Kšœ œ˜Kšœ"˜"Kšœ˜Kšœ˜Kšœ)˜)K˜—šŸœœœ˜'Kšœœœ˜K˜Kšœ%˜%Kšœ˜Kšœ˜Kšœ)˜)K˜—K˜ Kšœœ ˜K˜K˜—K˜š Ÿ œœœ œœ˜lKšœœ˜Kšœœ˜Kšœœœ˜K˜ Kšœ˜KšŸœœ&œ˜:Kšœ2˜2KšœK˜KKšœ3œœœ˜CKšœœZ˜bKšœ œ#˜1Kšœœ ˜-K˜ Kšœ˜—K˜šŸ œœœ˜/Kšœ œ)˜8Kšœ œ#˜2šŸœœ˜Kšœœ˜K˜Kšœ˜—šŸ œœœœ˜#Kšœœ˜Kšœ$˜$Kšœ˜—Kš œœœœœœ˜DKšœœ ˜*K˜Kšœ$˜$Kšœ˜—K˜šŸ œœ9œ˜RKšœœœ ˜K˜š˜Kšœ œ˜K˜Kšœ˜K˜Kšœœœ˜Kšœ œ ˜K˜.Kšœ œ˜-šœ ˜Kšœ˜šœ˜K˜"Kšœœ˜$Kšœ5˜5K˜——Kšœ˜—šœœœ˜"Kšœœœ˜Kšœ˜K˜—Kšœœœœ˜EKšœœœ˜Kšœœ˜Kšœœ˜š œŸ œœœœ˜%Kšœœ˜K˜šœœœ˜!Kšœœœ˜%Kšœ˜—K˜—Kšœ<˜