IPMaster.mesa
Token-level interface for reading an encoded Interpress master
Last edited by:
Doug Wyatt, March 1, 1984 9:49:46 am PST
DIRECTORY
IO USING [STREAM],
IP USING [Block, Identifier, Op, Vector],
Rope USING [ROPE];
IPMaster: CEDAR DEFINITIONS
~ BEGIN OPEN IP;
Types and Errors
ROPE: TYPE ~ Rope.ROPE;
STREAM: TYPE ~ IO.STREAM;
Rational: TYPE ~ RECORD[SELECT tag: * FROM
int => [num, den: INT], real => [num, den: REAL], ENDCASE];
ErrorCode: TYPE ~ {
ok, -- initial value for an ErrorCode
bug, -- implementation bug
unimplemented, -- operation not currently implemented
unknownEncoding, -- the requested encoding is not implemented
illegalHeader, -- invalid header for an Interpress master
illegalToken, -- a token is malformed
illegalIdentifier, -- illegal character in an Identifier
illegalStructure, -- the skeleton of the master is malformed
endOfFile, -- end of file encountered inside a token
overflow, -- overflow in a numeric conversion
illegalArgument -- invalid argument for an operation
};
Error: ERROR[code: ErrorCode, explanation: ROPENIL];
Reading a master
TokenType: TYPE ~ {
nil,
op, -- value is token.op
shortNumber, -- value is reader.shortNumber
integer, -- use ReadInt or ReadReal
rational, -- use ReadRational or ReadReal
real, -- use ReadReal
identifier, -- value is reader.text; use ReadRope or ReadIdentifier
string, -- value is reader.text
vector, -- use ReadVector
insertfile, -- value is reader.text
comment, -- value is reader.text
annotation, -- value is reader.text
eof -- end of file
};
Token: TYPE ~ RECORD[type: TokenType, op: Op];
nullToken: Token ~ [type: $nil, op: $nil];
Reader: TYPE ~ REF ReaderRep;
ReaderRep: TYPE ~ RECORD[
procs: ReaderProcs,
stream: STREAM, -- input stream on the master
index: INT, -- stream index of most recently scanned token
token: Token, -- token type
shortNumber: INTEGER, -- short number value for token
text: REF TEXT, -- text for token
length: INT ← 0, -- sequence data length (used by Xerox encoding)
buffer: REF TEXT -- scratch text buffer
];
ReaderProcs: TYPE ~ REF ReaderProcsRep;
ReaderProcsRep: TYPE ~ RECORD[
getToken: PROC[reader: Reader, flushComments: BOOLTRUE],
readInt: PROC[reader: Reader] RETURNS[INT],
readRational: PROC[reader: Reader] RETURNS[Rational],
readReal: PROC[reader: Reader] RETURNS[REAL],
readVector: PROC[reader: Reader] RETURNS[Vector],
finishBody: PROC[reader: Reader] ← NIL
];
CreateReader: PROC[stream: STREAM, encodingName: ROPE, encodingVersion: Version]
RETURNS[Reader];
Create a Reader for the given stream. Starts reading at the current stream index.
OpenReader: PROC[name: ROPE] RETURNS[Reader];
Open the named file, parse the header to determine the encoding type, and return a Reader.
CloseReader: PROC[reader: Reader];
Close the reader's stream and prevent further calls on the reader.
GetIndex: PROC[reader: Reader] RETURNS[INT];
SetIndex: PROC[reader: Reader, index: INT];
GetToken: PROC[reader: Reader, flushComments: BOOLTRUE]
~ INLINE { reader.procs.getToken[reader, flushComments] };
ReadInt: PROC[reader: Reader] RETURNS[INT];
ReadRational: PROC[reader: Reader] RETURNS[Rational];
ReadReal: PROC[reader: Reader] RETURNS[REAL];
ReadIdentifier: PROC[reader: Reader] RETURNS[Identifier];
ReadVector: PROC[reader: Reader] RETURNS[Vector];
ReadRope: PROC[reader: Reader] RETURNS[ROPE];
FinishBody: PROC[reader: Reader];
GetSkeleton: PROC[reader: Reader] RETURNS[Block];
Writing a master
Writer: TYPE ~ REF WriterRep;
WriterRep: TYPE ~ RECORD[procs: WriterProcs, stream: STREAM];
WriterProcs: TYPE ~ REF WriterProcsRep;
WriterProcsRep: TYPE ~ RECORD[
putOp: PROC[writer: Writer, op: Op],
putInt: PROC[writer: Writer, value: INT],
putReal: PROC[writer: Writer, value: REAL],
putRational: PROC[writer: Writer, value: Rational],
putIdentifier: PROC[writer: Writer, rope: ROPE],
putString: PROC[writer: Writer, rope: ROPE],
putVector: PROC[writer: Writer, vector: Vector] ← NIL,
putInsertfile: PROC[writer: Writer, rope: ROPE],
putComment: PROC[writer: Writer, rope: ROPE],
putAnnotation: PROC[writer: Writer, rope: ROPE]
];
CreateWriter: PROC[stream: STREAM,
encodingName: ROPE, encodingVersion: Version] RETURNS[Writer];
Create a Writer for the given stream.
OpenWriter: PROC[name: ROPE,
encodingName: ROPE, encodingVersion: Version] RETURNS[Writer];
Create the named file, write a header for the specified encoding, and return a Writer.
CloseWriter: PROC[writer: Writer];
Close the writer's stream and prevent further calls on the writer.
PutOp: PROC[writer: Writer, op: Op]
~ INLINE { writer.procs.putOp[writer, op] };
PutInt: PROC[writer: Writer, value: INT]
~ INLINE { writer.procs.putInt[writer, value] };
PutReal: PROC[writer: Writer, value: REAL]
~ INLINE { writer.procs.putReal[writer, value] };
PutRational: PROC[writer: Writer, value: Rational]
~ INLINE { writer.procs.putRational[writer, value] };
PutIdentifier: PROC[writer: Writer, rope: ROPE]
~ INLINE { writer.procs.putIdentifier[writer, rope] };
PutString: PROC[writer: Writer, rope: ROPE]
~ INLINE { writer.procs.putString[writer, rope] };
PutVector: PROC[writer: Writer, vector: Vector]
~ INLINE { writer.procs.putVector[writer, vector] };
PutComment: PROC[writer: Writer, rope: ROPE]
~ INLINE { writer.procs.putComment[writer, rope] };
PutAnnotation: PROC[writer: Writer, rope: ROPE]
~ INLINE { writer.procs.putAnnotation[writer, rope] };
PutInsertfile: PROC[writer: Writer, rope: ROPE]
~ INLINE { writer.procs.putInsertfile[writer, rope] };
Registering an encoding type
Version: TYPE ~ RECORD[major, minor: CARDINAL];
RegisterEncoding: PROC[name: ROPE, version: Version,
readerProcs: ReaderProcs, writerProcs: WriterProcs];
END.