DIRECTORY Atom USING[GetPName], FileUtilDefs USING[UpperCase], MCrossRefDefs, MCrossSorter, Rope USING[ROPE, Size, Fetch]; MCrossSorterImpl: PROGRAM IMPORTS Atom, FileUtilDefs, Rope EXPORTS MCrossSorter = BEGIN OPEN FileUtilDefs, MCrossSorter, MCrossRefDefs; NotInitialized: PUBLIC ERROR = CODE; SortTableLength: CARDINAL = 256; SortTable: TYPE = REF ASortTable; ASortTable: TYPE = ARRAY SortTableIndex OF RECORD[first, last: TokenHandle]; SortTableIndex: TYPE = [0..SortTableLength); sortTables: ARRAY [0..1] OF SortTable _ [NIL, NIL]; lastKeyIndex: CARDINAL _ 0; initialized: BOOLEAN _ FALSE; Initialize: PUBLIC PROC[keyLength: CARDINAL] = { Clear[]; IF initialized THEN { sortTables[0] _ NIL; sortTables[1] _ NIL}; IF keyLength = 0 THEN keyLength _ 1; lastKeyIndex _ keyLength - 1; sortTables _ [NEW[ASortTable], NEW[ASortTable]]; sortTables[0]^ _ ALL[[NIL, NIL]]; sortTables[1]^ _ ALL[[NIL, NIL]]; initialized _ TRUE; }; Finalize: PUBLIC PROC = { Clear[]; IF initialized THEN { sortTables[0] _ NIL; sortTables[1] _ NIL; initialized _ FALSE}; }; Clear: PUBLIC PROC = { i: SortTableIndex; k: [0..1]; IF ~initialized THEN RETURN; FOR k IN [0..1] DO FOR i IN SortTableIndex DO sortTables[k][i] _ [NIL, NIL]; ENDLOOP; ENDLOOP; }; Enter: PUBLIC PROC[token: TokenHandle] = { Insert[sortTables[lastKeyIndex MOD 2], token, GetSTI[Atom.GetPName[token.name], lastKeyIndex]]; }; Enumerate: PUBLIC PROC[leafProc: PROC[token: TokenHandle] RETURNS[stop: BOOLEAN], order: SortOrder _ unordered] RETURNS[stopped: BOOLEAN] = { i: SortTableIndex; st: SortTable = sortTables[0]; IF ~initialized THEN ERROR NotInitialized; IF order # unordered THEN Sort[]; IF order = decreasing THEN FOR i DECREASING IN SortTableIndex DO leaf: TokenHandle; st[i].first _ ReverseEntryList[st[i].first]; FOR leaf _ st[i].first, leaf.next UNTIL leaf = NIL DO IF leafProc[leaf] THEN { st[i].first _ ReverseEntryList[st[i].first]; RETURN[TRUE]}; ENDLOOP; st[i].first _ ReverseEntryList[st[i].first]; -- otherwise can't enumerate again ENDLOOP ELSE FOR i IN SortTableIndex DO leaf: TokenHandle; FOR leaf _ st[i].first, leaf.next UNTIL leaf = NIL DO IF leafProc[leaf] THEN RETURN[TRUE]; ENDLOOP; ENDLOOP; RETURN[FALSE]; }; GetSTI: PROC[key: Rope.ROPE, chi: CARDINAL] RETURNS[SortTableIndex]= INLINE { IF Rope.Size[key] <= chi THEN RETURN[FIRST[SortTableIndex]]; RETURN[LOOPHOLE[UpperCase[Rope.Fetch[key, chi]]]]}; ReverseEntryList: PROC[this: TokenHandle] RETURNS[last: TokenHandle _ NIL] = INLINE { UNTIL this = NIL DO next: TokenHandle _ this.next; this.next _ last; last _ this; this _ next; ENDLOOP}; Sort: PROC = { FOR k: CARDINAL DECREASING IN [0..lastKeyIndex) DO oldST: SortTable = sortTables[(k+1) MOD 2]; newST: SortTable = sortTables[k MOD 2]; FOR i: SortTableIndex IN SortTableIndex DO entry: TokenHandle _ oldST[i].first; oldST[i] _ [NIL, NIL]; UNTIL entry = NIL DO next: TokenHandle = entry.next; Insert[newST, entry, GetSTI[Atom.GetPName[entry.name], k]]; entry _ next; ENDLOOP; ENDLOOP; ENDLOOP; }; Insert: PROC[st: SortTable, entry: TokenHandle, sti: SortTableIndex] = INLINE { IF st[sti].first = NIL THEN st[sti].first _ entry ELSE st[sti].last.next _ entry; st[sti].last _ entry; entry.next _ NIL}; END. æMCrossSorterImpl.Mesa A simple interface for sorting a collection of objects based on a string key last edited October 11, 1983 11:53 pm by Paul Rovner ERRORS CONSTANTS TYPES VARIABLES PUBLIC PROCEDURES PRIVATE PROCEDURES Êl˜Jšœ™JšœM™MJšœ4™4J˜šÏk ˜ Jšœœ ˜Jšœ œ ˜J˜J˜ Jšœœœ˜J˜—šœœ˜Jšœ˜ Jšœ ˜—Jšœœœ+˜7J˜šœ™Jšœœœœ˜$J˜—šœ ™ Jšœœ˜ J˜—šœ™Jšœ œœ ˜!Jš œ œœœœ˜LJšœœ˜,J˜—šœ ™ Jš œ œœœœ˜3Jšœœ˜Jšœ œœ˜J˜J˜—Jšœ™˜šÏn œœœ œ˜.˜ šœ ˜šœœ˜Jšœœ˜——Jšœœ˜$J˜Jšœœœ˜0Jšœœœœ˜!Jšœœœœ˜!Jšœœ˜—J˜J˜—šžœœœ˜˜ šœ ˜šœœ˜Jšœœ˜Jšœœ˜———J˜J˜—šžœœœ˜˜J˜ Jšœœœ˜šœœ˜Jš œœœœœœ˜BJšœ˜——J˜J˜—šžœœœ˜(šœ!œ˜(J˜J˜1—J˜J˜—š ž œœœ œœœ˜QJ˜Jšœ œ˜˜J˜J˜Jšœœœ˜*Jšœœ˜!šœ˜šœ œœ˜%J˜J˜,šœœœ˜5šœ˜Jšœ/œœ˜=—Jšœ˜—Jšœ.Ïc"˜PJš˜—š˜šœœ˜J˜šœœœ˜5Jšœœœœ˜$Jšœ˜—Jšœ˜———Jšœœ˜—J˜J˜J˜J˜——Jšœ™˜š žœœ œœœ˜Dš œœœœœ˜EJšœœ$˜3J˜——šžœœœœ˜Lšœœœ˜J˜J˜J˜ J˜ Jšœ˜ J˜——šžœœ˜ š œœœ œœ˜4Jšœ$œ˜+Jšœ œ˜'šœœ˜*J˜$Jšœ œœ˜šœ œ˜J˜J˜;J˜ Jšœ˜—Jšœ˜—Jšœ˜—J˜J˜—šžœœ:˜Fšœœœœ˜:Jšœ˜J˜Jšœ œ˜J˜J˜———Jšœ˜J˜—…— ŠÜ