<<>> <> <> <> <> DIRECTORY Basics, SourceMarks; SourceMarksImpl: CEDAR PROGRAM IMPORTS Basics EXPORTS SourceMarks = BEGIN Object: TYPE = REF ObjectRep; ObjectRep: TYPE = RECORD [ sortLink: Object ¬ NIL, tableLink: Object ¬ NIL, startPos: INT ¬ 0, endPos: INT ¬ -1, nextPos: INT ¬ -1, mark: REF ¬ NIL ]; table: MyTable ¬ NIL; MyTable: TYPE = REF MyTableRep; MyTableRep: TYPE = RECORD [ size: INT ¬ 0, head: Object ¬ NIL, tail: Object ¬ NIL, free: Object ¬ NIL, mask: CARDINAL ¬ 0, objs: SEQUENCE len: NAT OF Object]; NoSuchSource: PUBLIC ERROR = CODE; StartSource: PUBLIC PROC [startPos: INT, mark: REF] = { <> IF table = NIL THEN table ¬ CreateTable[]; IF TableFetch[table, startPos] = NIL THEN { new: Object ¬ NewObject[table]; new.startPos ¬ startPos; new.mark ¬ mark; TableStore[table, startPos, new]; }; }; <<>> EndSource: PUBLIC PROC [startPos: INT, endPos: INT] = { <> object: Object = TableFetch[table, startPos]; IF object = NIL THEN ERROR NoSuchSource; object.endPos ¬ endPos; }; <<>> MarkSource: PUBLIC PROC [startPos: INT, mark: REF, overWrite: BOOL] = { <> object: Object = TableFetch[table, startPos]; IF object = NIL THEN ERROR NoSuchSource; IF overWrite OR object.mark = NIL THEN object.mark ¬ mark; }; <<>> GetProps: PUBLIC PROC [startPos: INT] RETURNS [found: BOOL, endPos: INT, mark: REF] = { <> object: Object = TableFetch[table, startPos]; IF object # NIL THEN RETURN [TRUE, object.endPos, object.mark]; RETURN [FALSE, -1, NIL]; }; GetNext: PUBLIC PROC [startPos: INT] RETURNS [INT] = { object: Object = TableFetch[table, startPos]; IF object = NIL THEN ERROR NoSuchSource; RETURN [object.nextPos]; }; <<>> Reset: PUBLIC PROC = { <> IF table # NIL THEN ResetTable[table]; }; <> <<>> CreateTable: PROC [size: [0..16*1024) ¬ 2000] RETURNS [MyTable] = { table: MyTable ¬ NIL; mask: CARDINAL ¬ 1; IF size < 100 THEN size ¬ 100; WHILE mask < size DO mask ¬ mask + mask + 1; ENDLOOP; table ¬ NEW[MyTableRep[mask+1]]; table.mask ¬ mask; RETURN [table]; }; HashForTable: PROC [int: INT] RETURNS [CARDINAL] = INLINE { ln: Basics.LongNumber = [int[int]]; RETURN [ln.lo + ln.hi]; }; TableStore: PROC [table: MyTable, int: INT, object: Object] = { hash: CARDINAL = Basics.BITAND[table.mask, HashForTable[int]]; object.tableLink ¬ table.objs[hash]; table.objs[hash] ¬ object; IF table.tail = NIL THEN { <> table.head ¬ object; } ELSE { IF object.startPos < table.tail.startPos THEN { <> IF object.startPos < table.head.startPos THEN { <> object.sortLink ¬ table.head; object.nextPos ¬ table.head.startPos; table.head ¬ object; RETURN; } ELSE { <> lag: Object ¬ table.head; FOR each: Object ¬ lag.sortLink, each.sortLink WHILE each # NIL DO IF object.startPos < each.startPos THEN { object.nextPos ¬ each.startPos; object.sortLink ¬ each; lag.sortLink ¬ object; lag.nextPos ¬ object.startPos; RETURN; }; lag ¬ each; ENDLOOP; ERROR; }; }; table.tail.nextPos ¬ object.startPos; table.tail.sortLink ¬ object; }; table.tail ¬ object; }; TableFetch: PROC [table: MyTable, int: INT] RETURNS [Object] = { hash: CARDINAL = Basics.BITAND[table.mask, HashForTable[int]]; object: Object ¬ table.objs[hash]; WHILE object # NIL AND object.startPos # int DO object ¬ object.tableLink; ENDLOOP; RETURN [object]; }; NewObject: PROC [table: MyTable] RETURNS [Object] = { object: Object ¬ table.free; IF object # NIL THEN { table.free ¬ object.tableLink; object.tableLink ¬ NIL; } ELSE { object ¬ NEW[ObjectRep ¬ []]; }; RETURN [object]; }; ResetTable: PROC [table: MyTable] = { FOR i: NAT IN [0..table.len) DO table.objs[i] ¬ NIL; ENDLOOP; table.tail ¬ NIL; WHILE table.head # NIL DO this: Object ¬ table.head; next: Object ¬ this.sortLink; this­ ¬ [tableLink: table.free]; table.free ¬ this; table.head ¬ next; ENDLOOP; table.size ¬ 0; }; END.