From 17b346d40a6ac856114dfae365e4f106933d14f9 Mon Sep 17 00:00:00 2001 From: megacz Date: Fri, 30 Jan 2004 07:00:40 +0000 Subject: [PATCH] 2003/06/03 23:21:28 darcs-hash:20040130070040-2ba56-bbd1af048813eabe1fbeae3febc777578e594450.gz --- src/org/xwt/js/Parser.java | 276 ++++++++++++++++++++++++-------------------- 1 file changed, 150 insertions(+), 126 deletions(-) diff --git a/src/org/xwt/js/Parser.java b/src/org/xwt/js/Parser.java index e99eaa7..c99ff71 100644 --- a/src/org/xwt/js/Parser.java +++ b/src/org/xwt/js/Parser.java @@ -104,13 +104,67 @@ public class Parser extends Lexer { // these case arms match the precedence of operators; each arm is a precedence level. switch (tok) { - case ASSIGN_BITOR: case ASSIGN_BITXOR: case ASSIGN_BITAND: case ASSIGN_LSH: - case ASSIGN_RSH: case ASSIGN_URSH: case ASSIGN_ADD: case ASSIGN_SUB: case ASSIGN_MUL: case ASSIGN_DIV: case ASSIGN_MOD: - return new Expr(curLine, ASSIGN, prefix, new Expr(curLine, tok - 1, prefix, parseMaximalExpr(null, precedence[ASSIGN]))); + case VAR: { + if (prefix != null) { pushBackToken(); return prefix; } + ByteCode b = new ByteCode(curLine); + b.add(b.THIS, NO_ARG); + while(true) { + consume(NAME); + String name = string; + b.add(b.DECLARE, name); + if (peekToken() == ASSIGN) { + b.add(b.LITERAL, name); + consume(ASSIGN); + b.add(b.EXPR, parseMaximalExpr()); + b.add(b.PUT, NO_ARG); + b.add(b.POP, NO_ARG); + } + if (peekToken() != COMMA) break; + consume(COMMA); + } + return b; + } - // DONE // + case IN: pushBackToken(); return prefix; + + case IF: { + if (prefix != null) { pushBackToken(); return prefix; } + ByteCode b = new ByteCode(curLine); + consume(LP); + b.add(b.EXPR, parseMaximalExpr()); + consume(RP); + b.add(b.JF, new Integer(3)); + b.add(b.EXPR, parseBlock(false)); + b.add(b.JMP, new Integer(2)); + if (peekToken() != ELSE) return b.add(b.LITERAL, null); + consume(ELSE); + b.add(b.EXPR, parseBlock(false)); + return b; + } // FIXME: ugly hack!! + case ASSIGN_BITOR: if (tok == ASSIGN_BITOR) tok = BITOR; + case ASSIGN_BITXOR: if (tok == ASSIGN_BITXOR) tok = BITXOR; + case ASSIGN_BITAND: if (tok == ASSIGN_BITAND) tok = BITAND; + case ASSIGN_LSH: if (tok == ASSIGN_LSH) tok = LSH; + case ASSIGN_RSH: if (tok == ASSIGN_RSH) tok = RSH; + case ASSIGN_URSH: if (tok == ASSIGN_URSH) tok = URSH; + case ASSIGN_ADD: if (tok == ASSIGN_ADD) tok = ADD; + case ASSIGN_SUB: if (tok == ASSIGN_SUB) tok = SUB; + case ASSIGN_MUL: if (tok == ASSIGN_MUL) tok = MUL; + case ASSIGN_DIV: if (tok == ASSIGN_DIV) tok = DIV; + case ASSIGN_MOD: if (tok == ASSIGN_MOD) tok = MOD; + { + ByteCode b = (ByteCode)prefix; + b.set(b.size() - 1, b.GET_PRESERVE, new Boolean(true)); + b.add(b.EXPR, parseMaximalExpr(null, precedence[tok])); + b.add(tok, NO_ARG); + b.add(b.PUT, NO_ARG); + b.add(b.SWAP, NO_ARG); + b.add(b.POP, NO_ARG); + return b; + } + case INC: case DEC: if (prefix == null) { // prefix @@ -265,9 +319,9 @@ public class Parser extends Lexer { while(true) { Expr e = parseMaximalExpr(); if (e == null && peekToken() == RB) { consume(RB); return b; } - if (e == null) e = new Expr(curLine, NULL); b.add(b.LITERAL, new Integer(i++)); - b.add(b.EXPR, e); + if (e == null) b.add(b.LITERAL, null); + else b.add(b.EXPR, e); b.add(b.PUT, NO_ARG); b.add(b.POP, NO_ARG); if (peekToken() == RB) { consume(RB); return b; } @@ -324,69 +378,64 @@ public class Parser extends Lexer { case FUNCTION: { if (prefix != null) { pushBackToken(); return prefix; } consume(LP); - ExprList list = new ExprList(curLine, LC); + ByteCode b = new ByteCode(curLine); + int numArgs = 0; + b.add(b.THIS, NO_ARG); + b.add(b.SWAP, NO_ARG); + b.add(b.LITERAL, "arguments"); + b.add(b.LITERAL, "arguments"); + b.add(b.DECLARE, NO_ARG); + b.add(b.SWAP, NO_ARG); + b.add(b.PUT, NO_ARG); + b.add(b.SWAP, NO_ARG); + b.add(b.POP, NO_ARG); if (peekToken() == RP) consume(RP); else while(true) { - tok = peekToken(); - if (tok == COMMA) { + if (peekToken() == COMMA) { consume(COMMA); - list.add(new Expr(curLine, NULL)); } else { consume(NAME); - list.add(new Expr(curLine, NAME, string)); + + // declare the name + b.add(b.LITERAL, string); + b.add(b.DECLARE, NO_ARG); + + // retrieve it from the arguments array + b.add(b.LITERAL, new Integer(numArgs)); + b.add(b.GET_PRESERVE, NO_ARG); + b.add(b.SWAP, NO_ARG); + b.add(b.POP, NO_ARG); + + // put it to the current scope + b.add(b.THIS, NO_ARG); + b.add(b.SWAP, NO_ARG); + b.add(b.LITERAL, string); + b.add(b.SWAP, NO_ARG); + b.add(b.PUT, NO_ARG); + + // clean the stack + b.add(b.POP, NO_ARG); + b.add(b.POP, NO_ARG); + if (peekToken() == RP) { consume(RP); break; } consume(COMMA); } + numArgs++; } - return new Expr(curLine, FUNCTION, list, parseBlock(true)); + // pop off the arguments array + b.add(b.POP, NO_ARG); + parseBlock(true, b); + return new ByteCode(curLine, b.FUNCTION, b); } - case VAR: { - if (prefix != null) { pushBackToken(); return prefix; } - ByteCode b = new ByteCode(curLine); - b.add(b.THIS, NO_ARG); - while(true) { - consume(NAME); - String name = string; - b.add(b.DECLARE, name); - if (peekToken() == ASSIGN) { - b.add(b.LITERAL, name); - consume(ASSIGN); - b.add(b.EXPR, parseMaximalExpr()); - b.add(b.PUT, NO_ARG); - b.add(b.POP, NO_ARG); - } - if (peekToken() != COMMA) break; - consume(COMMA); - } - return b; - } - - case IN: pushBackToken(); return prefix; - - case IF: { - if (prefix != null) { pushBackToken(); return prefix; } - ByteCode b = new ByteCode(curLine); - consume(LP); - b.add(b.EXPR, parseMaximalExpr()); - consume(RP); - b.add(b.JF, new Integer(3)); - b.add(b.EXPR, parseBlock(false)); - b.add(b.JMP, new Integer(2)); - if (peekToken() != ELSE) return b.add(b.LITERAL, null); - consume(ELSE); - b.add(b.EXPR, parseBlock(false)); - return b; - } - // Needs break // case SWITCH: { if (prefix != null) { pushBackToken(); return prefix; } - if (getToken() != LP) throw new ParserException("expected left paren"); + consume(LP); Expr switchExpr = parseMaximalExpr(); - if (getToken() != RP) throw new ParserException("expected left paren"); - if (getToken() != LC) throw new ParserException("expected left brace"); + consume(RP); + consume(LC); ExprList toplevel = new ExprList(curLine, LC); while(true) { tok = getToken(); @@ -519,6 +568,7 @@ public class Parser extends Lexer { public static final byte DECLARE = -6; // < name > -- declare in the current scope public static final byte THIS = -7; // -- push the topmost non-transparent scope onto the stack public static final byte GET = -8; // -- get stack[0] from stack[1] + public static final byte GET_PRESERVE = -80; // -- get stack[0] from stack[1] public static final byte PUT = -9; // -- put stack[1] to key stack[0] on stack[2]; leaves object on the stack public static final byte THROW = -10; // -- throw topmost element public static final byte RETURN = -11; // -- return the topmost value on the stack @@ -562,7 +612,7 @@ public class Parser extends Lexer { public Object eval(final JS.Scope s) throws ControlTransferException, JS.Exn { return eval(s, new Parser.Thread()); } - public Object eval(JS.Scope s, Parser.Thread t) throws ControlTransferException { + public Object eval(final JS.Scope s, Parser.Thread t) throws ControlTransferException { for(int i=0; i