changes made after tupshins reconstruction
[org.ibex.core.git] / src / org / xwt / js / Parser.java
index 0583202..1914cc7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL]
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
 package org.xwt.js;
 
 import org.xwt.util.*;
@@ -73,7 +73,7 @@ class Parser extends Lexer implements ByteCodes {
 
     /** for debugging */
     public static void main(String[] s) throws Exception {
-        JSFunction block = JSFunction.fromReader("stdin", 0, new InputStreamReader(System.in));
+        JS block = JS.fromReader("stdin", 0, new InputStreamReader(System.in));
         if (block == null) return;
         System.out.println(block);
     }
@@ -97,7 +97,10 @@ class Parser extends Lexer implements ByteCodes {
             isRightAssociative[ASSIGN_SUB] =
             isRightAssociative[ASSIGN_MUL] =
             isRightAssociative[ASSIGN_DIV] =
-            isRightAssociative[ASSIGN_MOD] = true;
+            isRightAssociative[ASSIGN_MOD] =
+            isRightAssociative[ADD_TRAP] =
+            isRightAssociative[DEL_TRAP] =
+            true;
 
         precedence[COMMA] = 1;
         // 2 is intentionally left unassigned. we use minPrecedence==2 for comma separated lists
@@ -112,6 +115,8 @@ class Parser extends Lexer implements ByteCodes {
             precedence[ASSIGN_SUB] =
             precedence[ASSIGN_MUL] =
             precedence[ASSIGN_DIV] =
+            precedence[ADD_TRAP] =
+            precedence[DEL_TRAP] =
             precedence[ASSIGN_MOD] = 3;
         precedence[HOOK] = 4;
         precedence[OR] = 5;
@@ -370,9 +375,9 @@ class Parser extends Lexer implements ByteCodes {
             Grammar g = parseGrammar(null);
             if (peekToken() == LC) {
                 g.action = new JSFunction(sourceName, parserLine, null);
-                parseBlock(g.action);
-                g.action.add(parserLine, LITERAL, null);         // in case we "fall out the bottom", return NULL              
-                g.action.add(parserLine, RETURN);
+                parseBlock((JSFunction)g.action);
+                ((JSFunction)g.action).add(parserLine, LITERAL, null);         // in case we "fall out the bottom", return NULL              
+                ((JSFunction)g.action).add(parserLine, RETURN);
             }
             b.add(parserLine, MAKE_GRAMMAR, g);
             b.add(parserLine, PUT);
@@ -380,25 +385,22 @@ class Parser extends Lexer implements ByteCodes {
         }
 
         case ASSIGN_BITOR: case ASSIGN_BITXOR: case ASSIGN_BITAND: case ASSIGN_LSH: case ASSIGN_RSH: case ASSIGN_URSH:
-        case ASSIGN_MUL: case ASSIGN_DIV: case ASSIGN_MOD: case ASSIGN_ADD: case ASSIGN_SUB: {
-            if (tok != ASSIGN_ADD && tok != ASSIGN_SUB) b.add(parserLine, GET_PRESERVE);
+        case ASSIGN_MUL: case ASSIGN_DIV: case ASSIGN_MOD: case ASSIGN_ADD: case ASSIGN_SUB: case ADD_TRAP: case DEL_TRAP: {
+            if (tok != ADD_TRAP && tok != DEL_TRAP) b.add(parserLine, GET_PRESERVE);
             
             startExpr(b,  precedence[tok]);
             
             int size = b.size;
-            if (tok == ASSIGN_ADD || tok == ASSIGN_SUB) {
-                b.add(parserLine, tok);
-                b.add(parserLine, GET);
+            
+            if (tok != ADD_TRAP && tok != DEL_TRAP) {
+                // tok-1 is always s/^ASSIGN_// (0 is BITOR, 1 is ASSIGN_BITOR, etc) 
+                b.add(parserLine, tok - 1, tok-1==ADD ? JS.N(2) : null);
+                b.add(parserLine, PUT);
                 b.add(parserLine, SWAP);
+                b.add(parserLine, POP);
+            } else {
+                b.add(parserLine, tok);
             }
-            
-            // tok-1 is always s/^ASSIGN_// (0 is BITOR, 1 is ASSIGN_BITOR, etc) 
-            b.add(parserLine, tok - 1, tok-1==ADD ? JS.N(2) : null);
-            b.add(parserLine, PUT);
-            b.add(parserLine, SWAP);
-            b.add(parserLine, POP);
-            
-            if (tok == ASSIGN_ADD || tok == ASSIGN_SUB) b.set(size, tok, JS.N(b.size - size));
             break;
         }
         case INC: case DEC: { // postfix
@@ -726,8 +728,12 @@ class Parser extends Lexer implements ByteCodes {
             
             int catchJMPDistance = -1;
             if (peekToken() == CATCH) {
+                Vec catchEnds = new Vec();
+                boolean catchAll = false;
+                
                 catchJMPDistance = b.size - tryInsn;
-                while(peekToken() == CATCH) {
+                
+                while(peekToken() == CATCH && !catchAll) {
                     String exceptionVar;
                     getToken();
                     consume(LP);
@@ -753,36 +759,57 @@ class Parser extends Lexer implements ByteCodes {
                             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);
-                    parseStatement(b, null);
-                    b.add(parserLine, LITERAL, null);   // so we have something to pop
-                    for(int i=0; i<3; i++) if (writebacks[i] != -1) b.set(i, JS.N(b.size - i));
+                    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));