/** * Perform type propagation through a given expression, returning the type of value that is * returned by evaluating this expression. * * @param e * @param environment * @param generics * @param context * @return */ private SemanticType propagate( Expr e, HashMap<String, SemanticType> environment, HashSet<String> generics, WyalFile.Context context) { SemanticType t; if (e instanceof Expr.Variable) { t = propagate((Expr.Variable) e, environment, generics, context); } else if (e instanceof Expr.Constant) { t = propagate((Expr.Constant) e, environment, generics, context); } else if (e instanceof Expr.Unary) { t = propagate((Expr.Unary) e, environment, generics, context); } else if (e instanceof Expr.Binary) { t = propagate((Expr.Binary) e, environment, generics, context); } else if (e instanceof Expr.Ternary) { t = propagate((Expr.Ternary) e, environment, generics, context); } else if (e instanceof Expr.Nary) { t = propagate((Expr.Nary) e, environment, generics, context); } else if (e instanceof Expr.Quantifier) { t = propagate((Expr.Quantifier) e, environment, generics, context); } else if (e instanceof Expr.FunCall) { t = propagate((Expr.FunCall) e, environment, generics, context); } else if (e instanceof Expr.IndexOf) { t = propagate((Expr.IndexOf) e, environment, generics, context); } else { internalFailure("unknown expression encountered (" + e + ")", filename, e); return null; } e.attributes().add(new TypeAttribute(t)); return returnType(e); }