<> <> <> <> <> <> <> <> <> <<>> <> DIRECTORY Ascii USING [CR, SP, TAB, LF, BS, ControlA, ControlX, FF, NUL, ESC, DEL, BEL], Atom USING [PropList], Basics USING [UnsafeBlock], BasicTime USING [GMT, Now, Unpacked], Rope USING [ROPE]; IO: CEDAR DEFINITIONS IMPORTS BasicTime = BEGIN ROPE: TYPE = Rope.ROPE; UnsafeBlock: TYPE = Basics.UnsafeBlock; <> <<>> STREAM: TYPE = REF STREAMRecord; <> <> <<>> StreamVariety: TYPE = {input, output, inputOutput}; <> <> <> EndOfStream: ERROR [stream: STREAM]; Error: ERROR [ec: ErrorCode, stream: STREAM]; ErrorCode: TYPE = { Null, <> NotImplementedForThisStream, <> StreamClosed, <> Failure, <> IllegalBackup, <> BufferOverflow, <> BadIndex, <> SyntaxError, <> Overflow, <> PFInvalidCode, <> PFInvalidPFProcs, <> PFCantBindConversionProc, <> PFFormatSyntaxError, <> PFTypeMismatch, <> PFUnprintableValue < int conversion)>> }; <> GetInfo: PROC [stream: STREAM] RETURNS [variety: StreamVariety, class: ATOM]; <> GetChar: PROC [self: STREAM] RETURNS [CHAR]; <> <<>> GetBlock: PROC [self: STREAM, block: REF TEXT, startIndex: NAT _ 0, count: NAT _ NAT.LAST] RETURNS [nBytesRead: NAT]; <> <<>> UnsafeGetBlock: UNSAFE PROC [self: STREAM, block: UnsafeBlock] RETURNS [nBytesRead: INT]; <> <> <<>> EndOf: PROC [self: STREAM] RETURNS [BOOL]; <> <<>> CharsAvail: PROC [self: STREAM, wait: BOOL _ FALSE] RETURNS [INT]; <> <<>> Backup: PROC [self: STREAM, char: CHAR]; <> <> <<>> PeekChar: PROC [self: STREAM] RETURNS [char: CHAR]; <> <> PutChar: PROC [self: STREAM, char: CHAR]; <> PutBlock: PROC [self: STREAM, block: REF READONLY TEXT, startIndex: NAT _ 0, count: NAT _ NAT.LAST]; < block.maxLength, then set count _ block.length-startIndex. Then perform PutChar for each byte in block[startIndex .. startIndex+count).>> <<>> UnsafePutBlock: PROC [self: STREAM, block: UnsafeBlock]; <> <> <<>> Flush: PROC [self: STREAM]; <> <<>> EraseChar: PROC [self: STREAM, char: CHAR]; <> <> Reset: PROC [self: STREAM]; <> <<>> Close: PROC [self: STREAM, abort: BOOL _ FALSE]; <> <> GetIndex: PROC[self: STREAM] RETURNS [index: INT]; SetIndex: PROC[self: STREAM, index: INT]; GetLength: PROC[self: STREAM] RETURNS [length: INT]; SetLength: PROC[self: STREAM, length: INT]; <> <> <> <> <> <> RIS: PROC [rope: ROPE, oldStream: STREAM _ NIL] RETURNS [stream: STREAM]; <> ROS: PROC [oldStream: STREAM _ NIL] RETURNS [stream: STREAM]; <> RopeFromROS: PROC [self: STREAM, close: BOOL _ TRUE] RETURNS [ROPE]; <> <> TIS: PROC [text: REF READONLY TEXT, oldStream: STREAM _ NIL] RETURNS [stream: STREAM]; <> <<>> TOS: PROC [text: REF TEXT _ NIL, oldStream: STREAM _ NIL] RETURNS [stream: STREAM]; <> <<>> TextFromTOS: PROC [self: STREAM] RETURNS [REF TEXT]; <> <> noWhereStream: STREAM; <> noInputStream: STREAM; <> <> <> <> PutRope: PROC [self: STREAM, r: ROPE]; PutText: PROC [self: STREAM, t: REF READONLY TEXT]; atom: PROC [v: ATOM] RETURNS [Value] = INLINE {RETURN[[atom[v]]]}; bool: PROC [v: BOOL] RETURNS [Value] = INLINE {RETURN[[boolean[v]]]}; card: PROC [v: LONG CARDINAL] RETURNS [Value] = INLINE {RETURN[[cardinal[v]]]}; char: PROC [v: CHAR] RETURNS [Value] = INLINE {RETURN[[character[v]]]}; int: PROC [v: INT] RETURNS [Value] = INLINE {RETURN[[integer[v]]]}; real: PROC [v: REAL] RETURNS [Value] = INLINE {RETURN[[real[v]]]}; refAny: PROC [v: REF READONLY ANY] RETURNS [Value] = INLINE {RETURN[[refAny[v]]]}; rope: PROC [v: ROPE] RETURNS [Value] = INLINE {RETURN[[rope[v]]]}; text: PROC [v: REF READONLY TEXT] RETURNS [Value] = INLINE {RETURN[[text[v]]]}; time: PROC [v: BasicTime.GMT _ BasicTime.Now[]] RETURNS [Value] = INLINE { RETURN[[time[v]]]; }; <> <> <> Put: PROC [stream: STREAM, v1, v2, v3: Value _ [null[]]]; Put1: PROC [stream: STREAM, value: Value _ [null[]]]; PutR: PROC [v1, v2, v3: Value _ [null[]]] RETURNS [ROPE]; PutR1: PROC [value: Value _ [null[]]] RETURNS [ROPE]; PutL: PROC [stream: STREAM, list: LIST OF Value]; PutLR: PROC [list: LIST OF Value] RETURNS [ROPE]; <> <> <<"This is an integer in a 5 position field: | 17|">> <> <<"This is an integer in a 5 position field: |00017|">> <> <<"This is an integer in a 5 position field: |17 |">> PutF: PROC [stream: STREAM, format: ROPE _ NIL, v1, v2, v3, v4, v5: Value _ [null[]]]; PutF1: PROC [stream: STREAM, format: ROPE _ NIL, value: Value _ [null[]]]; PutFR: PROC [format: ROPE _ NIL, v1, v2, v3, v4, v5: Value _ [null[]]] RETURNS [ROPE]; PutFR1: PROC [format: ROPE _ NIL, value: Value _ [null[]]] RETURNS [ROPE]; PutFL: PROC [stream: STREAM, format: ROPE _ NIL, list: LIST OF Value]; PutFLR: PROC [format: ROPE _ NIL, list: LIST OF Value] RETURNS [ROPE]; <> <> <> GetCedarToken: PROC [stream: STREAM, buffer: REF TEXT, flushComments: BOOL _ TRUE] RETURNS [tokenKind: TokenKind, token: REF TEXT, charsSkipped: INT, error: TokenError]; <> <> TokenKind: TYPE = { tokenERROR, -- token.error describes the scanning error tokenID, -- an identifier or reserved word tokenDECIMAL, -- a whole number literal expressed in decimal tokenOCTAL, -- a whole number literal expressed in octal tokenHEX, -- a whole number literal expressed in hexidecimal tokenREAL, -- a REAL literal tokenROPE, -- a ROPE, REF TEXT, or STRING literal tokenCHAR, -- a CHAR literal tokenATOM, -- an ATOM literal tokenSINGLE, -- a single-character token tokenDOUBLE, -- a double-character token tokenCOMMENT, -- a comment tokenEOF -- the end-of-file marker }; TokenError: TYPE = { none, -- no error extendedChar, -- error following backslash in char or string literal numericLiteral, charLiteral, stringLiteral, atomLiteral, -- error in parsing indicated type singleChar -- first non-whitespace char is not legal as first char of token }; GetCedarTokenRope: PROC [stream: STREAM, flushComments: BOOL _ TRUE] RETURNS [tokenKind: TokenKind, token: ROPE, charsSkipped: INT]; <> <> <> <> <> GetInt: PROC [stream: STREAM] RETURNS [INT]; GetCard: PROC [stream: STREAM] RETURNS [LONG CARDINAL]; GetReal: PROC [stream: STREAM] RETURNS [REAL]; GetBool: PROC [stream: STREAM] RETURNS [BOOL]; GetAtom: PROC [stream: STREAM] RETURNS [ATOM]; GetRopeLiteral: PROC [stream: STREAM] RETURNS [ROPE]; GetCharLiteral: PROC [stream: STREAM] RETURNS [CHAR]; GetID: PROC [stream: STREAM] RETURNS [ROPE]; GetTime: PROC [stream: STREAM] RETURNS [BasicTime.GMT]; GetUnpackedTime: PROC [stream: STREAM] RETURNS [BasicTime.Unpacked]; GetRefAny: PROC [stream: STREAM] RETURNS [REF ANY]; <> <<'( starts a list (LIST OF REF ANY), ') terminates a list,>> <<'+, '- are unary operators that may precede a numeric literal,>> <<', is ignored between elements of a list,>> <<'^ is always ignored.>> GetRefAnyLine: PROC [stream: STREAM] RETURNS [LIST OF REF ANY]; <> <<>> <> SkipWhitespace: PROC [stream: STREAM, flushComments: BOOL _ TRUE] RETURNS [charsSkipped: INT]; <> <<>> GetToken: PROC [ stream: STREAM, breakProc: BreakProc _ TokenProc, buffer: REF TEXT] RETURNS [token: REF TEXT, charsSkipped: INT]; <> <> BreakProc: TYPE = PROC [char: CHAR] RETURNS [CharClass]; CharClass: TYPE = {break, sepr, other}; TokenProc: BreakProc; <> < sepr,>> <<'[, '], '(, '), '{, '}, '", '+, '-, '*, '/, '@, '_ => break,>> < other]};>> <> IDProc: BreakProc; <> < sepr,>> < other]};>> <> <<>> GetTokenRope: PROC [ stream: STREAM, breakProc: BreakProc _ TokenProc] RETURNS [token: ROPE, charsSkipped: INT]; <> <> <<>> GetLine: PROC [stream: STREAM, buffer: REF TEXT] RETURNS [line: REF TEXT]; <> <> <<>> GetLineRope: PROC [stream: STREAM] RETURNS [line: ROPE]; <> <> <> BS: CHAR = Ascii.BS; -- '\b TAB: CHAR = Ascii.TAB; -- '\t LF: CHAR = Ascii.LF; -- '\l FF: CHAR = Ascii.FF; -- '\f CR: CHAR = Ascii.CR; -- '\n NUL: CHAR = Ascii.NUL; ControlA: CHAR = Ascii.ControlA; BEL: CHAR = Ascii.BEL; ControlX: CHAR = Ascii.ControlX; ESC: CHAR = Ascii.ESC; SP: CHAR = Ascii.SP; DEL: CHAR = Ascii.DEL; <> <> <<>> CreateStreamProcs: PROC [ variety: StreamVariety, class: ATOM, getChar: PROC [self: STREAM] RETURNS[CHAR] _ NIL, getBlock: PROC [self: STREAM, block: REF TEXT, startIndex: NAT, count: NAT] RETURNS [nBytesRead: NAT] _ NIL, unsafeGetBlock: UNSAFE PROC [self: STREAM, block: UnsafeBlock] RETURNS [nBytesRead: INT] _ NIL, endOf: PROC [self: STREAM] RETURNS [BOOL] _ NIL, charsAvail: PROC [self: STREAM, wait: BOOL] RETURNS [INT] _ NIL, backup: PROC [self: STREAM, char: CHAR] _ NIL, putChar: PROC [self: STREAM, char: CHAR] _ NIL, putBlock: PROC [self: STREAM, block: REF READONLY TEXT, startIndex: NAT, count: NAT] _ NIL, unsafePutBlock: PROC [self: STREAM, block: UnsafeBlock] _ NIL, flush: PROC [self: STREAM] _ NIL, reset: PROC [self: STREAM] _ NIL, close: PROC [self: STREAM, abort: BOOL _ FALSE] _ NIL, getIndex: PROC [self: STREAM] RETURNS [INT] _ NIL, setIndex: PROC [self: STREAM, index: INT] _ NIL, getLength: PROC [self: STREAM] RETURNS [length: INT] _ NIL, setLength: PROC [self: STREAM, length: INT] _ NIL, eraseChar: PROC [self: STREAM, char: CHAR] _ NIL ] RETURNS [REF StreamProcs]; CreateStream: PROC [streamProcs: REF StreamProcs, streamData: REF ANY, backingStream: STREAM _ NIL] RETURNS [stream: STREAM]; <> STREAMRecord: TYPE = RECORD[ streamProcs: REF StreamProcs, -- the stream procedures streamData: REF ANY, -- instance data, type is specific to the stream class propList: Atom.PropList _ NIL, -- instance data, type is independent of the stream class backingStream: STREAM _ NIL -- distinguished instance data, used to "layer" streams ]; StreamProcs: TYPE = PRIVATE RECORD[ getChar: PROC [self: STREAM] RETURNS [CHAR], endOf: PROC [self: STREAM] RETURNS [BOOL], charsAvail: PROC [self: STREAM, wait: BOOL] RETURNS [INT], getBlock: PROC [self: STREAM, block: REF TEXT, startIndex: NAT, count: NAT] RETURNS [nBytesRead: NAT], unsafeGetBlock: UNSAFE PROC [self: STREAM, block: UnsafeBlock] RETURNS [nBytesRead: INT], backup: PROC [self: STREAM, char: CHAR], putChar: PROC [self: STREAM, char: CHAR], putBlock: PROC [self: STREAM, block: REF READONLY TEXT, startIndex: NAT, count: NAT], unsafePutBlock: PROC [self: STREAM, block: UnsafeBlock], flush: PROC [self: STREAM], reset: PROC [self: STREAM], close: PROC [self: STREAM, abort: BOOL], getIndex: PROC [self: STREAM] RETURNS [INT], setIndex: PROC [self: STREAM, index: INT], propList: Atom.PropList, variety: StreamVariety, class: ATOM ]; Value: TYPE = RECORD [ SELECT type: ValueType FROM null => NULL, atom => [value: ATOM], boolean => [value: BOOL], character => [value: CHAR], cardinal => [value: LONG CARDINAL], integer => [value: INT], real => [value: REAL], refAny => [value: REF READONLY ANY], rope => [value: ROPE], text => [value: REF READONLY TEXT], time => [value: BasicTime.GMT], ENDCASE ]; ValueType: TYPE = {null, atom, boolean, character, cardinal, integer, real, refAny, rope, text, time}; END.