IPXeroxImpl.mesa
Copyright © 1984 Xerox Corporation. All rights reserved.
Doug Wyatt, November 10, 1984 7:01:43 pm PST
DIRECTORY
Basics USING [BYTE, HighHalf, LowHalf],
IO USING [GetChar, PutChar, STREAM],
IPXerox USING [EncodingValue, SequenceType, ShortEncodingValue, ShortNumber, Token];
IPXeroxImpl: CEDAR PROGRAM
IMPORTS Basics, IO
EXPORTS IPXerox
~ BEGIN OPEN IPXerox;
STREAM: TYPE ~ IO.STREAM;
BYTE: TYPE ~ Basics.BYTE;
PutByte: PROC[stream: STREAM, byte: BYTE] ~ INLINE {
IO.PutChar[stream, VAL[byte]]
};
PutToken: PUBLIC PROC[stream: STREAM, token: Token] ~ {
WITH token: token SELECT FROM
shortNumber => {
x: [0..77777B] ~ token.number-ShortNumber.FIRST;
PutByte[stream, x/400B];
PutByte[stream, x MOD 400B];
};
shortOp => {
PutByte[stream, 200B+ORD[token.op]];
};
longOp => {
x: [0..17777B] ~ ORD[token.op];
PutByte[stream, 240B+x/400B];
PutByte[stream, x MOD 400B];
};
shortSequence => {
PutByte[stream, 300B+ORD[token.type]];
PutByte[stream, token.length];
};
longSequence => {
highByte: BYTE ~ Basics.HighHalf[token.length]; -- this does the bounds check
lowWord: CARDINAL ~ Basics.LowHalf[token.length];
PutByte[stream, 340B+ORD[token.type]];
PutByte[stream, highByte];
PutByte[stream, lowWord/400B];
PutByte[stream, lowWord MOD 400B];
};
ENDCASE => ERROR;
};
GetByte: PROC[stream: STREAM] RETURNS[BYTE] ~ INLINE {
RETURN[ORD[CHAR[IO.GetChar[stream]]]]
};
GetToken: PUBLIC PROC[stream: STREAM] RETURNS[Token] ~ {
b: BYTE ~ GetByte[stream];
SELECT b FROM
<200B => RETURN[[shortNumber[b*400B+GetByte[stream]+ShortNumber.FIRST]]];
<240B => RETURN[[shortOp[VAL[b MOD 40B]]]];
<300B => RETURN[[longOp[VAL[(b MOD 40B)*400B+GetByte[stream]]]]];
<340B => RETURN[[shortSequence[type: VAL[b MOD 40B], length: GetByte[stream]]]];
<400B => {
length: INT ← GetByte[stream];
length ← length*400B+GetByte[stream];
length ← length*400B+GetByte[stream];
RETURN[[longSequence[type: VAL[b MOD 40B], length: length]]];
};
ENDCASE => ERROR;
};
END.