-// 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.*;
/** 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);
}
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
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;
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) {
default: pushBackToken(); return g;
}
if (g == null) return parseGrammar(g0);
- return new Grammar.Juxtaposition(g, g0);
+ return parseGrammar(new Grammar.Juxtaposition(g, g0));
}
/**
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);
}
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
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));