/** * Determine the operator that will be used with this operator node. The method gets the operand * types of this node and determines the operator, that will need the least implicit type casts * using the operands' types (this is done via {@link Operator#getNearest(int, TypeNode[])}). If * no such operator is found, an error message is reported. * * @return The proper operator for this node, <code>null</code> otherwise. */ private OperatorSignature computeOperator() { OperatorSignature operator = null; int n = children.size(); TypeNode[] argTypes = new TypeNode[n]; for (int i = 0; i < n; i++) { ExprNode op = children.get(i); TypeNode type = op.getType(); if (type instanceof NodeTypeNode || type instanceof EdgeTypeNode) type = OperatorSignature.TYPE; if (type instanceof ExternalTypeNode && argTypes.length < 3) // keep real ext type for cond type = OperatorSignature.TYPE; if (type instanceof ByteTypeNode || type instanceof ShortTypeNode) if (n < 3) type = BasicTypeNode.intType; argTypes[i] = type; } operator = OperatorSignature.getNearest(opId, argTypes); if (!operator.isValid()) { StringBuffer params = new StringBuffer(); boolean errorReported = false; params.append('('); for (int i = 0; i < n; i++) { if (argTypes[i].isEqual(BasicTypeNode.errorType)) { errorReported = true; } else { params.append((i > 0 ? ", " : "") + argTypes[i].toString()); } } params.append(')'); if (!errorReported) { reportError("No such operator " + OperatorSignature.getName(opId) + params); } } else { // Insert implicit type casts for the arguments that need them. TypeNode[] opTypes = operator.getOperandTypes(); assert (opTypes.length == argTypes.length); for (int i = 0; i < argTypes.length; i++) { if (!argTypes[i].isEqual(opTypes[i])) { ExprNode child = children.get(i); ExprNode adjusted = child.adjustType(opTypes[i]); becomeParent(adjusted); children.set(i, adjusted); } } } return operator; }
/** @see de.unika.ipd.grgen.ast.BaseNode#checkLocal() */ @Override protected boolean checkLocal() { boolean res = true; TypeNode type = getType(); int arity = OperatorSignature.getArity(opId); if (children.size() != arity) { reportError("Wrong operator arity: " + children.size()); res = false; } // Here the error must have been already reported if (type.isEqual(BasicTypeNode.errorType)) res = false; return res; }