X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2Fjs%2FParser.java;h=1914cc7e3226acaa6f8f57fe9ae85373515ed1de;hb=de378041d5ca2aca1a2b5a31ef15ae90a86c977f;hp=ee04b7eb484be47d59c1234de5a0072868931c26;hpb=772b947b9b23de711953d0a1e33cef5f356c442a;p=org.ibex.core.git diff --git a/src/org/xwt/js/Parser.java b/src/org/xwt/js/Parser.java index ee04b7e..1914cc7 100644 --- a/src/org/xwt/js/Parser.java +++ b/src/org/xwt/js/Parser.java @@ -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,26 +728,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