bool IPatternVisitor <bool> .Visit(UnionPattern expr) { // if this union case has never been matched, add it bool covered = false; if (!mCoveredValues.ContainsKey(expr.Name)) { var matchedCase = ((Union)mMatchType).Cases.First(unionCase => unionCase.Name == expr.Name); mCoveredValues[expr.Name] = new Coverage(matchedCase.ValueType.Bound); } else { // union case already present, so we may be covered covered = true; } // if we have a value for the case, recurse in to cover it if (expr.Value != null) { covered = mCoveredValues[expr.Name].CoverPattern(expr.Value); } // if we have all cases, and all of their values are covered, we're covered if ((mCoveredValues.Count == ((Union)mMatchType).Cases.Count) && mCoveredValues.Values.All(cover => cover.FullyCovered)) { FullyCovered = true; } return(covered); }
IUnboundExpr IPatternVisitor <IUnboundExpr> .Visit(UnionPattern expr) { var unionDecl = (Union)mDecl; var unionCase = unionDecl.Cases.First(thisCase => thisCase.Name == expr.Name); // create an expression to match the union case var matchExpr = mC.Call(unionCase.Name + "?", mValue); // match the value if (expr.Value != null) { // create an expression to pull out the union value var unionValue = mC.Call(unionCase.Name + "Value", mValue); // match it var matchValue = Match(mContext, unionCase.ValueType.Bound, expr.Value, unionValue, mVariables); if (matchValue != null) { // combine with the previous check matchExpr = mC.Op(matchExpr, "&", matchValue); } } return(matchExpr); }
bool IPatternVisitor <bool> .Visit(UnionPattern expr) { var union = mType as Union; // it must be a union if (union == null) { throw new CompileException(expr.Position, String.Format("A union case pattern cannot be used to match against a value of type {0}.", mType)); } // and it must be a valid case var unionCase = union.Cases.FirstOrDefault(it => it.Name == expr.Name); if (unionCase == null) { throw new CompileException(expr.Position, String.Format("Union type {0} does not have a case named {1}.", union.Name, expr.Name)); } // and the value must match if (unionCase.ValueType.Bound == Decl.Unit) { if (expr.Value != null) { throw new CompileException(expr.Position, String.Format("Union case {0} does not expect a value.", unionCase.Name)); } } else { if (expr.Value == null) { throw new CompileException(expr.Position, String.Format("Union case {0} expects a value.", unionCase.Name)); } expr.Value.Accept(new ShapeChecker(unionCase.ValueType.Bound, mUsedVariables)); } return(true); }