private VerificationResult CompareStacks(Label label, SigilTuple<bool, LinqStack<LinqList<TypeOnStack>>> actual, SigilTuple<bool, LinqStack<LinqList<TypeOnStack>>> expected) { if (!actual.Item1 && !expected.Item1) { if (expected.Item2.Count != actual.Item2.Count) { // Both stacks are based, so the wrong size is a serious error as well return VerificationResult.FailureUnderflow(label, expected.Item2.Count); } } for (var i = 0; i < expected.Item2.Count; i++) { if (i >= actual.Item2.Count && !actual.Item1) { // actual is based and expected wanted a value, this is an UNDERFLOW return VerificationResult.FailureUnderflow(label, expected.Item2.Count); } var expectedTypes = expected.Item2.ElementAt(i); LinqList<TypeOnStack> actualTypes; if (i < actual.Item2.Count) { actualTypes = actual.Item2.ElementAt(i); } else { // Underflowed, but our actual stack is baseless; so we assume we're good until proven otherwise break; } bool typesMatch = false; foreach (var a in actualTypes.AsEnumerable()) { foreach (var e in expectedTypes.AsEnumerable()) { typesMatch |= e.IsAssignableFrom(a); } } if (!typesMatch) { // Just went through what's on the stack, and we the types are known to not be compatible return VerificationResult.FailureTypeMismatch(label, actualTypes, expectedTypes); } } return null; }