* @param arity the current number of nodes in the stack (found after the context was opened)
* @return a new node representing the node that's having it's context closed.
* @throws Exception
*/
public final SimpleNode closeNode(final SimpleNode n, final int arity) throws Exception {
exprType value;
suiteType orelseSuite;
stmtType[] body;
exprType iter;
exprType target;
if (DEBUG_TREE_BUILDER) {
System.out.println("\n\n\n---------------------------");
System.out.println("Closing node scope: " + n);
System.out.println("Arity: " + arity);
if (arity > 0) {
System.out.println("Nodes in scope: ");
for (int i = 0; i < arity; i++) {
System.out.println(stack.peekNode(i));
}
}
}
exprType[] exprs;
switch (n.getId()) {
case -1:
throw new ParseException("Illegal node found: " + n, n);
case JJTFILE_INPUT:
Module m = (Module) n;
m.body = makeStmts(arity);
return m;
case JJTFALSE:
case JJTTRUE:
case JJTNONE:
case JJTNAME:
case JJTNUM:
case JJTPASS_STMT:
case JJTBREAK_STMT:
case JJTCONTINUE_STMT:
case JJTSTRING:
case JJTUNICODE:
case JJTBINARY:
case JJTBEGIN_DECORATOR:
case JJTCOMMA:
case JJTCOLON:
return n; //it's already the correct node (and it's value is already properly set)
case JJTSUITE:
stmtType[] stmts = new stmtType[arity];
for (int i = arity - 1; i >= 0; i--) {
SimpleNode yield_or_stmt = stack.popNode();
if (yield_or_stmt instanceof Yield) {
stmts[i] = new Expr((Yield) yield_or_stmt);
} else {
try {
stmts[i] = (stmtType) yield_or_stmt;
} catch (ClassCastException e) {
recoverFromClassCastException(yield_or_stmt, e);
stmts[i] = new Pass(); //recover from it with a valid node!
}
}
}
return new Suite(stmts);
case JJTFOR_STMT:
orelseSuite = null;
if (stack.nodeArity() == 5) {
orelseSuite = popSuiteAndSuiteType();
}
body = popSuite();
iter = (exprType) stack.popNode();
target = (exprType) stack.popNode();
ctx.setStore(target);
For forStmt = (For) n;
forStmt.target = target;
forStmt.iter = iter;
forStmt.body = body;
forStmt.orelse = orelseSuite;
return forStmt;
case JJTBEGIN_ELIF_STMT:
return new If(null, null, null);
case JJTIF_STMT:
return handleIfConstruct(n, arity);
case JJTEXEC_STMT:
exprType locals = arity >= 3 ? ((exprType) stack.popNode()) : null;
exprType globals = arity >= 2 ? ((exprType) stack.popNode()) : null;
value = (exprType) stack.popNode();
Exec exec = (Exec) n;
exec.body = value;
exec.locals = locals;
exec.globals = globals;
return exec;
case JJTDECORATORS:
ArrayList<SimpleNode> list2 = new ArrayList<SimpleNode>();
ArrayList<SimpleNode> listArgs = new ArrayList<SimpleNode>();
while (stack.nodeArity() > 0) {
SimpleNode node = stack.popNode();
while (!(node instanceof decoratorsType)) {
if (node instanceof comprehensionType) {
listArgs.add(node);
listArgs.add(stack.popNode()); //target
} else if (node instanceof ComprehensionCollection) {
listArgs.add(((ComprehensionCollection) node).getGenerators()[0]);
listArgs.add(stack.popNode()); //target
} else {
listArgs.add(node);
}
node = stack.popNode();
}
listArgs.add(node);//the decoratorsType
list2.add(0, makeDecorator(listArgs));
listArgs.clear();
}
return new Decorators((decoratorsType[]) list2.toArray(new decoratorsType[0]), JJTDECORATORS);
case JJTSUBSCRIPTLIST:
sliceType[] dims = new sliceType[arity];
for (int i = arity - 1; i >= 0; i--) {
SimpleNode sliceNode = stack.popNode();
if (sliceNode instanceof sliceType) {
dims[i] = (sliceType) sliceNode;
} else if (sliceNode instanceof IdentityNode) {
//this should be ignored...
//this happens when parsing something like a[1,], whereas a[1,2] would not have this.
} else {
throw new RuntimeException("Expected a sliceType or an IdentityNode. Received :"
+ sliceNode.getClass());
}
}
return new ExtSlice(dims);
case JJTAUG_PLUS:
case JJTAUG_MINUS:
case JJTAUG_MULTIPLY:
case JJTAUG_DIVIDE:
case JJTAUG_MODULO:
case JJTAUG_AND:
case JJTAUG_OR:
case JJTAUG_XOR:
case JJTAUG_LSHIFT:
case JJTAUG_RSHIFT:
case JJTAUG_POWER:
case JJTAUG_FLOORDIVIDE:
AugAssign augAssign = (AugAssign) n;
exprType value1 = (exprType) stack.popNode();
exprType target1 = (exprType) stack.popNode();
ctx.setAugStore(target1);
augAssign.target = target1;
augAssign.value = value1;
return n;
case JJTOR_BOOLEAN:
return new BoolOp(BoolOp.Or, makeExprs());
case JJTAND_BOOLEAN:
return new BoolOp(BoolOp.And, makeExprs());
case JJTCOMPARISION:
if (arity <= 2) {
throw new ParseException("Internal error: To make a compare, at least 3 nodes are needed.", n);
}
int l = arity / 2;
exprType[] comparators = new exprType[l];
int[] ops = new int[l];
for (int i = l - 1; i >= 0; i--) {
comparators[i] = (exprType) stack.popNode();
SimpleNode op = stack.popNode();
switch (op.getId()) {
case JJTLESS_CMP:
ops[i] = Compare.Lt;
break;
case JJTGREATER_CMP:
ops[i] = Compare.Gt;
break;
case JJTEQUAL_CMP:
ops[i] = Compare.Eq;
break;
case JJTGREATER_EQUAL_CMP:
ops[i] = Compare.GtE;
break;
case JJTLESS_EQUAL_CMP:
ops[i] = Compare.LtE;
break;
case JJTNOTEQUAL_CMP:
ops[i] = Compare.NotEq;
break;
case JJTIN_CMP:
ops[i] = Compare.In;
break;
case JJTNOT_IN_CMP:
ops[i] = Compare.NotIn;
break;
case JJTIS_NOT_CMP:
ops[i] = Compare.IsNot;
break;
case JJTIS_CMP:
ops[i] = Compare.Is;
break;
default:
throw new RuntimeException("Unknown cmp op:" + op.getId());
}
}
return new Compare(((exprType) stack.popNode()), ops, comparators);
case JJTLESS_CMP:
case JJTGREATER_CMP:
case JJTEQUAL_CMP:
case JJTGREATER_EQUAL_CMP:
case JJTLESS_EQUAL_CMP:
case JJTNOTEQUAL_CMP:
case JJTIN_CMP:
case JJTNOT_IN_CMP:
case JJTIS_NOT_CMP:
case JJTIS_CMP:
return n;
case JJTOR_2OP:
case JJTXOR_2OP:
case JJTAND_2OP:
case JJTLSHIFT_2OP:
case JJTRSHIFT_2OP:
case JJTADD_2OP:
case JJTSUB_2OP:
case JJTMUL_2OP:
case JJTDIV_2OP:
case JJTMOD_2OP:
case JJTPOW_2OP:
case JJTFLOORDIV_2OP:
BinOp op = (BinOp) n;
exprType right = (exprType) stack.popNode();
exprType left = (exprType) stack.popNode();
op.right = right;
op.left = left;
return n;
case JJTPOS_1OP: