SELECT char
FROM
'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm, 'n, 'o, 'p, 'q, 'r, 's, 't, 'u, 'v, 'w, 'x, 'y, 'z => {
i: CARDINAL ← 0;
DO
buffer[i] ← char;
IF (tI←tI+1) = tMax THEN FillBuffer[];
char ← tB[tI];
SELECT char
FROM
IN ['a..'z],
IN ['A..'Z],
IN ['0..'9] =>
IF (i ← i+1) >= iMax THEN ExpandBuffer[];
ENDCASE => EXIT;
ENDLOOP;
desc.length ← i+1;
class ← tokenID; value.r ← SymbolOps.EnterString[desc];
GO TO GotNext};
'A, 'B, 'C, 'D, 'E, 'F, 'G, 'H, 'I, 'J, 'K, 'L, 'M, 'N, 'O, 'P, 'Q, 'R, 'S, 'T, 'U, 'V, 'W, 'X, 'Y, 'Z => {
i: CARDINAL ← 0;
uId: BOOL ← TRUE;
first, last: NAT ← char.ORD;
DO
buffer[i] ← char;
IF (tI←tI+1) = tMax THEN FillBuffer[];
char ← tB[tI];
SELECT char
FROM
IN ['A..'Z] => {
last ← char.ORD; IF (i ← i+1) >= iMax THEN ExpandBuffer[]};
IN ['a..'z],
IN ['0..'9] => {
uId ← FALSE; IF (i ← i+1) >= iMax THEN ExpandBuffer[]};
ENDCASE => EXIT;
ENDLOOP;
i ← i+1;
IF uId
THEN {
h: HashIndex ← ((first*128-first) + last) MOD HashIndex.LAST + 1;
j, s1, s2: CARDINAL;
WHILE (j ← hashTab[h].symbol) # 0
DO
IF vocabIndex[j]-(s2←vocabIndex[j-1]) = i
THEN
FOR s1
IN [0 .. i)
DO
IF buffer[s1] # vocab.text[s2] THEN EXIT;
s2 ← s2+1;
REPEAT
FINISHED => {class ← j; GO TO GotNext};
ENDLOOP;
IF (h ← hashTab[h].link) = 0 THEN EXIT;
ENDLOOP};
desc.length ← i;
class ← tokenID; value.r ← SymbolOps.EnterString[desc];
GO TO GotNext};
'0, '1, '2, '3, '4, '5, '6, '7, '8, '9 => {
valid: BOOL;
[class, value, valid] ← CollectNumber[i~0];
IF ~valid THEN ScanError[$number, index];
GO TO GotNext};
',, ';, ':, '←, '#, '+, '*, '/, '^, '@, '!, '(, '), '[, '], '{, '} => {
class ← scanTab[char];
GO TO GetNext};
'' => {
c: CHAR;
valid, advance: BOOL;
NextChar[];
[c, valid, advance] ← Escape[];
IF ~valid THEN ScanError[$escape, index + 1];
class ← tokenCHAR; value.r ← LiteralOps.Find[c.ORD];
IF advance THEN GO TO GetNext ELSE GO TO GotNext};
'" => {
i: CARDINAL ← 0;
valid: BOOL;
advance: BOOL ← TRUE;
DO
IF advance
THEN
IF NextCharInline[] THEN GO TO EOFEnd;
SELECT char
FROM
'" => {
IF (tI←tI+1) = tMax THEN FillBuffer[];
char ← tB[tI];
IF char # '" THEN GO TO QuoteEnd};
ENDCASE;
IF i >= iMax
THEN ExpandBuffer[
! BufferOverflow => {ScanError[$string, index]; i ← 0; CONTINUE}];
[buffer[i], valid, advance] ← Escape[]; i ← i+1;
IF ~valid THEN ScanError[$escape, tOrigin + tI];
REPEAT
QuoteEnd => NULL;
EOFEnd => {ScanError[$string, index]; FillBuffer[]; char ← tB[tI]};
ENDLOOP;
desc.length ← i;
value.r ← LiteralOps.FindString[desc];
IF char = 'l OR char = 'L THEN {class ← tokenLSTR; GO TO GetNext}
ELSE {class ← tokenSTR; GO TO GotNext}};
'$, '\244 => {
note: 244c = ¤ in the Xerox Character Code standard
i: CARDINAL;
i ← 0; NextChar[];
SELECT char
FROM
IN ['a..'z], IN ['A..'Z] => NULL;
ENDCASE => ScanError[$atom, index];
DO
SELECT char
FROM
IN ['a..'z],
IN ['A..'Z],
IN ['0..'9] => {
IF i >= iMax THEN ExpandBuffer[]; buffer[i] ← char; i ← i+1};
ENDCASE => EXIT;
NextChar[];
ENDLOOP;
desc.length ← i;
class ← tokenATOM; value.r ← SymbolOps.EnterString[desc];
GO TO GotNext};
'- => {
NextChar[];
IF char # '- THEN {class ← tokenMINUS; GO TO GotNext};
char ← '\000;
DO
pChar: CHAR ~ char;
IF NextCharInline[] THEN GO TO EndFile;
SELECT char
FROM
'- => IF pChar = '- THEN EXIT;
'\n => EXIT;
ENDCASE;
ENDLOOP;
NextChar[]};
'. => {
IF qDot
THEN {
qDot ← FALSE; index ← index-1; class ← tokenDOTS; GO TO GetNext};
NextChar[];
SELECT char
FROM
'. => {class ← tokenDOTS; GO TO GetNext};
IN ['0..'9] => {
valid: BOOL;
buffer[0] ← '.;
[class, value, valid] ← CollectNumber[i~1, float~TRUE];
IF ~valid THEN ScanError[$number, index];
GO TO GotNext};
ENDCASE => {class ← tokenDOT; GO TO GotNext}};
'= => {
NextChar[];
IF char = '> THEN {class ← tokenARROW; GO TO GetNext}
ELSE {class ← tokenEQUAL; GO TO GotNext}};
'< => {
NextChar[];
SELECT char
FROM
'= => {class ← tokenLE; GO TO GetNext};
'< => GO TO ScanComment;
ENDCASE => {class ← tokenLESS; GO TO GotNext};
};
'> => {
NextChar[];
IF char = '= THEN {class ← tokenGE; GO TO GetNext}
ELSE {class ← tokenGREATER; GO TO GotNext}};
'~ => {
NextChar[];
SELECT char
FROM
'= => {class ← tokenNE; GO TO GetNext};
'< => {class ← tokenGE; GO TO GetNext};
'> => {class ← tokenLE; GO TO GetNext}
ENDCASE => {class ← tokenTILDE; GO TO GotNext}};
'\253 =>
GO
TO ScanComment;
« in the Xerox Character Code Standard
'\254 => {class ← scanTab['←];
GO
TO GetNext};
¬ in the Xerox Character Code Standard
'\255 => {class ← scanTab['^];
GO
TO GetNext};
in the Xerox Character Code Standard
'\264 => {class ← scanTab['*];
GO
TO GetNext};
´ in the Xerox Character Code Standard (multiplication)
'\270 => {class ← scanTab['/];
GO
TO GetNext};
¸ in the Xerox Character Code Standard (division)
ENDCASE => {
class ← scanTab[char];
IF class # 0 THEN GO TO GetNext;
NextChar[];
ScanError[$char, index];
};