-- PPCommentTableImpl.mesa -- Russ Atkinson, November 12, 1982 2:46 pm DIRECTORY PPCommentTable USING [], Rope USING [ROPE]; PPCommentTableImpl: CEDAR PROGRAM EXPORTS PPCommentTable = BEGIN OPEN PPCommentTable, Rope; Ref: TYPE = REF Node; Node: PUBLIC TYPE = RECORD [start: INT, text: ROPE, lastToken,prefix: INT]; Table: TYPE = REF TableNode; TableNode: TYPE = RECORD [ last: Ref, size: NAT, lastx: NAT, data: SEQUENCE max: NAT OF Ref]; BreakTab: TYPE = REF BreakSequence; BreakSequence: TYPE = RECORD [ size: NAT, indexes: SEQUENCE max: NAT OF INT ]; TableOverflow: PUBLIC ERROR = CODE; TableOrder: PUBLIC ERROR = CODE; -- variables in the global frame commentTable: Table _ NIL; breakTable: BreakTab _ NIL; ending: INT _ 0; Reset: PUBLIC PROC = { IF commentTable # NIL THEN { commentTable.size _ 0; commentTable.last _ NIL; commentTable.lastx _ 0}; IF breakTable # NIL THEN breakTable.size _ 0; ending _ 0; }; AddComment: PUBLIC PROC [start: INT, text: ROPE, lastToken,prefix: INT] = { ref: Ref _ NEW[Node _ [start, text, lastToken, prefix]]; size: NAT _ IF commentTable = NIL THEN 0 ELSE commentTable.size; max: NAT _ IF commentTable = NIL THEN 0 ELSE commentTable.max; last: Ref _ IF size > 0 THEN commentTable[size-1] ELSE NIL; IF lastToken > start THEN RETURN; IF last # NIL THEN { IF last.start > start OR lastToken < last.lastToken THEN RETURN; IF last.start = start THEN { -- merge the blank line comment with the actual comment IF last.text # NIL THEN RETURN; ref.prefix _ prefix + last.prefix; commentTable[size-1] _ ref; RETURN}; }; IF size >= max THEN { newMax: NAT _ IF max > (LAST[NAT]/2 - 2) THEN newMax _ LAST[NAT] ELSE newMax _ max*2 + 4; IF newMax <= size THEN ERROR TableOverflow; {newTable: Table _ NEW[TableNode[newMax]]; newTable.last _ NIL; FOR i: NAT IN [0..size) DO newTable[i] _ commentTable[i]; commentTable[i] _ NIL; ENDLOOP; commentTable _ newTable; }}; commentTable[size] _ ref; commentTable.size _ size + 1; }; AddBreakHint: PUBLIC PROC [index: INT] = { size: NAT _ IF breakTable = NIL THEN 0 ELSE breakTable.size; max: NAT _ IF breakTable = NIL THEN 0 ELSE breakTable.max; last: INT _ IF size = 0 THEN 0 ELSE breakTable[size-1]; IF index <= last THEN RETURN; IF size >= max THEN { -- must extend the table new: BreakTab _ NIL; nmax: NAT _ MAX[32, IF max < LAST[NAT]/2 THEN max+max ELSE LAST[NAT]]; IF nmax <= max THEN ERROR TableOverflow; new _ NEW[BreakSequence[nmax]]; FOR i: NAT IN [0..size) DO new[i] _ breakTable[i]; ENDLOOP; breakTable _ new; }; breakTable[size] _ index; breakTable.size _ size + 1; }; FindNextComment: PUBLIC PROC [notBefore: INT] RETURNS [Ref] = { IF commentTable # NIL AND commentTable.size > 0 THEN { low: NAT _ 0; high: NAT _ commentTable.size-1; last: Ref _ commentTable.last; lastx: NAT _ commentTable.lastx; lval: INT _ 0; IF last # NIL THEN { lval _ last.start; IF notBefore = lval THEN RETURN [last]; IF notBefore < lval THEN high _ lastx ELSE low _ lastx+1; }; WHILE low < high DO lval _ (last _ commentTable[lastx _ (low+high)/2]).start; IF notBefore < lval THEN {high _ lastx; LOOP}; IF notBefore > lval THEN {low _ lastx+1; LOOP}; commentTable.lastx _ lastx; RETURN [commentTable.last _ last]; ENDLOOP; IF high # lastx OR last = NIL THEN lval _ (last _ commentTable[lastx _ high]).start; IF notBefore <= lval THEN {commentTable.lastx _ lastx; RETURN [commentTable.last _ last]}; }; RETURN [NIL]; }; TestBreakHint: PUBLIC PROC [start: INT, next: INT] RETURNS [BOOL] = { IF start = 0 OR next <= start THEN RETURN [TRUE]; IF breakTable = NIL OR breakTable.size <= 1 THEN RETURN [FALSE]; {low: NAT _ 0; high: NAT _ breakTable.size - 1; DO last: NAT _ (low+high)/2; lval: INT _ breakTable[last]; IF low = high THEN RETURN [start < lval AND next > lval]; IF start < lval THEN { IF next > lval THEN RETURN [TRUE]; high _ last; LOOP}; IF start >= lval THEN {low _ last+1; LOOP}; ENDLOOP; }}; Explode: PUBLIC PROC [ref: Ref] RETURNS [start: INT, text: ROPE, lastToken,prefix: INT] = { IF ref = NIL THEN RETURN [LAST[INT], NIL, LAST[INT], 0]; RETURN [ref.start, ref.text, ref.lastToken, ref.prefix]; }; SetEnding: PUBLIC PROC [end: INT] = {ending _ end}; GetEnding: PUBLIC PROC RETURNS [INT] = {RETURN [ending]}; END. ĘK˜Jš”ĪcGœĪk œžœ žœžœžœžœžœžœžœžœžœžœžœžœ žœžœžœ žœžœžœžœžœ žœ žœžœžœžœžœ!žœžœ žœžœžœžœžœžœžœžœžœžœžœ!œžœžœ žœ Īnœžœžœ žœžœžœ<žœ&žœžœžœ0Ÿ œžœžœ žœžœžœžœ5žœžœžœžœžœžœžœžœžœžœ#žœ žœžœžœžœžœžœžœžœžœ žœžœ&žœžœ žœžœ 8œ žœ žœžœžœ_žœžœ žœžœžœžœžœžœ žœžœ žœžœžœžœ*žœ-žœ žœžœžœ žœJžœžœyŸ œžœžœ žœžœžœžœžœžœžœžœžœžœžœžœžœ žœžœžœžœžœžœ žœ œžœžœžœžœžœžœžœ žœžœžœ žœ žœžœžœžœžœžœ žœžœpŸœžœžœ žœžœžœžœžœžœžœžœLžœ$žœ žœžœžœ*žœžœžœžœžœžœ$žœ žœOžœžœžœ žœžœžœ3žœ'žœ žœžœžœ žœ:žœžœ.žœ,žœžœ Ÿ œžœžœ žœžœžœžœ žœ žœžœžœžœžœžœžœžœžœžœ žœžœžœžœžœžœ žœžœžœžœžœžœ žœžœžœ&žœ žœžœžœ žœŸœžœžœžœ žœžœžœ žœžœžœžœžœžœžœžœžœ žœ=Ÿ œžœžœžœŸ œžœžœžœžœžœžœ˜‘'—…—”å