From 69ecee0bc41e6bd410572817e7c59d51f1b5b629 Mon Sep 17 00:00:00 2001 From: megacz Date: Fri, 30 Jan 2004 07:00:43 +0000 Subject: [PATCH] 2003/06/04 05:29:39 darcs-hash:20040130070043-2ba56-d12a8a751fe6c6dd84d7441afdaa645fc6df1ac3.gz --- src/org/xwt/js/Parser.java | 222 +++++++++++++++++++++----------------------- 1 file changed, 106 insertions(+), 116 deletions(-) diff --git a/src/org/xwt/js/Parser.java b/src/org/xwt/js/Parser.java index 9af090f..6f55b50 100644 --- a/src/org/xwt/js/Parser.java +++ b/src/org/xwt/js/Parser.java @@ -60,7 +60,7 @@ public class Parser extends Lexer { public void consume(int code) throws IOException { if (getToken() != code) - throw new ParserException("expected " + codeToString[op] + ", got " + (op == -1 ? "EOL" : codeToString[op])); + throw new ParserException("expected " + codeToString[code] + ", got " + (op == -1 ? "EOL" : codeToString[op])); } /** parses the largest possible expression */ @@ -489,63 +489,82 @@ public class Parser extends Lexer { 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: { + // FIXME: don't just ignore this! // 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 (tok == FINALLY) getToken(); - if (list.size() == 0) throw new ParserException("try without catch or finally"); - return new Expr(curLine, TRY, tryBlock, list); + return tryBlock; } + 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; + } + } + default: pushBackToken(); return prefix; @@ -577,26 +596,20 @@ public class Parser extends Lexer { public static final byte GET = -8; // -- get stack[0] from stack[1] public static final byte GET_PRESERVE = -80; // -- get stack[0] from stack[1] public static final byte PUT = -9; // -- put stack[1] to key stack[0] on stack[2]; leaves object on the stack - public static final byte THROW = -10; // -- throw topmost element - public static final byte RETURN = -11; // -- return the topmost value on the stack - public static final byte ASSERT = -12; // -- fail if topmost element is not true public static final byte JT = -13; // < relative_address > -- pop the stack; if true, jump to public static final byte JF = -21; // < relative_address > -- pop the stack; if false, jump to public static final byte JMP = -22; // < relative_address > -- jump to static public final byte POP = -14; // -- discard the top element on the stack public static final byte CALL = -15; // < numargs > -- call stack[0] with the topmost values as arguments - public static final byte TRY = -16; // < bytecode_block > -- run the block pointed to; returns with thrown exn on top of stack - - public static final byte INSTANCEOF = -17; // -- ?? - public static final byte TYPEOF = -18; // -- - public static final byte FOR__IN = -19; // -- ?? + public static final byte PUSHKEYS = -19; // -- ?? public static final byte EXPR = -20; // -- transitional public static final byte SWAP = -23; // -- transitional public static final byte SCOPE = -30; // -- transitional public static final byte LOOP = -40; // -- transitional public static final byte DUP = -50; // -- transitional + public static final byte LABEL = -60; // -- transitional int[] op = new int[10]; Object[] arg = new Object[10]; @@ -624,22 +637,41 @@ public class Parser extends Lexer { public Object eval(final JS.Scope s, Parser.Thread t) throws ControlTransferException { for(int i=0; i