sclass SimpleLeftToRightParser { settable S text; LS tok; ListAndIndex ptr, mainLoopPtr; S currentToken; bool caseInsensitive; new L warnings; *() {} *(S *text) {} *(LS *tok) {} S t aka token() { ret currentToken; } S token(int i) { ret get(tok, ptr.idx()+i*2); } S tpp() { var t = t(); next(); ret t; } S lastSpace() { ret get(tok, ptr.idx()-1); } bool is(S t) { ret eqOrEqic(caseInsensitive, currentToken, t); } bool was(S t) { ret eqOrEqic(caseInsensitive, token(-1), t); } meta-for isInteger also as isIdentifier { bool isInteger() { ret isInteger(t()); } bool isInteger(S s) { ret main isInteger(s); } } void next { if (!endOfText()) ptr(ptr.plus(2)); } void ptr(ListAndIndex ptr) { this.ptr = ptr; fetch(); } int idx() { ret ptr.idx(); } bool atEnd aka endOfText() { ret ptr.atEnd(); } void fetch { currentToken = ptr!; } bool lineBreak() { ret containsLineBreak(get(tok, ptr.idx()-1)); } bool atEndOrLineBreak() { ret atEnd() || lineBreak(); } void init { tok if null = javaTok(text); if (ptr == null) ptr(ListAndIndex(tok, 1)); } bool mainLoop() { init(); if (atEnd()) false; if (eq(mainLoopPtr, ptr)) fail("main loop didn't advance (current token: " + quote(token()) + ")"); mainLoopPtr = ptr; true; } void unknownToken { warn("Unknown token: " + t()); } void warn(S msg) { warnings.add(print(msg)); } void next(int n) { ptr(ptr.idx()+n*2); } // if i points to an N token, it is incremented void ptr(int i) { ptr(ListAndIndex(tok, min(i | 1, l(tok)))); } LineAndColumn lineAndColumn() { ret tokenToLineAndColumn(ptr); } }