2003/07/07 01:47:37
authorbrian <brian@xwt.org>
Fri, 30 Jan 2004 07:03:27 +0000 (07:03 +0000)
committerbrian <brian@xwt.org>
Fri, 30 Jan 2004 07:03:27 +0000 (07:03 +0000)
darcs-hash:20040130070327-aa32f-2d0fff6f019ae76d0c9a35456646cd3586fa5da3.gz

src/org/xwt/js/Parser.java

index 49b5d34..9183c94 100644 (file)
@@ -194,9 +194,14 @@ class Parser extends Lexer implements ByteCodes {
         }
         case INC: case DEC: {  // prefix (not postfix)
             startExpr(b, precedence[tok]);
-            if (b.get(b.size() - 1) != GET)
+            int prev = b.size() - 1;
+            if (b.get(prev) == GET && b.getArg(prev) != null)
+                b.set(prev, LITERAL, b.getArg(prev));
+            else if(b.get(prev) == GET)
+                b.pop();
+            else
                 throw pe("prefixed increment/decrement can only be performed on a valid assignment target");
-            b.set(b.size() - 1, tok, new Boolean(true));
+            b.add(parserLine, tok, Boolean.TRUE);
             break;
         }
         case BANG: case BITNOT: case TYPEOF: {
@@ -236,38 +241,26 @@ class Parser extends Lexer implements ByteCodes {
             b.add(parserLine, NEWFUNCTION, b2);
 
             // function prelude; arguments array is already on the stack
-            b2.add(parserLine, TOPSCOPE);                                                // push the scope onto the stack
-            b2.add(parserLine, SWAP);                                                    // swap 'this' and 'arguments'
-
-            b2.add(parserLine, LITERAL, "arguments");                                    // declare arguments (equivalent to 'var arguments;')
-            b2.add(parserLine, DECLARE);
-
-            b2.add(parserLine, LITERAL, "arguments");                                    // set this.arguments and leave the value on the stack
+            b2.add(parserLine, TOPSCOPE);
             b2.add(parserLine, SWAP);
+            b2.add(parserLine, DECLARE, "arguments");                     // declare arguments (equivalent to 'var arguments;')
+            b2.add(parserLine, SWAP);                                     // set this.arguments and leave the value on the stack
             b2.add(parserLine, PUT);
-            b2.add(parserLine, SWAP);
-            b2.add(parserLine, POP);
 
             while(peekToken() != RP) {                                    // run through the list of argument names
                 if (peekToken() == NAME) {
                     consume(NAME);                                        // a named argument
+                    String varName = string;
                     
-                    b2.add(parserLine, LITERAL, string);                  // declare the name
-                    b2.add(parserLine, DECLARE);
-                    
-                    b2.add(parserLine, LITERAL, new Integer(numArgs));    // retrieve it from the arguments array
-                    b2.add(parserLine, GET_PRESERVE);
-                    b2.add(parserLine, SWAP);
-                    b2.add(parserLine, POP);
-                    
-                    b2.add(parserLine, TOPSCOPE);                         // put it to the current scope
+                    b2.add(parserLine, DUP);                              // dup the args array 
+                    b2.add(parserLine, GET, new Integer(numArgs));   // retrieve it from the arguments array
+                    b2.add(parserLine, TOPSCOPE);
                     b2.add(parserLine, SWAP);
-                    b2.add(parserLine, LITERAL, string);
+                    b2.add(parserLine, DECLARE, varName);                  // declare the name
                     b2.add(parserLine, SWAP);
-                    b2.add(parserLine, PUT);
-                    
-                    b2.add(parserLine, POP);                              // clean the stack
-                    b2.add(parserLine, POP);
+                    b2.add(parserLine, PUT); 
+                    b2.add(parserLine, POP);                               // pop the value
+                    b2.add(parserLine, POP);                               // pop the scope                  
                 }
                 if (peekToken() == RP) break;
                 consume(COMMA);
@@ -276,11 +269,17 @@ class Parser extends Lexer implements ByteCodes {
             consume(RP);
 
             b2.add(parserLine, POP);                                      // pop off the arguments array
+            b2.add(parserLine, POP);                                      // pop off TOPSCOPE
+            
+           if(peekToken() != LC)
+                throw pe("Functions must have a block surrounded by curly brackets");
+                
+            parseBlock(b2, null);                                   // the function body
 
-            parseStatement(b2, null);                                     // the function body
-
-            b2.add(parserLine, LITERAL, null);                            // in case we "fall out the bottom", return NULL
-            b2.add(parserLine, RETURN);
+            if(b2.get(b2.size()-1) != RETURN) {
+                b2.add(parserLine, LITERAL, null);                        // in case we "fall out the bottom", return NULL
+                b2.add(parserLine, RETURN);
+            }
 
             break;
         }
@@ -343,7 +342,10 @@ class Parser extends Lexer implements ByteCodes {
         }
         default: {
             pushBackToken();
-            b.add(parserLine, GET);
+            if(b.get(b.size()-1) == LITERAL && b.getArg(b.size()-1) != null)
+                b.set(b.size()-1,GET,b.getArg(b.size()-1));
+            else
+                b.add(parserLine, GET);
             return;
         }
         }
@@ -493,16 +495,15 @@ class Parser extends Lexer implements ByteCodes {
             b.add(parserLine, TOPSCOPE);                         // push the current scope
             while(true) {
                 consume(NAME);
-                String name = string;
-                b.add(parserLine, LITERAL, name);                // push the name to be declared
-                b.add(parserLine, DECLARE);                      // declare it
+                b.add(parserLine, DECLARE, string);               // declare it
                 if (peekToken() == ASSIGN) {                     // if there is an '=' after the variable name
-                    b.add(parserLine, LITERAL, name);            // put the var name back on the stack
                     consume(ASSIGN);
                     startExpr(b, -1);
                     b.add(parserLine, PUT);                      // assign it
                     b.add(parserLine, POP);                      // clean the stack
-                }
+                } else {
+                    b.add(parserLine, POP);                      // pop the string pushed by declare
+                }   
                 if (peekToken() != COMMA) break;
                 consume(COMMA);
             }