// Parsing Logic /////////////////////////////////////////////////////////
- /** the label for the current statement */
- private String label = null;
-
/** gets a token and throws an exception if it is not <tt>code</tt> */
public void consume(int code) throws IOException {
if (getToken() != code)
throw new ParserException("expected " + codeToString[code] + ", got " + (op == -1 ? "EOF" : codeToString[op]));
}
- /** append the largest expression beginning with prefix containing no operators of precedence below <tt>minPrecedence</tt> */
- public void startExpr(CompiledFunction block) throws IOException { startExpr(-1, block); }
- /*
- public CompiledFunction startExpr(int minPrecedence) throws IOException {
- CompiledFunction ret = new CompiledFunction(line, sourceName);
- startExpr(minPrecedence, ret);
- return ret.size() == 0 ? null : ret;
- }
- */
-
+ /** append the largest possible expression containing no operators of precedence below <tt>minPrecedence</tt> */
public void startExpr(int minPrecedence, CompiledFunction appendTo) throws IOException {
int tok = getToken();
- int line = this.line;
CompiledFunction b = appendTo;
+
switch (tok) {
case -1: return;
case NUMBER: continueExpr(b.add(line, CompiledFunction.LITERAL, number), minPrecedence); return;
int i = 0;
while(true) {
int size = b.size();
- startExpr(b);
+ startExpr(-1, b);
if (size == b.size())
if (peekToken() == RB) { consume(RB); continueExpr(b, minPrecedence); return; }
b.add(line, LITERAL, new Integer(i++));
return;
}
case LP: {
- startExpr(b);
+ startExpr(-1, b);
consume(RP);
continueExpr(b, minPrecedence);
return;
getToken();
b.add(line, LITERAL, string);
consume(COLON);
- startExpr(b);
+ startExpr(-1, b);
b.add(line, PUT);
b.add(line, POP);
if (peekToken() == RC) break;
int i = 0;
while(peekToken() != RP) {
i++;
- startExpr(b);
+ startExpr(-1, b);
if (peekToken() == RP) break;
consume(COMMA);
}
if (peekToken() == ASSIGN) {
consume(ASSIGN);
b.add(line, LITERAL, target);
- startExpr(b);
+ startExpr(-1, b);
b.add(line, PUT);
b.add(line, SWAP);
b.add(line, POP);
}
case LB: {
- startExpr(b);
+ startExpr(-1, b);
consume(RB);
if (peekToken() == ASSIGN) {
consume(ASSIGN);
- startExpr(b);
+ startExpr(-1, b);
b.add(line, PUT);
b.add(line, SWAP);
b.add(line, POP);
case HOOK: {
b.add(line, JF, new Integer(0));
int size = b.size();
- startExpr(b);
+ startExpr(-1, b);
b.set(size - 1, new Integer(b.size() - size + 2));
b.add(line, JMP, new Integer(0));
consume(COLON);
size = b.size();
- startExpr(b);
+ startExpr(-1, b);
b.set(size - 1, new Integer(b.size() - size + 1));
continueExpr(b, minPrecedence);
return;
return ret;
}
- public void parseStatement(boolean requireBraces, CompiledFunction b) throws IOException {
+ public void parseStatement(boolean r, CompiledFunction b) throws IOException { parseStatement(r, b, null); }
+ public void parseStatement(boolean requireBraces, CompiledFunction b, String label) throws IOException {
int tok = peekToken();
if (tok == -1) return;
int line = this.line;
case THROW: case RETURN: case ASSERT: {
getToken();
if (tok == RETURN && peekToken() == SEMI) b.add(line, LITERAL, null);
- else startExpr(b);
+ else startExpr(-1, b);
consume(SEMI);
b.add(line, tok);
break;
if (peekToken() == ASSIGN) { // if there is an '=' after the variable name
b.add(line, LITERAL, name); // put the var name back on the stack
consume(ASSIGN);
- startExpr(b);
+ startExpr(-1, b);
b.add(line, PUT);
b.add(line, POP);
}
case IF: {
consume(IF);
consume(LP);
- startExpr(b);
+ startExpr(-1, b);
consume(RP);
b.add(line, JF, new Integer(0));
b.add(line, LOOP);
int size = b.size();
b.add(line, POP);
- startExpr(b);
+ startExpr(-1, b);
b.add(line, JT, new Integer(2));
b.add(line, BREAK);
consume(RP);
if (label != null) b.add(line, LABEL, label);
b.add(line, LOOP);
int size0 = b.size();
- startExpr(b);
+ startExpr(-1, b);
consume(RP);
consume(LC);
while(true)
if (peekToken() == CASE) {
consume(CASE);
b.add(line, DUP);
- startExpr(b);
+ startExpr(-1, b);
consume(COLON);
b.add(line, EQ);
b.add(line, JF, new Integer(0));
parseStatement(false, b);
consume(WHILE);
consume(LP);
- startExpr(b);
+ startExpr(-1, b);
b.add(line, JT, new Integer(2));
b.add(line, BREAK);
b.add(line, CONTINUE);
// FIXME: break needs to work in here
consume(NAME);
consume(IN);
- startExpr(b);
+ startExpr(-1, b);
b.add(line, PUSHKEYS);
b.add(line, LITERAL, "length");
b.add(line, GET);
parseStatement(false, b);
CompiledFunction e2 = new CompiledFunction(sourceName, line, null);
- startExpr(e2);
+ startExpr(-1, e2);
consume(SEMI);
if (e2 == null) e2 = new CompiledFunction(sourceName, line, null).add(line, b.LITERAL, Boolean.TRUE);
b.add(line, JT, new Integer(0));
int size = b.size();
- startExpr(b);
+ startExpr(-1, b);
if (b.size() > size) b.add(line, POP);
b.set(size - 1, new Integer(b.size() - size + 1));
consume(RP);
case NAME: {
consume(NAME);
- String oldlabel = label;
- label = string;
+ String possiblyTheLabel = string;
if (peekToken() == COLON) {
consume(COLON);
- parseStatement(false, b);
- label = oldlabel;
+ label = possiblyTheLabel;
+ System.out.println("label == " + label);
+ parseStatement(false, b, label);
break;
} else {
- pushBackToken(NAME, label);
- label = oldlabel;
+ pushBackToken(NAME, possiblyTheLabel);
// fall through to default case
}
}
// fall through
default: {
int size = b.size();
- startExpr(b);
+ startExpr(-1, b);
if (size == b.size()) return;
b.add(line, POP);
if (peekToken() == SEMI) consume(SEMI);