<<>> <> <> <> <> <> <> <> <> <> <> <> DIRECTORY ARAccess USING [AppendChar], Ascii USING [CR, LF, NUL, SP, TAB], Convert USING [CardFromRope, Error], <> <> Rope USING [Fetch, Length, ROPE], <> <> <> <> Token; <> TokensA: CEDAR MONITOR IMPORTS ARAccess, Convert, --Heap, Inline, --Rope--, String, StringLookUp --EXPORTS Token = BEGIN OPEN Ascii; UnterminatedQuote: PUBLIC SIGNAL = CODE; FilterState: TYPE = Token.FilterState; StandardFilterState: TYPE = Token.StandardFilterState; FilterProcType: TYPE = Token.FilterProcType; GetCharProcType: TYPE = Token.GetCharProcType; QuoteProcType: TYPE = Token.QuoteProcType; SkipMode: TYPE = Token.SkipMode; nonQuote: CHARACTER = Token.nonQuote; initialLength: CARDINAL = 100; --initial length for Token strings lengthIncrement: CARDINAL = 100; --amount of additional storage to allocate <> savedString: Rope.ROPE ¬ NIL; -- keep one string of length initialLength GetString: ENTRY PROC [length: CARDINAL] RETURNS [Rope.ROPE] = { ENABLE UNWIND => NULL; IF length = initialLength AND savedString # NIL THEN { ls: Rope.ROPE ¬ savedString; savedString ¬ NIL; ls ¬ NIL; <> RETURN[ls]}; RETURN[NIL--Heap.systemZone.NEW[StringBody[length]]--]}; FreeString: ENTRY PROC [ls: Rope.ROPE] = { ENABLE UNWIND => NULL; IF ls # NIL --AND ls.maxlength = initialLength-- AND savedString = NIL THEN { savedString ¬ ls; RETURN}; --Heap.systemZone.FREE[@ls]--}; <> <> <> <> <> <> <> <> <> <> <> <> <> <<0 => box.place.x _ Decimal[sh, FALSE];>> <<1 => box.place.y _ Decimal[sh, FALSE];>> <<2 => box.dims.w _ Decimal[sh, FALSE];>> <<3 => box.dims.h _ Decimal[sh, FALSE];>> < {FreeString[temp]; EXIT};>> <> <> <<[] _ FreeStringHandle[sh]};>> <> <> <<>> <> ZeroData: PROCEDURE [data: FilterState] = TRUSTED INLINE BEGIN pu: REF LONG UNSPECIFIED = LOOPHOLE[data]; IF pu # NIL THEN pu­ ¬ 0; END; Skip: PUBLIC PROCEDURE [ h: Token.Handle, data: FilterState, filter: FilterProcType, skipInClass: BOOLEAN ¬ TRUE] = BEGIN ZeroData[data]; WHILE (h.break ¬ h.getChar[h]) # NUL AND filter[h.break, data] = skipInClass DO ENDLOOP; END; Filtered: PUBLIC PROCEDURE [ h: Token.Handle, data: FilterState, filter: FilterProcType, skip: SkipMode ¬ whiteSpace, temporary: BOOLEAN ¬ TRUE] RETURNS [value: Rope.ROPE] = BEGIN value ¬ NIL; ZeroData[data]; <> DO IF (h.break ¬ h.getChar[h]) = NUL THEN RETURN; IF skip = whiteSpace AND WhiteSpaceInline[h.break] THEN LOOP; IF filter[h.break, data] THEN EXIT; IF skip = none OR skip = whiteSpace THEN RETURN; ENDLOOP; <> value ¬ GetString[initialLength]; DO ENABLE { UNWIND => FreeString[value]; <>> <> <> <> <> <> <> }; value ¬ ARAccess.AppendChar[value, h.break]; <> IF (h.break ¬ h.getChar[h]) = NUL OR ~filter[h.break, data] THEN EXIT; ENDLOOP; IF ~temporary THEN { old: Rope.ROPE ¬ value; value ¬ old; <> FreeString[old]}; END; closeQuote: CHAR ¬ 0c; QuoteFilter: FilterProcType = { IF c = NUL THEN {SIGNAL UnterminatedQuote; RETURN [FALSE]} ELSE RETURN[c # closeQuote]}; MaybeQuoted: PUBLIC PROCEDURE [ h: Token.Handle, data: FilterState, filter: FilterProcType ¬ NonWhiteSpace, isQuote: QuoteProcType ¬ Quote, skip: SkipMode ¬ whiteSpace, temporary: BOOLEAN ¬ TRUE] RETURNS [value: Rope.ROPE] = BEGIN ApplyFilter: FilterProcType ¬ filter; ZeroData[data]; value ¬ NIL; <> DO IF (h.break ¬ h.getChar[h]) = NUL THEN RETURN; IF skip = whiteSpace AND WhiteSpaceInline[h.break] THEN LOOP; IF (closeQuote ¬ isQuote[h.break]) # nonQuote THEN IF (h.break ¬ h.getChar[h]) = closeQuote THEN { h.break ¬ h.getChar[h]; IF h.break = closeQuote THEN EXIT; -- doubling close quote is literal quote character RETURN} ELSE { IF h.break = NUL THEN {SIGNAL UnterminatedQuote; RETURN}; ApplyFilter ¬ QuoteFilter; EXIT}; IF filter[h.break, data] THEN EXIT; IF skip = none OR skip = whiteSpace THEN RETURN; ENDLOOP; <> value ¬ GetString[initialLength]; BEGIN ENABLE { UNWIND => FreeString[value]; <>> <> <> <> <> <> <> }; WHILE h.break # NUL DO value ¬ ARAccess.AppendChar[value, h.break]; IF ~ApplyFilter[h.break ¬ h.getChar[h], data] THEN BEGIN IF ApplyFilter = QuoteFilter THEN { h.break ¬ h.getChar[h]; -- get next character IF h.break = closeQuote THEN LOOP}; -- of closeQuote, include character in token EXIT; END; ENDLOOP; IF ~temporary THEN { old: Rope.ROPE ¬ value; value ¬ old; <> FreeString[old]}; END; END; <> Alphabetic: PUBLIC FilterProcType = BEGIN RETURN[SELECT c FROM IN ['a..'z], IN ['A..'Z] => TRUE, ENDCASE => FALSE]; END; AlphaNumeric: PUBLIC FilterProcType = BEGIN RETURN[ SELECT c FROM IN ['a..'z], IN ['A..'Z], IN ['0..'9] => TRUE, ENDCASE => FALSE]; END; <> <> <> <> <> <> <> <> <> uninitialized: CARDINAL = 0; inHost: CARDINAL = 1; startName: CARDINAL = 2; inName: CARDINAL = 3; FileName: PUBLIC FilterProcType = BEGIN IF data = NIL THEN ERROR NilData; SELECT c FROM IN ['a..'z], IN ['A..'Z], IN ['0..'9], '>, '*, '!, ';, '#, '-, '., '$, '+ => IF data[0] = uninitialized OR data[0] = startName THEN data[0] ¬ inName; '< => IF data[0] = uninitialized OR data[0] = startName THEN data[0] ¬ inName ELSE RETURN[FALSE]; '[ => IF data[0] = uninitialized THEN data[0] ¬ inHost ELSE RETURN[FALSE]; '] => IF data[0] = inHost THEN data[0] ¬ startName ELSE RETURN[FALSE]; ENDCASE => IF data[0] # inHost THEN RETURN[FALSE]; RETURN[TRUE]; END; Line: PUBLIC FilterProcType = BEGIN RETURN[SELECT c FROM CR, NUL => FALSE, ENDCASE => TRUE]; END; Numeric: PUBLIC FilterProcType = BEGIN RETURN[SELECT c FROM IN ['0..'9] => TRUE, ENDCASE => FALSE]; END; Switches: PUBLIC FilterProcType = -- '~, '-, AlphaNumeric BEGIN RETURN[ SELECT c FROM IN ['a..'z], IN ['A..'Z], IN ['0..'9], '~, '- => TRUE, ENDCASE => FALSE]; END; NumberFilter: FilterProcType = BEGIN RETURN[ SELECT c FROM IN ['0..'9], '+, '-, 'B, 'b, 'D, 'd => TRUE, ENDCASE => FALSE]; END; NonWhiteSpace: PUBLIC FilterProcType = BEGIN RETURN[c # NUL AND ~WhiteSpaceInline[c]]; END; WhiteSpace: PUBLIC FilterProcType = BEGIN RETURN[WhiteSpaceInline[c]]; END; WhiteSpaceInline: PROCEDURE [c: CHARACTER] RETURNS [ --isWhiteSpace:-- BOOLEAN] = INLINE BEGIN RETURN[SELECT c FROM SP, TAB, LF, CR => TRUE, ENDCASE => FALSE]; END; Brackets: PUBLIC QuoteProcType = -- () [] {} <> BEGIN RETURN[ SELECT c FROM '( => '), '[ => '], '{ => '}, '< => '>, ENDCASE => nonQuote]; END; Quote: PUBLIC QuoteProcType = -- '" BEGIN RETURN[SELECT c FROM '', '" => c, ENDCASE => nonQuote]; END; <> LSHandle: TYPE = REF LSObject; LSObject: TYPE = MACHINE DEPENDENT RECORD [ object: Token.Object, s: Rope.ROPE, i: CARDINAL]; FreeStringHandle: PUBLIC PROCEDURE [h: Token.Handle] RETURNS [nil: Token.Handle ¬ NIL] = {--Heap.systemZone.FREE[@h]--}; StringToHandle: PUBLIC PROCEDURE [s: Rope.ROPE, offset: CARDINAL ¬ 0] RETURNS [h: Token.Handle] = BEGIN lsh: LSHandle ¬ NEW[LSObject ¬ [[getChar: StringGetChar, break: Ascii.NUL], s, offset]]; h ¬ NEW[Token.Object ¬ [StringGetChar, Ascii.NUL]]; END; FreeTokenString: PUBLIC PROCEDURE [s: Rope.ROPE] RETURNS [nil: Rope.ROPE ¬ NIL] = {FreeString[s]}; StringGetChar: Token.GetCharProcType = TRUSTED BEGIN lsh: LSHandle ¬ LOOPHOLE[h]; leng: CARD ¬ lsh.s.Length[]; IF lsh.i < leng THEN { c ¬ lsh.s.Fetch[lsh.i]; lsh.i ¬ lsh.i + 1} ELSE c ¬ Ascii.NUL; END; <> NilData: PUBLIC SIGNAL = CODE; SyntaxError: PUBLIC SIGNAL [s: Rope.ROPE] = CODE; END...