зеркало из https://github.com/mozilla/pjs.git
Removal of Token.UNARYOP: after the previous patches parse tree used Token.UNARYOP only to group Token.TYPEOF and Token.VOID into the same node type. Since they are very different, it is simpler to use the tokens directly as node type.
To remove ambiguity caused by re-use of Token.VOID to denote no-operation node, a new Token.EMPTY is added to denote the former usage.
This commit is contained in:
Родитель
945c6bd1ec
Коммит
807d553c04
|
@ -258,7 +258,7 @@ public class IRFactory {
|
|||
{
|
||||
Node bodyTarget = new Node(Token.TARGET);
|
||||
Node condTarget = new Node(Token.TARGET);
|
||||
if (loopType == LOOP_FOR && cond.getType() == Token.VOID) {
|
||||
if (loopType == LOOP_FOR && cond.getType() == Token.EMPTY) {
|
||||
cond = new Node(Token.TRUE);
|
||||
}
|
||||
Node IFEQ = new Node(Token.IFEQ, (Node)cond);
|
||||
|
@ -282,7 +282,7 @@ public class IRFactory {
|
|||
result.addChildToFront(GOTO);
|
||||
|
||||
if (loopType == LOOP_FOR) {
|
||||
if (init.getType() != Token.VOID) {
|
||||
if (init.getType() != Token.EMPTY) {
|
||||
if (init.getType() != Token.VAR) {
|
||||
init = new Node(Token.POP, init);
|
||||
}
|
||||
|
@ -290,7 +290,7 @@ public class IRFactory {
|
|||
}
|
||||
Node incrTarget = new Node(Token.TARGET);
|
||||
result.addChildAfter(incrTarget, body);
|
||||
if (incr.getType() != Token.VOID) {
|
||||
if (incr.getType() != Token.EMPTY) {
|
||||
incr = (Node)createUnary(Token.POP, incr);
|
||||
result.addChildAfter(incr, incrTarget);
|
||||
}
|
||||
|
@ -471,7 +471,7 @@ public class IRFactory {
|
|||
pn.addChildToBack(catchTarget);
|
||||
|
||||
// get the exception object and store it in a temp
|
||||
Node exn = createNewLocal(new Node(Token.VOID));
|
||||
Node exn = createNewLocal(new Node(Token.EMPTY));
|
||||
pn.addChildToBack(new Node(Token.POP, exn));
|
||||
|
||||
Node endCatch = new Node(Token.TARGET);
|
||||
|
@ -536,7 +536,7 @@ public class IRFactory {
|
|||
|
||||
if (hasFinally) {
|
||||
pn.addChildToBack(finallyTarget);
|
||||
Node returnTemp = createNewLocal(new Node(Token.VOID));
|
||||
Node returnTemp = createNewLocal(new Node(Token.EMPTY));
|
||||
Node popAndMake = new Node(Token.POP, returnTemp);
|
||||
pn.addChildToBack(popAndMake);
|
||||
pn.addChildToBack(finallyNode);
|
||||
|
@ -722,21 +722,21 @@ public class IRFactory {
|
|||
return new Node(Token.TRUE);
|
||||
}
|
||||
return new Node(nodeType, left, right);
|
||||
|
||||
} else if (nodeType == Token.TYPEOF) {
|
||||
if (childNode.getType() == Token.NAME) {
|
||||
childNode.setType(Token.TYPEOFNAME);
|
||||
return childNode;
|
||||
}
|
||||
}
|
||||
return new Node(nodeType, childNode);
|
||||
}
|
||||
|
||||
public Object createUnary(int nodeType, int nodeOp, Object child) {
|
||||
Node childNode = (Node) child;
|
||||
int childType = childNode.getType();
|
||||
if (nodeOp == Token.TYPEOF &&
|
||||
childType == Token.NAME)
|
||||
{
|
||||
childNode.setType(Token.TYPEOFNAME);
|
||||
return childNode;
|
||||
}
|
||||
|
||||
if (nodeType == Token.INC || nodeType == Token.DEC) {
|
||||
int childType = childNode.getType();
|
||||
|
||||
if (!hasSideEffects(childNode)
|
||||
&& (nodeOp == Token.POST)
|
||||
|
@ -768,7 +768,7 @@ public class IRFactory {
|
|||
}
|
||||
|
||||
Node result = new Node(nodeType, nodeOp);
|
||||
result.addChildToBack((Node)child);
|
||||
result.addChildToBack(childNode);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -340,7 +340,7 @@ public class Interpreter
|
|||
case Token.LOOP :
|
||||
case Token.DEFAULT :
|
||||
case Token.BLOCK :
|
||||
case Token.VOID :
|
||||
case Token.EMPTY :
|
||||
case Token.NOP :
|
||||
iCodeTop = updateLineNumber(node, iCodeTop);
|
||||
while (child != null) {
|
||||
|
@ -604,23 +604,14 @@ public class Interpreter
|
|||
case Token.NEG :
|
||||
case Token.NOT :
|
||||
case Token.BITNOT :
|
||||
case Token.TYPEOF :
|
||||
case Token.VOID :
|
||||
iCodeTop = generateICode(child, iCodeTop);
|
||||
iCodeTop = addToken(type, iCodeTop);
|
||||
break;
|
||||
|
||||
case Token.UNARYOP :
|
||||
iCodeTop = generateICode(child, iCodeTop);
|
||||
switch (node.getOperation()) {
|
||||
case Token.VOID :
|
||||
iCodeTop = addToken(Token.POP, iCodeTop);
|
||||
iCodeTop = addToken(Token.UNDEFINED, iCodeTop);
|
||||
break;
|
||||
case Token.TYPEOF :
|
||||
iCodeTop = addToken(Token.TYPEOF, iCodeTop);
|
||||
break;
|
||||
default:
|
||||
badTree(node);
|
||||
break;
|
||||
if (type == Token.VOID) {
|
||||
iCodeTop = addToken(Token.POP, iCodeTop);
|
||||
iCodeTop = addToken(Token.UNDEFINED, iCodeTop);
|
||||
} else {
|
||||
iCodeTop = addToken(type, iCodeTop);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -443,7 +443,6 @@ public class Node implements Cloneable {
|
|||
switch (type) {
|
||||
case Token.EQOP:
|
||||
case Token.RELOP:
|
||||
case Token.UNARYOP:
|
||||
return intDatum;
|
||||
}
|
||||
Context.codeBug();
|
||||
|
@ -454,7 +453,6 @@ public class Node implements Cloneable {
|
|||
switch (type) {
|
||||
case Token.EQOP:
|
||||
case Token.RELOP:
|
||||
case Token.UNARYOP:
|
||||
Context.codeBug();
|
||||
}
|
||||
return intDatum;
|
||||
|
|
|
@ -561,7 +561,7 @@ class Parser {
|
|||
decompiler.addToken(Token.LP);
|
||||
tt = ts.peekToken();
|
||||
if (tt == Token.SEMI) {
|
||||
init = nf.createLeaf(Token.VOID);
|
||||
init = nf.createLeaf(Token.EMPTY);
|
||||
} else {
|
||||
if (tt == Token.VAR) {
|
||||
// set init to a var list or initial
|
||||
|
@ -582,7 +582,7 @@ class Parser {
|
|||
decompiler.addToken(Token.SEMI);
|
||||
if (ts.peekToken() == Token.SEMI) {
|
||||
// no loop condition
|
||||
cond = nf.createLeaf(Token.VOID);
|
||||
cond = nf.createLeaf(Token.EMPTY);
|
||||
} else {
|
||||
cond = expr(ts, false);
|
||||
}
|
||||
|
@ -590,7 +590,7 @@ class Parser {
|
|||
mustMatchToken(ts, Token.SEMI, "msg.no.semi.for.cond");
|
||||
decompiler.addToken(Token.SEMI);
|
||||
if (ts.peekToken() == Token.RP) {
|
||||
incr = nf.createLeaf(Token.VOID);
|
||||
incr = nf.createLeaf(Token.EMPTY);
|
||||
} else {
|
||||
incr = expr(ts, false);
|
||||
}
|
||||
|
@ -777,7 +777,7 @@ class Parser {
|
|||
// Fall thru, to have a node for error recovery to work on
|
||||
case Token.EOL:
|
||||
case Token.SEMI:
|
||||
pn = nf.createLeaf(Token.VOID);
|
||||
pn = nf.createLeaf(Token.EMPTY);
|
||||
skipsemi = true;
|
||||
break;
|
||||
|
||||
|
@ -1108,13 +1108,10 @@ class Parser {
|
|||
ts.flags &= ~ts.TSF_REGEXP;
|
||||
|
||||
switch(tt) {
|
||||
case Token.TYPEOF:
|
||||
case Token.VOID:
|
||||
decompiler.addToken(tt);
|
||||
return nf.createUnary(Token.UNARYOP, tt, unaryExpr(ts));
|
||||
|
||||
case Token.NOT:
|
||||
case Token.BITNOT:
|
||||
case Token.TYPEOF:
|
||||
decompiler.addToken(tt);
|
||||
return nf.createUnary(tt, unaryExpr(ts));
|
||||
|
||||
|
|
|
@ -177,7 +177,8 @@ public class Token
|
|||
WITH = 98, // with keyword
|
||||
CATCH = 99, // catch keyword
|
||||
FINALLY = 100, // finally keyword
|
||||
RESERVED = 101, // reserved keywords
|
||||
VOID = 101, // void keyword
|
||||
RESERVED = 102, // reserved keywords
|
||||
|
||||
/** Added by Mike - these are JSOPs in the jsref, but I
|
||||
* don't have them yet in the java implementation...
|
||||
|
@ -186,24 +187,23 @@ public class Token
|
|||
* Most of these go in the 'op' field when returning
|
||||
* more general token types, eg. 'DIV' as the op of 'ASSIGN'.
|
||||
*/
|
||||
NOP = 102, // NOP
|
||||
PRE = 103, // for INC, DEC nodes.
|
||||
POST = 104,
|
||||
NOP = 103, // NOP
|
||||
PRE = 104, // for INC, DEC nodes.
|
||||
POST = 105,
|
||||
|
||||
/**
|
||||
* For JSOPs associated with keywords...
|
||||
* eg. op = ADD; token = ASSIGN
|
||||
*/
|
||||
|
||||
VOID = 105,
|
||||
EMPTY = 106,
|
||||
|
||||
/* types used for the parse tree - these never get returned
|
||||
* by the scanner.
|
||||
*/
|
||||
|
||||
EQOP = 106, // equality ops (== !=)
|
||||
RELOP = 107, // relational ops (< <= > >= in instanceof)
|
||||
UNARYOP = 108, // unary prefix operator
|
||||
EQOP = 107, // equality ops (== !=)
|
||||
RELOP = 108, // relational ops (< <= > >= in instanceof)
|
||||
|
||||
BLOCK = 109, // statement block
|
||||
ARRAYLIT = 110, // array literal
|
||||
|
@ -310,7 +310,6 @@ public class Token
|
|||
case AND: return "and";
|
||||
case EQOP: return "eqop";
|
||||
case RELOP: return "relop";
|
||||
case UNARYOP: return "unaryop";
|
||||
case INC: return "inc";
|
||||
case DEC: return "dec";
|
||||
case DOT: return "dot";
|
||||
|
@ -335,7 +334,7 @@ public class Token
|
|||
case NOP: return "nop";
|
||||
case PRE: return "pre";
|
||||
case POST: return "post";
|
||||
case VOID: return "void";
|
||||
case EMPTY: return "empty";
|
||||
case BLOCK: return "block";
|
||||
case ARRAYLIT: return "arraylit";
|
||||
case OBJLIT: return "objlit";
|
||||
|
|
|
@ -1041,7 +1041,7 @@ public class Codegen extends Interpreter {
|
|||
|
||||
case Token.SCRIPT:
|
||||
case Token.BLOCK:
|
||||
case Token.VOID:
|
||||
case Token.EMPTY:
|
||||
case Token.NOP:
|
||||
// no-ops.
|
||||
visitStatement(node);
|
||||
|
@ -1228,8 +1228,17 @@ public class Codegen extends Interpreter {
|
|||
addDoubleConstructor();
|
||||
break;
|
||||
|
||||
case Token.UNARYOP:
|
||||
visitUnary(node, child);
|
||||
case Token.VOID:
|
||||
generateCodeFromNode(child, node);
|
||||
addByteCode(ByteCode.POP);
|
||||
pushUndefined();
|
||||
break;
|
||||
|
||||
case Token.TYPEOF:
|
||||
generateCodeFromNode(child, node);
|
||||
addScriptRuntimeInvoke("typeof",
|
||||
"(Ljava/lang/Object;"
|
||||
+")Ljava/lang/String;");
|
||||
break;
|
||||
|
||||
case Token.TYPEOFNAME:
|
||||
|
@ -2312,29 +2321,6 @@ public class Codegen extends Interpreter {
|
|||
visitGOTO(GOTO, type, null);
|
||||
}
|
||||
|
||||
private void visitUnary(Node node, Node child)
|
||||
{
|
||||
int op = node.getOperation();
|
||||
switch (op) {
|
||||
|
||||
case Token.TYPEOF:
|
||||
generateCodeFromNode(child, node);
|
||||
addScriptRuntimeInvoke("typeof",
|
||||
"(Ljava/lang/Object;"
|
||||
+")Ljava/lang/String;");
|
||||
break;
|
||||
|
||||
case Token.VOID:
|
||||
generateCodeFromNode(child, node);
|
||||
addByteCode(ByteCode.POP);
|
||||
pushUndefined();
|
||||
break;
|
||||
|
||||
default:
|
||||
badTree();
|
||||
}
|
||||
}
|
||||
|
||||
private void visitTypeofname(Node node)
|
||||
{
|
||||
String name = node.getString();
|
||||
|
|
Загрузка…
Ссылка в новой задаче