IPReader.mesa
Copyright © 1984 Xerox Corporation. All rights reserved.
Doug Wyatt, August 24, 1984 10:43:47 am PDT
Token-level interface for reading encoded Interpress masters
DIRECTORY
IO USING [STREAM],
IPBasic USING [Op, Rational, Version, XeroxPixelVectorType],
Rope USING [ROPE];
IPReader: CEDAR DEFINITIONS
~ BEGIN
ROPE: TYPE ~ Rope.ROPE;
STREAM: TYPE ~ IO.STREAM;
Op: TYPE ~ IPBasic.Op;
Rational: TYPE ~ IPBasic.Rational;
Version: TYPE ~ IPBasic.Version;
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
illegalStructure, -- the skeleton of the master is malformed
illegalToken, -- a token is malformed
wrongType, -- token to be parsed has the wrong type
overflow, -- numeric overflow while trying to parse a number
closed -- tried to operate on a closed reader
};
Error:
ERROR[code: ErrorCode, explanation:
ROPE ←
NIL];
Index: TYPE ~ INT; -- a byte position in the master
nullIndex: Index ~ -1;
TokenType:
TYPE ~ {
nil,
op, -- value is token.op
shortNumber, -- value is token.shortNumber
integer, -- use ReadInt or ReadReal
rational, -- use ReadRational or ReadReal
real, -- use ReadReal
identifier, -- value is token text
string, -- value is token text (uses Xerox Character Code Standard encoding)
insertfile, -- value is token text
comment, -- value is token text
annotation, -- value is token text
largeVector, -- use ReadLargeVector
eof -- end of file
};
Token:
TYPE ~
RECORD[
type: TokenType,
op: Op,
shortNumber: INTEGER,
index: Index
];
nullToken: Token ~ [type: $nil, op: $nil, shortNumber: 0, index: 0];
LargeVector: TYPE ~ REF LargeVectorRep;
LargeVectorRep:
TYPE ~
RECORD[
source: STREAM,
bytesPerElement: [0..256),
type: IPBasic.XeroxPixelVectorType ← $nil
];
Reader: TYPE ~ REF ReaderRep;
ReaderRep:
TYPE ~
RECORD[
class: Class, -- procedures for reading the encoding
stream: STREAM, -- input stream on the master
buffer: REF TEXT -- scratch text buffer
];
Class: TYPE ~ REF ClassRep;
ClassRep:
TYPE ~
RECORD[
encoding: ATOM ←,
getToken:
PROC[reader: Reader, buffer:
REF
TEXT ←
NIL, flushComments:
BOOL ←
TRUE]
RETURNS[token: Token, text: REF TEXT] ←,
readInt: PROC[reader: Reader, token: Token, text: REF TEXT] RETURNS[INT] ←,
readRational: PROC[reader: Reader, token: Token, text: REF TEXT] RETURNS[Rational] ←,
readReal: PROC[reader: Reader, token: Token, text: REF TEXT] RETURNS[REAL] ←,
readLargeVector: PROC[reader: Reader, token: Token] RETURNS[LargeVector] ←,
finishBody: PROC[reader: Reader] ← NIL
];
Open:
PROC[name:
ROPE]
RETURNS[Reader];
Open the named file, parse the header to determine the encoding, and return a Reader.
Create:
PROC[stream:
STREAM, encoding:
ATOM, version: Version]
RETURNS[Reader];
Create a Reader for the given stream. Starts reading at the current stream index.
Close:
PROC[reader: Reader];
Close the reader's stream and prevent further calls on the reader.
GetIndex: PROC[reader: Reader] RETURNS[Index];
SetIndex:
PROC[reader: Reader, index: Index];
GetToken:
PROC[reader: Reader, buffer:
REF
TEXT ←
NIL, flushComments:
BOOL ←
TRUE]
RETURNS[token: Token, text: REF TEXT]
~ INLINE { RETURN reader.class.getToken[reader, buffer, flushComments] };
ReadInt:
PROC[reader: Reader, token: Token, text:
REF
TEXT]
RETURNS[
INT]
~ INLINE { RETURN reader.class.readInt[reader, token, text] };
ReadRational:
PROC[reader: Reader, token: Token, text:
REF
TEXT]
RETURNS[Rational]
~ INLINE { RETURN reader.class.readRational[reader, token, text] };
ReadReal:
PROC[reader: Reader, token: Token, text:
REF
TEXT]
RETURNS[
REAL]
~ INLINE { RETURN reader.class.readReal[reader, token, text] };
ReadLargeVector:
PROC[reader: Reader, token: Token]
RETURNS[LargeVector];
FinishBody:
PROC[reader: Reader];
StreamFromInputStream:
PROC[stream:
STREAM]
RETURNS[
STREAM];
Node: TYPE ~ REF NodeRep;
BodyNode: TYPE ~ REF NodeRep[body];
BlockNode: TYPE ~ REF NodeRep[block];
NodeRep:
TYPE ~
RECORD[
instructions: Index ← nullIndex, -- nullIndex if no instructions
content:
SELECT tag: *
FROM
body => [body: Index],
block => [block: Block],
ENDCASE
];
Block: TYPE ~ REF BlockRep;
BlockRep:
TYPE ~
RECORD[
noPages: BOOL,
preamble: Node,
nodes: SEQUENCE size: NAT OF Node
];
GetSkeleton:
PROC[reader: Reader]
RETURNS[Block];
Register: PROC[class: Class];
END.