示例#1
0
        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);
        }