+ case FOR: {
+ if (prefix != null) { pushBackToken(); return prefix; }
+ if (getToken() != LP) throw new ParserException("expected left paren");
+
+ tok = getToken();
+ if (tok == VAR) tok = getToken();
+ String varName = string;
+ boolean forIn = peekToken() == IN;
+ pushBackToken(tok, varName);
+
+ ByteCode b = new ByteCode(curLine);
+ if (forIn) {
+ consume(NAME);
+ consume(IN);
+ b.add(b.EXPR, parseMaximalExpr());
+ b.add(b.PUSHKEYS, NO_ARG);
+ b.add(b.LITERAL, "length");
+ b.add(b.GET, NO_ARG);
+ consume(RP);
+ ByteCode b2 = new ByteCode(curLine);
+ b.add(b.SCOPE, b2);
+ b2.add(b.LITERAL, new Integer(1));
+ b2.add(SUB, NO_ARG);
+ b2.add(b.DUP, NO_ARG);
+ b2.add(b.LITERAL, new Integer(0));
+ b2.add(LT, NO_ARG);
+ b2.add(b.JT, new Integer(7));
+ b2.add(b.GET_PRESERVE, NO_ARG);
+ b2.add(b.LITERAL, varName);
+ b2.add(b.LITERAL, varName);
+ b2.add(b.DECLARE, NO_ARG);
+ b2.add(b.PUT, NO_ARG);
+ b2.add(b.EXPR, parseBlock(false));
+ b2.add(b.LITERAL, null);
+ return b;
+
+ } else {
+ ByteCode b2 = new ByteCode(curLine);
+ b.add(b.SCOPE, b2);
+ b2.add(b.EXPR, parseMaximalExpr());
+ b2.add(b.POP, NO_ARG);
+ consume(SEMI);
+ ByteCode b3 = new ByteCode(curLine);
+ b2.add(b.LOOP, b3);
+ b2.add(b.LITERAL, null);
+ b3.add(b.EXPR, parseMaximalExpr());
+ consume(SEMI);
+ b3.add(b.JT, new Integer(2));
+ b3.add(BREAK, NO_ARG);
+ b3.add(b.JT, new Integer(2));
+ b3.add(b.EXPR, parseMaximalExpr());
+ consume(RP);
+ parseBlock(false, b3);
+ return b;
+ }
+ }
+