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:
igor%mir2.org 2003-08-15 10:21:09 +00:00
Родитель 945c6bd1ec
Коммит 807d553c04
6 изменённых файлов: 47 добавлений и 76 удалений

Просмотреть файл

@ -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();