}
/** append the largest expression beginning with prefix containing no operators of precedence below <tt>minPrecedence</tt> */
- public ByteCodeBlock startExpr() throws IOException { return startExpr(-1); }
public void startExpr(ByteCodeBlock block) throws IOException { startExpr(-1, block); }
+ /*
public ByteCodeBlock startExpr(int minPrecedence) throws IOException {
ByteCodeBlock ret = new ByteCodeBlock(line, sourceName);
startExpr(minPrecedence, ret);
return ret.size() == 0 ? null : ret;
}
+ */
public void startExpr(int minPrecedence, ByteCodeBlock appendTo) throws IOException {
int tok = getToken();
}
/** a block is either a single statement or a list of statements surrounded by curly braces; all expressions are also statements */
+
public ByteCodeBlock parseStatement() throws IOException {
ByteCodeBlock ret = new ByteCodeBlock(line, sourceName);
ret.add(ret.LITERAL, null);
return ret;
}
- public void parseStatement(boolean requireBraces) throws IOException {
- parseStatement(requireBraces, new ByteCodeBlock(line, sourceName));
- }
public void parseStatement(boolean requireBraces, ByteCodeBlock b) throws IOException {
int tok = peekToken();
if (tok == -1) return;
case WHILE: {
consume(WHILE);
consume(LP);
- ByteCodeBlock loop = newbb(curLine);
- b.add(LOOP, loop);
-
- loop.add(POP);
- startExpr(loop);
- loop.add(JT, new Integer(2));
- loop.add(BREAK);
+ b.add(LOOP);
+ int size = b.size();
+ b.add(POP);
+ startExpr(b);
+ b.add(JT, new Integer(2));
+ b.add(BREAK);
consume(RP);
- parseStatement(false, loop);
-
- // if we fall out of the end, definately continue
- loop.add(CONTINUE);
+ parseStatement(false, b);
+ b.add(CONTINUE); // if we fall out of the end, definately continue
+ b.set(size - 1, new Integer(b.size() - size + 1)); // end of the loop
break;
}
case SWITCH: {
consume(SWITCH);
consume(LP);
- ByteCodeBlock loop = newbb(curLine);
- b.add(LOOP, loop);
- startExpr(loop);
+ b.add(LOOP);
+ int size0 = b.size();
+ startExpr(b);
consume(RP);
consume(LC);
while(true)
if (peekToken() == CASE) {
consume(CASE);
- loop.add(DUP);
- startExpr(loop);
+ b.add(DUP);
+ startExpr(b);
consume(COLON);
- loop.add(EQ);
- loop.add(JF, new Integer(0));
- int size = loop.size();
+ b.add(EQ);
+ b.add(JF, new Integer(0));
+ int size = b.size();
while(peekToken() != CASE && peekToken() != DEFAULT && peekToken() != RC) {
- int size2 = loop.size();
- parseStatement(false, loop);
- if (size2 == loop.size()) break;
+ int size2 = b.size();
+ parseStatement(false, b);
+ if (size2 == b.size()) break;
}
- loop.set(size - 1, new Integer(1 + loop.size() - size));
+ b.set(size - 1, new Integer(1 + b.size() - size));
} else if (peekToken() == DEFAULT) {
consume(DEFAULT);
consume(COLON);
while(peekToken() != CASE && peekToken() != DEFAULT && peekToken() != RC) {
- int size2 = loop.size();
- parseStatement(false, loop);
- if (size2 == loop.size()) break;
+ int size2 = b.size();
+ parseStatement(false, b);
+ if (size2 == b.size()) break;
}
} else if (peekToken() == RC) {
consume(RC);
- loop.add(BREAK);
+ b.add(BREAK);
break;
} else {
throw new ParserException("expected CASE, DEFAULT, or RC; got " + codeToString[peekToken()]);
}
+ b.add(BREAK);
+ b.set(size0 - 1, new Integer(b.size() - size0 + 1)); // end of the loop
break;
}
case DO: {
consume(DO);
- ByteCodeBlock loop = newbb(curLine);
- b.add(LOOP, loop);
-
- parseStatement(false, loop);
+ b.add(LOOP);
+ int size = b.size();
+ parseStatement(false, b);
consume(WHILE);
consume(LP);
- startExpr(loop);
- loop.add(JT, new Integer(2));
- loop.add(BREAK);
- loop.add(CONTINUE);
+ startExpr(b);
+ b.add(JT, new Integer(2));
+ b.add(BREAK);
+ b.add(CONTINUE);
consume(RP);
consume(SEMI);
+ b.set(size - 1, new Integer(b.size() - size + 1)); // end of the loop
break;
}
pushBackToken(tok, varName);
if (forIn) {
+ // FIXME: break needs to work in here
consume(NAME);
consume(IN);
startExpr(b);
b.add(GET);
consume(RP);
ByteCodeBlock b2 = newbb(curLine);
- b.add(SCOPE, b2);
- b2.add(LITERAL, new Integer(1));
- b2.add(SUB);
- b2.add(DUP);
- b2.add(LITERAL, new Integer(0));
- b2.add(LT);
- b2.add(JT, new Integer(7));
- b2.add(GET_PRESERVE);
- b2.add(LITERAL, varName);
- b2.add(LITERAL, varName);
- b2.add(DECLARE);
- b2.add(PUT);
- parseStatement(false, b2);
+
+ b.add(PUSHSCOPE);
+
+ b.add(LITERAL, new Integer(1));
+ b.add(SUB);
+ b.add(DUP);
+ b.add(LITERAL, new Integer(0));
+ b.add(LT);
+ b.add(JT, new Integer(7));
+ b.add(GET_PRESERVE);
+ b.add(LITERAL, varName);
+ b.add(LITERAL, varName);
+ b.add(DECLARE);
+ b.add(PUT);
+ parseStatement(false, b);
+
+ b.add(POPSCOPE);
+
break;
} else {
if (hadVar) pushBackToken(VAR, null);
- ByteCodeBlock b2 = newbb(curLine);
- b.add(SCOPE, b2);
- b.add(POP);
+ b.add(PUSHSCOPE);
- int size = b2.size();
- parseStatement(false, b2);
- ByteCodeBlock e2 = startExpr();
+ parseStatement(false, b);
+ ByteCodeBlock e2 = new ByteCodeBlock(line, sourceName);
+ startExpr(e2);
consume(SEMI);
- if (e2 == null) e2 = newbb(curLine).add(b.LITERAL, null);
+ if (e2 == null) e2 = newbb(curLine).add(b.LITERAL, Boolean.TRUE);
- ByteCodeBlock b3 = newbb(curLine);
- b2.add(LOOP, b3);
- b2.add(LITERAL, null);
+ b.add(LOOP);
+ int size2 = b.size();
- b3.add(JT, new Integer(0));
- size = b3.size();
- startExpr(b3);
+ b.add(JT, new Integer(0));
+ int size = b.size();
+ startExpr(b);
+ if (b.size() > size) b.add(POP);
+ b.set(size - 1, new Integer(b.size() - size + 1));
consume(RP);
- if (b3.size() - size > 0) b3.add(POP);
- b3.set(size - 1, new Integer(b3.size() - size + 1));
-
- b3.paste(e2);
- b3.add(JT, new Integer(2));
- b3.add(BREAK);
- parseStatement(false, b3);
- b3.add(CONTINUE);
+
+ b.paste(e2);
+ b.add(JT, new Integer(2));
+ b.add(BREAK);
+ parseStatement(false, b);
+ b.add(CONTINUE);
+ b.set(size2 - 1, new Integer(b.size() - size2 + 1)); // end of the loop
+
+ b.add(POPSCOPE);
break;
}
}