TDLexingImpl.mesa
Mike Spreitzer January 22, 1987 9:56:25 pm PST
DIRECTORY Atom, SymTab, IO, Rope, TDLexing;
TDLexingImpl: CEDAR PROGRAM
IMPORTS Atom, SymTab, IO, Rope
EXPORTS TDLexing
=
BEGIN OPEN TDLexing;
SyntaxError: PUBLIC ERROR = CODE;
MakeLexer: PUBLIC PROC [in: IO.STREAM, GetIndex: IndexGetter ← NIL--means VanillaIndexGetter--, filterComments: BOOLTRUE] RETURNS [l: Lexer] = {
IF GetIndex = NIL THEN GetIndex ← VanillaIndexGetter;
l ← NEW [LexerPrivate ← [in, filterComments, GetIndex]];
l.afterLast ← l.GetIndex[l.in];
[] ← l.in.SkipWhitespace[l.filterComments];
l.beforeNext ← l.GetIndex[l.in];
};
VanillaIndexGetter: PUBLIC PROC [in: IO.STREAM] RETURNS [index: INT] --IndexGetter-- = {
index ← in.GetIndex[];
};
GetToken: PUBLIC PROC [l: Lexer] RETURNS [token: Token] = {
IF l.tokenStack # NIL THEN {
token ← l.tokenStack.first;
l.afterLast ← token.after;
l.tokenStack ← l.tokenStack.rest;
l.beforeNext ← IF l.tokenStack # NIL THEN l.tokenStack.first.before ELSE l.GetIndex[l.in];
RETURN};
token.afterPrev ← l.afterLast;
token.before ← l.beforeNext;
IF l.in.EndOf[] THEN {
token.kind ← tokenEOF;
token.rope ← NIL;
token.after ← token.before;
RETURN};
[token.kind, token.rope] ← l.in.GetCedarTokenRope[l.filterComments];
token.after ← l.afterLast ← l.GetIndex[l.in];
[] ← l.in.SkipWhitespace[l.filterComments];
l.beforeNext ← l.GetIndex[l.in];
};
GetPosition: PUBLIC PROC [l: Lexer, side: WhichPosition] RETURNS [position: INT] = {
position ← SELECT side FROM
afterLast => l.afterLast,
beforeNext => l.beforeNext,
ENDCASE => ERROR;
};
ReturnToken: PUBLIC PROC [l: Lexer, token: Token] = {
l.tokenStack ← CONS[token, l.tokenStack];
l.afterLast ← token.afterPrev;
l.beforeNext ← token.before;
};
GetRope: PUBLIC PROC [l: Lexer, kind: IO.TokenKind] RETURNS [rope: ROPE] = {
toke: Token = GetToken[l];
IF toke.kind # kind THEN SyntaxError[];
rope ← toke.rope};
GetKwd: PUBLIC PROC [l: Lexer] RETURNS [kwd: ATOM] = {
kwd ← Atom.MakeAtom[GetRope[l, tokenID]];
};
NextIs: PUBLIC PROC [l: Lexer, rope: ROPE] RETURNS [is: BOOL] = {
toke: Token = GetToken[l];
is ← toke.rope.Equal[rope];
IF NOT is THEN ReturnToken[l, toke];
};
NextIsSeq: PUBLIC PROC [l: Lexer, seq: ROPEList] RETURNS [is: BOOL] = {
IF seq = NIL THEN RETURN [TRUE];
{token: Token = GetToken[l];
is ← token.rope.Equal[seq.first] AND NextIsSeq[l, seq.rest];
IF NOT is THEN ReturnToken[l, token];
}};
NextIsA: PUBLIC PROC [l: Lexer, ropes: ROPEList] RETURNS [is: BOOL] = {
toke: Token = GetToken[l];
is ← FALSE;
FOR ropes ← ropes, ropes.rest WHILE ropes # NIL AND NOT is DO
IF ropes.first.Equal[toke.rope] THEN is ← TRUE;
ENDLOOP;
IF NOT is THEN ReturnToken[l, toke];
};
SkipTo: PUBLIC PROC [l: Lexer, oneOf: ROPEList] = {
DO
toke: Token = GetToken[l];
IF toke.kind = tokenEOF THEN SyntaxError[];
FOR ropes: ROPEList ← oneOf, ropes.rest WHILE ropes # NIL DO
IF ropes.first.Equal[toke.rope] THEN {
ReturnToken[l, toke];
RETURN;
};
ENDLOOP;
l ← l;
ENDLOOP;
};
ReservedWord: PUBLIC PROC [id: ROPE] RETURNS [reserved: BOOL] = {
reserved ← reservedWords.Fetch[id].found;
};
PredefinedType: PUBLIC PROC [id: ROPE] RETURNS [is: BOOL] = {
is ← predefinedTypes.Fetch[id].found;
};
reservedWords: SymTab.Ref ← SymTab.Create[case: TRUE];
predefinedTypes: SymTab.Ref ← SymTab.Create[case: TRUE];
LoadIds: PROC [table: SymTab.Ref, list: ROPEList] = {
table.Erase[];
FOR list ← list, list.rest WHILE list # NIL DO
[] ← table.Insert[list.first, $T];
ENDLOOP;
list ← list;
};
Start: PROC = {
LoadIds[reservedWords, LIST["ABS", "ALL", "AND", "ANY", "APPLY", "ARRAY", "BASE", "BEGIN", "BROADCAST", "CEDAR", "CHECKED", "CODE", "COMPUTED", "CONS", "CONTINUE", "DECREASING", "DEFINITIONS", "DEPENDENT", "DESCRIPTOR", "DIRECTORY", "DO", "ELSE", "ENABLE", "END", "ENDCASE", "ENDLOOP", "ENTRY", "ERROR", "EXIT", "EXITS", "EXPORTS", "FINISHED", "FIRST", "FOR", "FORK", "FRAME", "FREE", "FROM", "GO", "GOTO", "IF", "IMPORTS", "IN", "INLINE", "INTERNAL", "ISTYPE", "JOIN", "LAST", "LENGTH", "LIST", "LOCKS", "LONG", "LOOP", "LOOPHOLE", "MACHINE", "MAX", "MIN", "MOD", "MONITOR", "MONITORED", "NARROW", "NEW", "NIL", "NOT", "NOTIFY", "NULL", "OF", "OPEN", "OR", "ORD", "ORDERED", "OVERLAID", "PACKED", "PAINTED", "POINTER", "PORT", "PRED", "PRIVATE", "PROC", "PROCEDURE", "PROCESS", "PROGRAM", "PUBLIC", "READONLY", "RECORD", "REF", "REJECT", "RELATIVE", "REPEAT", "RESTART", "RESUME", "RETRY", "RETURN", "RETURNS", "SAFE", "SELECT", "SEQUENCE", "SHARES", "SIGNAL", "SIZE", "START", "STATE", "STOP", "SUCC", "THEN", "THROUGH", "TO", "TRANSFER", "TRASH", "TRUSTED", "TYPE", "UNCHECKED", "UNCOUNTED", "UNSAFE", "UNTIL", "USING", "VAL", "VAR", "WAIT", "WHILE", "WITH", "ZONE"]];
LoadIds[predefinedTypes, LIST["ATOM", "BOOL", "BOOLEAN", "CARD", "CARDINAL", "CHAR", "INT", "INTEGER", "NAT", "REAL", "TEXT", "UNSPECIFIED", "WORD"]];
};
Start[];
END.