private Expression CompileIterationSum(int lambdaLevel) { PushPosition(); Move(); SkipPunctuation("("); List <IterationSumVariable> variables = new List <IterationSumVariable>(); Expression body; while (true) { bool isVariable; PushPosition(); Move(); isVariable = IsPunctuationOf(":"); Pos = PeekPos(); if (isVariable) { if (!IsWord) { ThrowException("Expecting iteration variable name."); } string variableName = GetWord(); Move(); SkipPunctuation(":"); Expression from = Compile(lambdaLevel); SkipPunctuation("->"); Expression to = Compile(lambdaLevel); SkipPunctuation(","); variables.Add(new IterationSumVariable() { From = from, To = to, Name = variableName }); } else { body = Compile(lambdaLevel); SkipPunctuation(")"); break; } } Expression result = new IterationSumExpression(variables.ToArray(), body, PeekPos(), Pos); PopPosition(); return(result); }
private void CheckIterationSumExpression(IterationSumExpression e, TypeCheckingContext context) { foreach (IterationSumVariable variable in e.Variables) { PerformTypeChecking(variable.From, context); PerformTypeChecking(variable.To, context); if (!Types.IsNumberType(variable.From.Type)) { context.ErrorProvider.ThrowException(string.Format("Start value of {0} is not number.", variable.Name), e); } if (!Types.IsNumberType(variable.To.Type)) { context.ErrorProvider.ThrowException(string.Format("End value of {1} is not number.", variable.Name), e); } context.VariableContext.Set(variable.Name, 0); } PerformTypeChecking(e.Body, context); foreach (IterationSumVariable variable in e.Variables) { context.VariableContext.Remove(variable.Name); } if (!Types.IsNumberType(e.Body.Type)) { context.ErrorProvider.ThrowException("Can only perform iteration sum on an expression of number type.", e); } e.Type = typeof(double); }
private object EvaluateIterationSumExpression(IterationSumExpression e, VariableContext context) { int[] values = new int[e.Variables.Length]; int[] fromValues = new int[e.Variables.Length]; int[] toValues = new int[e.Variables.Length]; int index = 0; foreach (IterationSumVariable variable in e.Variables) { if (context.HasVariable(variable.Name)) { throw new Exception(string.Format("Iteration variable {0} is already in use.", variable.Name)); } fromValues[index] = Types.ConvertValue <int>(Evaluate(variable.From, context)); toValues[index] = Types.ConvertValue <int>(Evaluate(variable.To, context)); context.Set(variable.Name, fromValues[index]); values[index] = fromValues[index]; index++; } double sum = 0; while (true) { double value = Types.ConvertValue <double>(Evaluate(e.Body, context));; if (!double.IsNaN(value)) { sum += value; } if (!IncreaseIterationValues(values, fromValues, toValues)) { break; } else { for (int i = 0; i <= e.Variables.Length - 1; i++) { context.Set(e.Variables[i].Name, values[i]); } } } foreach (IterationSumVariable variable in e.Variables) { context.Remove(variable.Name); } return(sum); }