TokenIO.mesa
Copyright © 1983, 1984, 1986 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, August 24, 1983 3:10 pm
Last edited by: Christian Jacobi, October 28, 1986 6:31:00 pm PST
DIRECTORY
IO, Properties, Rope;
TokenIO: CEDAR DEFINITIONS =
BEGIN
Input output in tokenized form. Allows grouping of tokens to clusters with a push and a popflag. No monitoring is provided.
All procedures may raise ERROR Stopped
All input procedures may raise "ERROR" EncodingError
The routines may generate standard IO signals and errors, however:
most input errors are mapped into raising EncodingError.
Stopped:
ERROR;
-- Raised if any process calls Stop
EncodingError:
SIGNAL;
-- All read procedures SIGNAL EncodingError if read token is not as expected;
-- for emergeny error bypassing or debugging, the state may be changed in
-- the debugger and the computation continued; however, normal computation
-- considers EncodingError to be an ERROR, not a SIGNAL.
--
-- The read routines do not have changed the state of the input stream.
Handle: TYPE = REF HandleRec;
HandleRec:
TYPE =
--READONLY--
RECORD [
stop: REF BOOL ←, --never NIL; stop^ is not considered READONLY
--private implementor fields which need to be fast
s: PRIVATE IO.STREAM ← NIL, --reserved for the implementor
funny: PRIVATE BOOL ← FALSE, --reserved for the implementor
imp: PRIVATE REF ImpRec ← NIL, --reserved for the implementor
--client fields
stream: IO.STREAM ← NIL, --for clients, but not automatically initialized
clientKey: REF ← NIL, --for clients; represents a key put on properties
clientData: REF ← NIL, --for clients; represents context
oldVersion: BOOL ← FALSE, --for client: client may switch it to true only
truth: --readonly-- BOOL ← TRUE, --for client: truth/versus cache
properties: REF Properties.PropList ← NIL --don't PutProp from forked processes
]; --[certain features to speed up ChipNDale's io only]
Mark: TYPE = REF;
ImpRec: TYPE;
Write: PROC [h: Handle, t: Token];
WritePush: PROC [h: Handle, a: ATOM];
WritePush2: PROC [h: Handle, a: ATOM];
WritePop: PROC [h: Handle];
WriteAtom: PROC [h: Handle, a: ATOM];
WriteRope: PROC [h: Handle, r: Rope.ROPE];
WriteInt: PROC [h: Handle, i: INT];
WriteReal: PROC [h: Handle, r: REAL];
WriteStream:
PROC [h: Handle]
RETURNS [s:
IO.
STREAM];
-- Next writes can be in stream mode
-- Usage of any other write procs finishes stream mode and switches back to token mode
-- Returns always same stream h.stream for same handle !
-- Do not close, do not use random access
MarkAndWriteInt:
PROC [h: Handle, value:
INT←-1]
RETURNS [Mark];
-- WriteInt and remembers position for later updates
UpdateMark:
PROC [h: Handle, mark: Mark, value:
INT];
-- Updates value of integer written before
TType: TYPE = {push, push2, pop, atom, rope, int, real, streamed, endOfStream, error};
Token:
TYPE =
RECORD [
SELECT type: TType
FROM
push => [value: ATOM],
push2 => [value: ATOM],
pop => [value: ATOM],
atom => [value: ATOM],
rope => [value: Rope.ROPE],
int => [value: INT],
real => [value: REAL],
streamed => [value: REF],
endOfStream => [],
error => [value: REF],
ENDCASE
];
Read: PROC [h: Handle] RETURNS [Token];
ReadAgain:
PROC [h: Handle, t: Token];
--Causes next call of Read to get t
--Do not use in stream mode except before any real input from stream
ReadInt: PROC [h: Handle] RETURNS [INT];
ReadAtom: PROC [h: Handle] RETURNS [ATOM];
ReadRope: PROC [h: Handle] RETURNS [Rope.ROPE];
ReadReal: PROC [h: Handle] RETURNS [REAL];
ReadPush: PROC [h: Handle] RETURNS [ATOM];
ReadPush2: PROC [h: Handle] RETURNS [ATOM];
ReadPop: PROC [h: Handle];
ReadStream:
PROC [h: Handle]
RETURNS [s:
IO.STREAM];
--Next reads can use stream
--Returns always the same read stream h.stream for the same handle
--Do not close, do not use random access
--It is not possible to read from stream anything which was not written in stream mode
Skip:
PROC [h: Handle];
--if the next token is a pop: no-op
--if the next token is not a pop
-- skips forward on the stream until the next pop is read
-- pairs of push and pop: calls the catcher;
-- pairs of push2 and pop are skipped.
--In stream mode: skips started stream
--Attaching TokenIO to STREAMS
-- while TokenIO is attached to a stream no other operations on this stream must occur
-- otherwise, TokenIO might not be able to read back the clobbered stream.
CreateReader:
PROC [stream:
IO.
STREAM, stop:
REF
BOOL←
NIL, catcher:
PROC [Handle]←
NIL]
RETURNS [Handle];
--EncodingError if stream was not written and closed with TokenIO
--stop: set stop^ to TRUE to stop the reading
--catcher: called implicitely by Skip
CreateWriter:
PROC [stream:
IO.
STREAM, stop:
REF
BOOL←
NIL, truth:
BOOL ←
TRUE]
RETURNS [Handle];
--EncodingError if stream does not provide random access
--stop: set stop^ to TRUE to stop the writing
Close:
PROC [h: Handle, closeStream:
BOOL←
TRUE];
--Closes TokenIO stream
--closeStream: implicit call of IO.Close
--Calling Close is not necessary if writing is supposed to fail
END.