@Override protected boolean checkLocal() { TypeNode targetType = targetExpr.getType(); if (!(targetType instanceof MapTypeNode)) { targetExpr.reportError("This argument to map range expression must be of type map<S,T>"); return false; } return true; }
/** * 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; }
/** * Check the types of this cast. Check if the expression can be casted to the given type. * * @see de.unika.ipd.grgen.ast.BaseNode#typeCheckLocal() */ private boolean typeCheckLocal() { TypeNode fromType = expr.getType(); if (fromType instanceof NodeTypeNode && type instanceof NodeTypeNode) { // we support up- and down-casts, but no cross-casts of nodes HashSet<TypeNode> supertypesOfFrom = new HashSet<TypeNode>(); ((NodeTypeNode) fromType).doGetCompatibleToTypes(supertypesOfFrom); HashSet<TypeNode> supertypesOfTo = new HashSet<TypeNode>(); ((NodeTypeNode) type).doGetCompatibleToTypes(supertypesOfTo); return fromType.equals(type) || supertypesOfFrom.contains(type) || supertypesOfTo.contains(fromType); } if (fromType instanceof EdgeTypeNode && type instanceof EdgeTypeNode) { // we support up- and down-casts, but no cross-casts of edges HashSet<TypeNode> supertypesOfFrom = new HashSet<TypeNode>(); ((EdgeTypeNode) fromType).doGetCompatibleToTypes(supertypesOfFrom); HashSet<TypeNode> supertypesOfTo = new HashSet<TypeNode>(); ((EdgeTypeNode) type).doGetCompatibleToTypes(supertypesOfTo); return fromType.equals(type) || supertypesOfFrom.contains(type) || supertypesOfTo.contains(fromType); } if (fromType instanceof ObjectTypeNode && !(type instanceof NodeTypeNode) && !(type instanceof EdgeTypeNode)) return true; // object is castable to anything besides nodes and edges if (type instanceof ObjectTypeNode && !(fromType instanceof NodeTypeNode) && !(fromType instanceof EdgeTypeNode)) return true; // anything besides nodes and edges can be casted into an object if (fromType instanceof ExternalTypeNode && type instanceof ExternalTypeNode) { // we support up- and down-casts, but no cross-casts of external types HashSet<TypeNode> supertypesOfFrom = new HashSet<TypeNode>(); ((ExternalTypeNode) fromType).doGetCompatibleToTypes(supertypesOfFrom); HashSet<TypeNode> supertypesOfTo = new HashSet<TypeNode>(); ((ExternalTypeNode) type).doGetCompatibleToTypes(supertypesOfTo); return fromType.equals(type) || supertypesOfFrom.contains(type) || supertypesOfTo.contains(fromType); } boolean result = fromType.isCastableTo(type); if (!result) { reportError("Illegal cast from \"" + expr.getType() + "\" to \"" + type + "\""); } return result; }
/** * Tries to simplify this node by simplifying the target expression and, if the expression is a * constant, applying the cast. * * @return The possibly simplified value of the expression. */ @Override public ExprNode evaluate() { assert isResolved(); expr = expr.evaluate(); return expr instanceof ConstNode ? ((ConstNode) expr).castTo(type) : this; }
/** @see de.unika.ipd.grgen.ast.BaseNode#checkLocal() */ @Override protected boolean checkLocal() { if (!(nodeType.getType() instanceof NodeTypeNode)) { reportError("argument of nodes(.) must be a node type"); return false; } return true; }
@Override protected IR constructIR() { return new NodesExpr(nodeType.checkIR(Expression.class), getType().getType()); }
@Override protected IR constructIR() { return new MapRangeExpr(targetExpr.checkIR(Expression.class), getType().getType()); }
@Override public TypeNode getType() { return SetTypeNode.getSetType(((MapTypeNode) targetExpr.getType()).valueTypeUnresolved); }