- b.add(b.POP, NO_ARG);
- parseBlock(true, b);
- return new ByteCode(curLine, b.FUNCTION, b);
- }
-
- case WHILE: {
- if (prefix != null) { pushBackToken(); return prefix; }
- consume(LP);
- ByteCode r = new ByteCode(curLine);
- ByteCode loop = new ByteCode(curLine);
- r.add(loop.LOOP, loop);
- r.add(r.LITERAL, null);
-
- loop.add(loop.EXPR, parseMaximalExpr());
- loop.add(loop.JT, new Integer(2));
- loop.add(Lexer.BREAK, NO_ARG);
- consume(RP);
- parseBlock(false, loop);
-
- // if we fall out of the end, definately continue
- loop.add(CONTINUE, NO_ARG);
- return r;
- }
-
- case SWITCH: {
- if (prefix != null) { pushBackToken(); return prefix; }
- consume(LP);
- ByteCode r = new ByteCode(curLine);
- ByteCode loop = new ByteCode(curLine);
- r.add(loop.LOOP, loop);
- r.add(r.LITERAL, null);
- loop.add(loop.EXPR, parseMaximalExpr());
- consume(RP);
- consume(LC);
- while(true) {
- Expr caseExpr;
- tok = getToken();
- if (tok == CASE) {
- loop.add(loop.DUP, NO_ARG);
- loop.add(loop.EXPR, parseMaximalExpr());
- loop.add(EQ, NO_ARG);
- loop.add(loop.JF, new Integer(2));
- } else if (tok != DEFAULT) throw new ParserException("expected CASE or DEFAULT");
- consume(COLON);
- ByteCode b = new ByteCode(curLine);
- while(peekToken() != CASE && peekToken() != DEFAULT && peekToken() != RC) {
- if ((e1 = parseBlock(false)) == null) break;
- b.add(b.EXPR, e1);
- }
- loop.add(loop.EXPR, b);
- if (peekToken() == RC) {
- consume(RC);
- r.add(BREAK, NO_ARG);
- return r;
- }
- }
- }
-
- case DO: {
- if (prefix != null) { pushBackToken(); return prefix; }
- ByteCode r = new ByteCode(curLine);
- ByteCode loop = new ByteCode(curLine);
- r.add(loop.LOOP, loop);
- r.add(r.LITERAL, null);
-
- parseBlock(false, loop);
- consume(WHILE);
- consume(LP);
- loop.add(loop.EXPR, parseMaximalExpr());
- loop.add(loop.JT, new Integer(2));
- loop.add(Lexer.BREAK, NO_ARG);
- loop.add(Lexer.CONTINUE, NO_ARG);
- consume(RP);
- consume(SEMI);
- return r;
- }
-
- // Needs break //
-
- case FOR:
- if (prefix != null) { pushBackToken(); return prefix; }
- if (getToken() != LP) throw new ParserException("expected left paren");
- e1 = parseMaximalExpr();
- if (peekToken() == IN) {
- getToken();
- e2 = parseMaximalExpr();
- if (getToken() != RP) throw new ParserException("expected right paren");
- return new Expr(curLine, FOR, new Expr(curLine, IN, e1.left, e2), parseBlock(false));
-
- } else {
- Expr initExpr = e1;
- if (initExpr == null) initExpr = new Expr(curLine, NULL);
- consume(SEMI);
- Expr whileExpr = parseMaximalExpr();
- consume(SEMI);
- Expr incExpr = parseMaximalExpr();
- consume(RP);
- Expr body = parseBlock(false);
- Expr loop = new Expr(curLine, WHILE, whileExpr, body);
- ExprList list = new ExprList(curLine, LC);
- list.add(initExpr);
- ExprList list2 = new ExprList(curLine, WHILE);
- list.add(list2);
- list2.add(whileExpr);
- list2.add(body);
- list2.add(incExpr);
- return list;
- }
-
- case TRY: {
- // We deliberately allow you to omit braces in catch{}/finally{} if they are single statements...
- if (prefix != null) { pushBackToken(); return prefix; }
- Expr tryBlock = parseBlock(true);
-
- tok = peekToken();
- ExprList list = new ExprList(curLine, TRY);
- if (tok == CATCH) {
- getToken();
- if (getToken() != LP) throw new ParserException("expected (");
- if (getToken() != NAME) throw new ParserException("expected name");
- Expr name = new Expr(curLine, NAME, string);
- if (getToken() != RP) throw new ParserException("expected )");
- list.add(new Expr(curLine, CATCH, name, parseBlock(false)));
- tok = peekToken();
- }
- if (tok == FINALLY) {
- getToken();
- list.add(new Expr(curLine, FINALLY, parseBlock(false)));
- }
-
- if (list.size() == 0) throw new ParserException("try without catch or finally");
- return new Expr(curLine, TRY, tryBlock, list);