static ExpressionList GenerateMethodCallParameters(IEnumerable <TypeAssertionAttribute> typeAssertions, PrimitiveAttribute primitiveInformation) { IEnumerable <Expression> Parameters(ParameterExpression input) => Enumerable .Range(0, primitiveInformation.InputCount) .Select(x => Property(input, "Item", Constant(x))); List <Expression> GenerateCallParameterCasts(ExpressionList parameters) => parameters.Select((expression, index) => { if (!(typeAssertions.FirstOrDefault(x => x.Index == index) is TypeAssertionAttribute assertion)) { return(expression); }
static Expression GenerateParameterCountCheck(PrimitiveAttribute primitive , IEnumerable <TypeAssertionAttribute> typeAssertions) { var expectedCount = Constant(primitive.InputCount); var optionalParameters = typeAssertions.Count(x => x.Optional); Expression countPredicate = null; var difference = ""; if (optionalParameters == 0) { if (primitive.InputCount != 0) { countPredicate = LessThan(ArgumentCount, expectedCount); difference = "Not enough"; } if (!primitive.Variadic) { var compareInputWithExpected = NotEqual(ArgumentCount, expectedCount); if (countPredicate == null) { difference = "Too many"; countPredicate = compareInputWithExpected; } else { difference += " or too many"; countPredicate = Or(countPredicate, compareInputWithExpected); } } } else { difference = "Not enough or too many"; countPredicate = Or(GreaterThan(ArgumentCount, expectedCount) , LessThan(ArgumentCount, Constant(primitive.InputCount - optionalParameters))); } return(countPredicate == null ? Empty() : (Expression)Block( #if DebugCallMethods Call(null, typeof(Console).GetMethod("Write", new[] { typeof(string) }), Constant($"The function {primitive.PrimitiveName} has input count {primitive.InputCount} and receives ")), Call(null, typeof(Console).GetMethod("WriteLine", new[] { typeof(int) }), realCount), Call(null, typeof(Console).GetMethod("Write", new[] { typeof(string) }), Constant("With Input ")), Call(null, typeof(Console).GetMethod("WriteLine", new[] { typeof(object) }), Input), #endif ThrowIF(countPredicate, $"{difference} arguments for combiner '{primitive.PrimitiveName}'"))); }