2003/06/09 06:38:36
[org.ibex.core.git] / src / org / xwt / js / Parser.java
index ff59d3b..f594eee 100644 (file)
@@ -10,11 +10,7 @@ class Parser extends Lexer implements ByteCodes {
 
     // Constructors //////////////////////////////////////////////////////
 
-    public Parser(Reader r, String sourceName, int line) throws IOException {
-       super(r);
-       this.sourceName = sourceName;
-       this.line = line;
-    }
+    public Parser(Reader r, String sourceName, int line) throws IOException { super(r, sourceName, line); }
 
     /** for debugging */
     public static void main(String[] s) throws Exception {
@@ -50,7 +46,7 @@ class Parser extends Lexer implements ByteCodes {
        precedence[LSH] = precedence[RSH] = precedence[URSH] = 12;
        precedence[ADD] = precedence[SUB] = 13;
        precedence[MUL] = precedence[DIV] = precedence[MOD] = 14;
-       precedence[BITNOT] = precedence[INSTANCEOF] = 15;
+       precedence[BITNOT] =  15;
        precedence[INC] = precedence[DEC] = 16;
        precedence[LP] = 17;
        precedence[LB] = 18;
@@ -60,10 +56,12 @@ class Parser extends Lexer implements ByteCodes {
 
     // Parsing Logic /////////////////////////////////////////////////////////
 
+    private ByteCodeBlock newbb(int line) { return new ByteCodeBlock(line, sourceName); }
+
     /** gets a token and throws an exception if it is not <tt>code</tt> */
     public void consume(int code) throws IOException {
        if (getToken() != code)
-           throw new ParserException("expected " + codeToString[code] + ", got " + (op == -1 ? "EOL" : codeToString[op]));
+           throw new ParserException("expected " + codeToString[code] + ", got " + (op == -1 ? "EOF" : codeToString[op]));
     }
 
     /** append the largest expression beginning with prefix containing no operators of precedence below <tt>minPrecedence</tt> */
@@ -79,9 +77,6 @@ class Parser extends Lexer implements ByteCodes {
        int tok = getToken();
        int curLine = line;
        if (tok == -1) return;
-       if (minPrecedence > 0 && precedence[tok] != 0)
-           if (precedence[tok] < minPrecedence || (precedence[tok] == minPrecedence && !isRightAssociative[tok]))
-               { pushBackToken(); return; }
 
        ByteCodeBlock b = appendTo;
 
@@ -109,7 +104,8 @@ class Parser extends Lexer implements ByteCodes {
        }
        case SUB: {
            consume(NUMBER);
-           continueExpr(b.add(ByteCodeBlock.LITERAL, new Double(number.doubleValue() * -1)), minPrecedence);
+           b.add(ByteCodeBlock.LITERAL, new Double(number.doubleValue() * -1));
+           continueExpr(b, minPrecedence);
            return;
        }
        case LP: {
@@ -125,7 +121,7 @@ class Parser extends Lexer implements ByteCodes {
            continueExpr(b, minPrecedence);
            return;
        }
-       case BANG: case BITNOT: case INSTANCEOF: case TYPEOF: {
+       case BANG: case BITNOT: case TYPEOF: {
            startExpr(precedence[tok], b);
            b.add(tok);
            continueExpr(b, minPrecedence);
@@ -133,8 +129,7 @@ class Parser extends Lexer implements ByteCodes {
        }
        case LC: {
            b.add(OBJECT, null);
-           if (peekToken() == RC) { consume(RC); continueExpr(b, minPrecedence); return; }
-           while(true) {
+           if (peekToken() != RC) while(true) {
                if (peekToken() != NAME && peekToken() != STRING) throw new Error("expected NAME or STRING");
                getToken();
                b.add(LITERAL, string);
@@ -142,10 +137,13 @@ class Parser extends Lexer implements ByteCodes {
                startExpr(b);
                b.add(PUT);
                b.add(POP);
-               if (peekToken() == RC) { consume(RC); continueExpr(b, minPrecedence); return; }
+               if (peekToken() == RC) break;
                consume(COMMA);
-               if (peekToken() == RC) { consume(RC); continueExpr(b, minPrecedence); return; }
+               if (peekToken() == RC) break;
            }
+           consume(RC);
+           continueExpr(b, minPrecedence);
+           return;
        }
        case NAME: {
            String name = string;
@@ -168,7 +166,7 @@ class Parser extends Lexer implements ByteCodes {
        case FUNCTION: {
            consume(LP);
            int numArgs = 0;
-           ByteCodeBlock b2 = new ByteCodeBlock(curLine, sourceName);
+           ByteCodeBlock b2 = newbb(curLine);
            b2.add(TOPSCOPE);
            b2.add(SWAP);
            b2.add(LITERAL, "arguments");
@@ -260,8 +258,8 @@ class Parser extends Lexer implements ByteCodes {
            // invocation
            int i = 0;
            while(peekToken() != RP) {
-               startExpr(b);
                i++;
+               startExpr(b);
                if (peekToken() == RP) break;
                consume(COMMA);
            }
@@ -284,7 +282,7 @@ class Parser extends Lexer implements ByteCodes {
            b.add(tok == AND ? b.JF : b.JT, new Integer(0));
            int size = b.size();
            startExpr(precedence[tok], b);
-           b.arg[size - 1] = new Integer(b.size() - size + 2);
+           b.set(size - 1, new Integer(b.size() - size + 2));
            b.add(JMP, new Integer(2));
            b.add(LITERAL, tok == AND ? new Boolean(false) : new Boolean(true));
            continueExpr(b, minPrecedence);
@@ -329,12 +327,12 @@ class Parser extends Lexer implements ByteCodes {
            b.add(JF, new Integer(0));
            int size = b.size();
            startExpr(b);
-           b.arg[size - 1] = new Integer(b.size() - size + 2);
+           b.set(size - 1, new Integer(b.size() - size + 2));
            b.add(JMP, new Integer(0));
            consume(COLON);
            size = b.size();
            startExpr(b);
-           b.arg[size - 1] = new Integer(b.size() - size + 1);
+           b.set(size - 1, new Integer(b.size() - size + 1));
            continueExpr(b, minPrecedence);
            return;
        }
@@ -422,19 +420,19 @@ class Parser extends Lexer implements ByteCodes {
                
                if (peekToken() == ELSE) {
                    consume(ELSE);
-                   b.arg[size - 1] = new Integer(2 + b.size() - size);
+                   b.set(size - 1, new Integer(2 + b.size() - size));
                    b.add(JMP, new Integer(0));
                    size = b.size();
                    parseStatement(false, b);
                }
-               b.arg[size - 1] = new Integer(1 + b.size() - size);
+               b.set(size - 1, new Integer(1 + b.size() - size));
                break;
            }
 
            case WHILE: {
                consume(WHILE);
                consume(LP);
-               ByteCodeBlock loop = new ByteCodeBlock(curLine, sourceName);
+               ByteCodeBlock loop = newbb(curLine);
                b.add(LOOP, loop);
                
                loop.add(POP);
@@ -452,7 +450,7 @@ class Parser extends Lexer implements ByteCodes {
            case SWITCH: {
                consume(SWITCH);
                consume(LP);
-               ByteCodeBlock loop = new ByteCodeBlock(curLine, sourceName);
+               ByteCodeBlock loop = newbb(curLine);
                b.add(LOOP, loop);
                startExpr(loop);
                consume(RP);
@@ -471,7 +469,7 @@ class Parser extends Lexer implements ByteCodes {
                            parseStatement(false, loop);
                            if (size2 == loop.size()) break;
                        }
-                       loop.arg[size - 1] = new Integer(1 + loop.size() - size);
+                       loop.set(size - 1, new Integer(1 + loop.size() - size));
                    } else if (peekToken() == DEFAULT) {
                        consume(DEFAULT);
                        consume(COLON);
@@ -492,7 +490,7 @@ class Parser extends Lexer implements ByteCodes {
                
            case DO: {
                consume(DO);
-               ByteCodeBlock loop = new ByteCodeBlock(curLine, sourceName);
+               ByteCodeBlock loop = newbb(curLine);
                b.add(LOOP, loop);
                
                parseStatement(false, loop);
@@ -532,7 +530,8 @@ class Parser extends Lexer implements ByteCodes {
            consume(LP);
 
            tok = getToken();
-           if (tok == VAR) tok = getToken();
+           boolean hadVar = false;
+           if (tok == VAR) { hadVar = true; tok = getToken(); }
            String varName = string;
            boolean forIn = peekToken() == IN;
            pushBackToken(tok, varName);
@@ -545,7 +544,7 @@ class Parser extends Lexer implements ByteCodes {
                b.add(LITERAL, "length");
                b.add(GET);
                consume(RP);
-               ByteCodeBlock b2 = new ByteCodeBlock(curLine, sourceName);
+               ByteCodeBlock b2 = newbb(curLine);
                b.add(SCOPE, b2);
                b2.add(LITERAL, new Integer(1));
                b2.add(SUB);
@@ -562,19 +561,18 @@ class Parser extends Lexer implements ByteCodes {
                break;
                
            } else {
-               ByteCodeBlock b2 = new ByteCodeBlock(curLine, sourceName);
+               if (hadVar) pushBackToken(VAR, null);
+               ByteCodeBlock b2 = newbb(curLine);
                b.add(SCOPE, b2);
                b.add(POP);
 
                int size = b2.size();
-               startExpr(b2);
-               if (b2.size() - size > 0) b2.add(POP);
-               consume(SEMI);
+               parseStatement(false, b2);
                ByteCodeBlock e2 = startExpr();
                consume(SEMI);
-               if (e2 == null) e2 = new ByteCodeBlock(curLine, sourceName, b.LITERAL, null);
+               if (e2 == null) e2 = newbb(curLine).add(b.LITERAL, null);
 
-               ByteCodeBlock b3 = new ByteCodeBlock(curLine, sourceName);
+               ByteCodeBlock b3 = newbb(curLine);
                b2.add(LOOP, b3);
                b2.add(LITERAL, null);
 
@@ -583,13 +581,13 @@ class Parser extends Lexer implements ByteCodes {
                startExpr(b3);
                consume(RP);
                if (b3.size() - size > 0) b3.add(POP);
-               b3.arg[size - 1] = new Integer(b3.size() - size + 1);
+               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(BREAK);
+               b3.add(CONTINUE);
                break;
            }
        }