+ switch (tok) {
+ case NUMBER: return continueExpr(b.add(ForthBlock.LITERAL, number), minPrecedence);
+ case STRING: return continueExpr(b.add(ForthBlock.LITERAL, string), minPrecedence);
+ case THIS: return continueExpr(b.add(THIS, null), minPrecedence);
+ case NULL: return continueExpr(b.add(ForthBlock.LITERAL, null), minPrecedence);
+ case TRUE: case FALSE: return continueExpr(b.add(ForthBlock.LITERAL, new Boolean(tok == TRUE)), minPrecedence);
+ case LB: {
+ b.add(b.ARRAY, new Integer(0));
+ int i = 0;
+ while(true) {
+ ForthBlock e = startExpr();
+ if (e == null && peekToken() == RB) { consume(RB); return continueExpr(b, minPrecedence); }
+ b.add(b.LITERAL, new Integer(i++));
+ if (e == null) b.add(b.LITERAL, null);
+ else b.add(b.EXPR, e);
+ b.add(b.PUT);
+ b.add(b.POP);
+ if (peekToken() == RB) { consume(RB); return continueExpr(b, minPrecedence); }
+ consume(COMMA);
+ }
+ }
+ case SUB: {
+ consume(NUMBER);
+ return continueExpr(b.add(ForthBlock.LITERAL, new Double(number.doubleValue() * -1)), minPrecedence);
+ }
+ case LP: {
+ b.add(EXPR, startExpr());
+ consume(RP);
+ return continueExpr(b, minPrecedence);
+ }
+ case INC: case DEC: {
+ // prefix
+ ForthBlock subexp = startExpr(precedence[tok]);
+ subexp.set(subexp.size() - 1, tok, new Boolean(true));
+ b.add(b.EXPR, subexp);
+ return continueExpr(b, minPrecedence);
+ }
+ case BANG: case BITNOT: case INSTANCEOF: case TYPEOF: {
+ b.add(b.EXPR, startExpr(precedence[tok]));
+ b.add(tok);
+ return continueExpr(b, minPrecedence);
+ }
+ case LC: {
+ b.add(b.OBJECT, null);
+ if (peekToken() == RC) { consume(RC); return continueExpr(b, minPrecedence); }
+ while(true) {
+ if (peekToken() != NAME && peekToken() != STRING) throw new Error("expected NAME or STRING");