2004/01/12 16:37:22
[org.ibex.core.git] / src / org / xwt / js / Parser.java
index 66084e0..41e314e 100644 (file)
@@ -319,9 +319,9 @@ class Parser extends Lexer implements ByteCodes {
         if (g != null)
             switch(tok) {
                 case BITOR: return new Grammar.Alternative(g, parseGrammar(null));
-                case ADD:   return new Grammar.Repetition(g, 1, Integer.MAX_VALUE);
-                case MUL:   return new Grammar.Repetition(g, 0, Integer.MAX_VALUE);
-                case HOOK:  return new Grammar.Repetition(g, 0, 1);
+                case ADD:   return parseGrammar(new Grammar.Repetition(g, 1, Integer.MAX_VALUE));
+                case MUL:   return parseGrammar(new Grammar.Repetition(g, 0, Integer.MAX_VALUE));
+                case HOOK:  return parseGrammar(new Grammar.Repetition(g, 0, 1));
             }
         Grammar g0 = null;
         switch(tok) {
@@ -342,7 +342,7 @@ class Parser extends Lexer implements ByteCodes {
             default:     pushBackToken(); return g;
         }
         if (g == null) return parseGrammar(g0);
-        return new Grammar.Juxtaposition(g, g0);
+        return parseGrammar(new Grammar.Juxtaposition(g, g0));
     }
 
     /**
@@ -726,26 +726,88 @@ class Parser extends Lexer implements ByteCodes {
             
             int catchJMPDistance = -1;
             if (peekToken() == CATCH) {
+                Vec catchEnds = new Vec();
+                boolean catchAll = false;
+                
                 catchJMPDistance = b.size - tryInsn;
-                String exceptionVar;
-                getToken();
-                consume(LP);
-                consume(NAME);
-                exceptionVar = string;
-                consume(RP);
-                b.add(parserLine, TOPSCOPE);                        // the exception is on top of the stack; put it to the chosen name
-                b.add(parserLine, SWAP);
-                b.add(parserLine, LITERAL,exceptionVar);
-                b.add(parserLine, SWAP);
-                b.add(parserLine, PUT);
-                b.add(parserLine, POP);
-                b.add(parserLine, POP);
-                parseStatement(b, null);
+                
+                while(peekToken() == CATCH && !catchAll) {
+                    String exceptionVar;
+                    getToken();
+                    consume(LP);
+                    consume(NAME);
+                    exceptionVar = string;
+                    int[] writebacks = new int[] { -1, -1, -1 };
+                    if (peekToken() != RP) {
+                        // extended XWT catch block: catch(e faultCode "foo.bar.baz")
+                        consume(NAME);
+                        String propName = string;
+                        b.add(parserLine, DUP);
+                        b.add(parserLine, LITERAL, string);
+                        b.add(parserLine, GET);
+                        b.add(parserLine, DUP);
+                        b.add(parserLine, LITERAL, null);
+                        b.add(parserLine, EQ);
+                        b.add(parserLine, JT);
+                        writebacks[0] = b.size - 1;
+                        if (peekToken() == STRING) {
+                            consume(STRING);
+                            b.add(parserLine, DUP);
+                            b.add(parserLine, LITERAL, string);
+                            b.add(parserLine, LT);
+                            b.add(parserLine, JT);
+                            writebacks[1] = b.size - 1;
+                            b.add(parserLine, DUP);
+                            b.add(parserLine, LITERAL, string + "/");   // (slash is ASCII after dot)
+                            b.add(parserLine, GE);
+                            b.add(parserLine, JT);
+                            writebacks[2] = b.size - 1;
+                        } else {
+                            consume(NUMBER);
+                            b.add(parserLine, DUP);
+                            b.add(parserLine, LITERAL, number);
+                            b.add(parserLine, EQ);
+                            b.add(parserLine, JF);
+                            writebacks[1] = b.size - 1;
+                        }
+                        b.add(parserLine, POP);  // pop the element thats on the stack from the compare
+                    } else {
+                        catchAll = true;
+                    }
+                    consume(RP);
+                    // the exception is on top of the stack; put it to the chosen name
+                    b.add(parserLine, NEWSCOPE);
+                    b.add(parserLine, TOPSCOPE);
+                    b.add(parserLine, SWAP);
+                    b.add(parserLine, LITERAL,exceptionVar);
+                    b.add(parserLine, DECLARE);
+                    b.add(parserLine, SWAP);
+                    b.add(parserLine, PUT);
+                    b.add(parserLine, POP);
+                    b.add(parserLine, POP);
+                    parseBlock(b, null);
+                    b.add(parserLine, OLDSCOPE);
+                    
+                    b.add(parserLine, JMP);
+                    catchEnds.addElement(new Integer(b.size-1));
+                    
+                    for(int i=0; i<3; i++) if (writebacks[i] != -1) b.set(writebacks[i], JS.N(b.size-writebacks[i]));
+                    b.add(parserLine, POP); // pop the element thats on the stack from the compare
+                }
+                
+                if(!catchAll)
+                    b.add(parserLine, THROW);
+                
+                for(int i=0;i<catchEnds.size();i++) {
+                    int n = ((Integer)catchEnds.elementAt(i)).intValue();
+                    b.set(n, JS.N(b.size-n));
+                }
+                
                 // pop the try and catch markers
                 b.add(parserLine,POP);
                 b.add(parserLine,POP);
             }
-            
+                        
             // jump here if no exception was thrown
             b.set(successJMPInsn, JS.N(b.size - successJMPInsn));