Beispiel #1
0
        /// <summary>
        /// Evaluates the node, using the variables provided in the <paramref name="Variables"/> collection.
        /// </summary>
        /// <param name="Variables">Variables collection.</param>
        /// <returns>Result.</returns>
        public override IElement Evaluate(Variables Variables)
        {
            ICommutativeRingWithIdentityElement From = this.left.Evaluate(Variables) as ICommutativeRingWithIdentityElement;

            if (From is null)
            {
                throw new ScriptRuntimeException("Invalid range.", this);
            }

            ICommutativeRingWithIdentityElement To = this.middle.Evaluate(Variables) as ICommutativeRingWithIdentityElement;

            if (To is null)
            {
                throw new ScriptRuntimeException("Invalid range.", this);
            }

            IOrderedSet S = From.AssociatedSet as IOrderedSet;

            if (S is null)
            {
                throw new ScriptRuntimeException("Cannot compare range.", this);
            }

            IElement Step, Last;
            int      Direction = S.Compare(From, To);
            bool     Done;

            if (!(this.middle2 is null))
            {
                Step = this.middle2.Evaluate(Variables);

                if (Direction < 0)
                {
                    if (S.Compare(Step, From.Zero) <= 0)
                    {
                        throw new ScriptRuntimeException("Invalid step size for corresponding range.", this);
                    }
                }
                else if (Direction > 0)
                {
                    if (S.Compare(Step, From.Zero) >= 0)
                    {
                        throw new ScriptRuntimeException("Invalid step size for corresponding range.", this);
                    }
                }
            }
Beispiel #2
0
        /// <summary>
        /// Increments a value.
        /// </summary>
        /// <param name="Value">Value to increment.</param>
        /// <param name="Node">Node performing the evaluation.</param>
        /// <returns>Incremented value.</returns>
        public static IElement Increment(IElement Value, ScriptNode Node)
        {
            ICommutativeRingWithIdentityElement e = Value as ICommutativeRingWithIdentityElement;

            if (e != null)
            {
                return(Operators.Arithmetics.Add.EvaluateAddition(Value, e.One, Node));
            }
            else if (Value.IsScalar)
            {
                throw new ScriptRuntimeException("Unable to increment variable.", Node);
            }
            else
            {
                LinkedList <IElement> Elements = new LinkedList <IElement>();

                foreach (IElement Element in Value.ChildElements)
                {
                    Elements.AddLast(Increment(Element, Node));
                }

                return(Value.Encapsulate(Elements, Node));
            }
        }
Beispiel #3
0
        /// <summary>
        /// Evaluates the node, using the variables provided in the <paramref name="Variables"/> collection.
        /// </summary>
        /// <param name="Variables">Variables collection.</param>
        /// <returns>Result.</returns>
        public override IElement Evaluate(Variables Variables)
        {
            ICommutativeRingWithIdentityElement From = this.left.Evaluate(Variables) as ICommutativeRingWithIdentityElement;

            if (From == null)
            {
                throw new ScriptRuntimeException("Invalid range.", this);
            }

            ICommutativeRingWithIdentityElement To = this.middle.Evaluate(Variables) as ICommutativeRingWithIdentityElement;

            if (To == null)
            {
                throw new ScriptRuntimeException("Invalid range.", this);
            }

            IOrderedSet S = From.AssociatedSet as IOrderedSet;

            if (S == null)
            {
                throw new ScriptRuntimeException("Cannot compare range.", this);
            }

            IElement Step;
            int      Direction = S.Compare(From, To);
            bool     Done;

            if (this.middle2 != null)
            {
                Step = this.middle2.Evaluate(Variables);

                if (Direction < 0)
                {
                    if (S.Compare(Step, From.Zero) <= 0)
                    {
                        throw new ScriptRuntimeException("Invalid step size for corresponding range.", this);
                    }
                }
                else if (Direction > 0)
                {
                    if (S.Compare(Step, From.Zero) >= 0)
                    {
                        throw new ScriptRuntimeException("Invalid step size for corresponding range.", this);
                    }
                }
            }
            else
            {
                if (Direction <= 0)
                {
                    Step = From.One;
                }
                else
                {
                    Step = From.One.Negate();
                }
            }

            LinkedList <IElement> Elements = new LinkedList <IElement>();

            do
            {
                Variables[this.variableName] = From;
                Elements.AddLast(this.right.Evaluate(Variables));

                if (Direction == 0)
                {
                    Done = true;
                }
                else
                {
                    From = Operators.Arithmetics.Add.EvaluateAddition(From, Step, this) as ICommutativeRingWithIdentityElement;
                    if (From == null)
                    {
                        throw new ScriptRuntimeException("Invalid step size.", this);
                    }

                    if (Direction > 0)
                    {
                        Done = S.Compare(From, To) < 0;
                    }
                    else
                    {
                        Done = S.Compare(From, To) > 0;
                    }
                }
            }while (!Done);

            return(this.Encapsulate(Elements));
        }
Beispiel #4
0
        /// <summary>
        /// Calculates Left ^ Right.
        /// </summary>
        /// <param name="Left">Left operand.</param>
        /// <param name="Right">Right operand.</param>
        /// <param name="Node">Node performing the operation.</param>
        /// <returns>Result</returns>
        public static IElement EvaluatePower(IElement Left, IElement Right, ScriptNode Node)
        {
            DoubleNumber DL = Left as DoubleNumber;
            DoubleNumber DR = Right as DoubleNumber;

            if (DL != null && DR != null)
            {
                return(new DoubleNumber(Math.Pow(DL.Value, DR.Value)));
            }

            IRingElement LE = Left as IRingElement;

            if (LE != null && DR != null)
            {
                double d = DR.Value;
                if (d >= long.MinValue && d <= long.MaxValue && Math.Truncate(d) == d)
                {
                    long n = (long)d;

                    if (n < 0)
                    {
                        LE = LE.Invert();
                        if (LE == null)
                        {
                            throw new ScriptRuntimeException("Base element not invertible.", Node);
                        }

                        n = -n;
                    }
                    else if (n == 0)
                    {
                        ICommutativeRingWithIdentityElement LE2 = LE as ICommutativeRingWithIdentityElement;
                        if (LE2 == null)
                        {
                            throw new ScriptRuntimeException("Base element ring does not have unity.", Node);
                        }

                        return(LE2.One);
                    }

                    IRingElement Result = null;

                    while (n > 0)
                    {
                        if ((n & 1) == 1)
                        {
                            if (Result == null)
                            {
                                Result = LE;
                            }
                            else
                            {
                                Result = (IRingElement)Multiply.EvaluateMultiplication(Result, LE, Node);
                            }
                        }

                        n >>= 1;
                        if (n > 0)
                        {
                            LE = (IRingElement)Multiply.EvaluateMultiplication(LE, LE, Node);
                        }
                    }

                    return(Result);
                }
                else
                {
                    throw new ScriptRuntimeException("Exponent too large.", Node);
                }
            }

            if (Left.IsScalar)
            {
                if (Right.IsScalar)
                {
                    throw new ScriptRuntimeException("Power operation could not be computed.", Node);
                }
                else
                {
                    LinkedList <IElement> Elements = new LinkedList <IElement>();

                    foreach (IElement RightChild in Right.ChildElements)
                    {
                        Elements.AddLast(EvaluatePower(Left, RightChild, Node));
                    }

                    return(Right.Encapsulate(Elements, Node));
                }
            }
            else
            {
                if (Right.IsScalar)
                {
                    LinkedList <IElement> Elements = new LinkedList <IElement>();

                    foreach (IElement LeftChild in Left.ChildElements)
                    {
                        Elements.AddLast(EvaluatePower(LeftChild, Right, Node));
                    }

                    return(Left.Encapsulate(Elements, Node));
                }
                else
                {
                    ICollection <IElement> LeftChildren  = Left.ChildElements;
                    ICollection <IElement> RightChildren = Right.ChildElements;

                    if (LeftChildren.Count == RightChildren.Count)
                    {
                        LinkedList <IElement>  Elements = new LinkedList <IElement>();
                        IEnumerator <IElement> eLeft    = LeftChildren.GetEnumerator();
                        IEnumerator <IElement> eRight   = RightChildren.GetEnumerator();

                        try
                        {
                            while (eLeft.MoveNext() && eRight.MoveNext())
                            {
                                Elements.AddLast(EvaluatePower(eLeft.Current, eRight.Current, Node));
                            }
                        }
                        finally
                        {
                            eLeft.Dispose();
                            eRight.Dispose();
                        }

                        return(Left.Encapsulate(Elements, Node));
                    }
                    else
                    {
                        LinkedList <IElement> LeftResult = new LinkedList <IElement>();

                        foreach (IElement LeftChild in LeftChildren)
                        {
                            LinkedList <IElement> RightResult = new LinkedList <IElement>();

                            foreach (IElement RightChild in RightChildren)
                            {
                                RightResult.AddLast(EvaluatePower(LeftChild, RightChild, Node));
                            }

                            LeftResult.AddLast(Right.Encapsulate(RightResult, Node));
                        }

                        return(Left.Encapsulate(LeftResult, Node));
                    }
                }
            }
        }