示例#1
0
        /// <summary>
        /// Execute an operator.
        /// </summary>
        /// <param name="op">The operator.</param>
        protected override void ExecuteOperator(Operator op)
        {
            Derivatives <Expression> a, b;

            switch (op)
            {
            case TernaryOperator to:
                b = _stack.Pop();
                a = _stack.Pop();
                _stack.Push(_stack.Pop().IfThenElse(a, b));
                break;

            case ClosingTernaryOperator _:
                break;

            case FunctionOperator fo:

                // Extract all arguments for the method
                var arguments = new Derivatives <Expression> [fo.Arguments];
                for (var i = fo.Arguments - 1; i >= 0; i--)
                {
                    arguments[i] = _stack.Pop();
                }
                var args = new FunctionFoundEventArgs <Derivatives <Expression> >(fo.Name, null, arguments);

                // Ask around for the result of this method
                FunctionFound?.Invoke(this, args);
                if (!args.Found || args.Result == null)
                {
                    throw new ParserException("Unrecognized method '{0}()'".FormatString(fo.Name), Input, Index);
                }
                _stack.Push(args.Result);
                break;

            case BracketOperator _:
                break;

            case ArgumentOperator _:
                break;

            case ArithmeticOperator ao:
                switch (ao.Type)
                {
                case OperatorType.Positive:
                    break;

                case OperatorType.Negative:
                    _stack.Push(_stack.Pop().Negate());
                    break;

                case OperatorType.Not:
                    _stack.Push(_stack.Pop().Not());
                    break;

                case OperatorType.Add:
                    b = _stack.Pop();
                    _stack.Push(_stack.Pop().Add(b));
                    break;

                case OperatorType.Subtract:
                    b = _stack.Pop();
                    _stack.Push(_stack.Pop().Subtract(b));
                    break;

                case OperatorType.Multiply:
                    b = _stack.Pop();
                    _stack.Push(_stack.Pop().Multiply(b));
                    break;

                case OperatorType.Divide:
                    b = _stack.Pop();
                    _stack.Push(_stack.Pop().Divide(b));
                    break;

                case OperatorType.Power:
                    b = _stack.Pop();
                    _stack.Push(_stack.Pop().Pow(b));
                    break;

                case OperatorType.ConditionalOr:
                    b = _stack.Pop();
                    _stack.Push(_stack.Pop().Or(b));
                    break;

                case OperatorType.ConditionalAnd:
                    b = _stack.Pop();
                    _stack.Push(_stack.Pop().And(b));
                    break;

                case OperatorType.GreaterThan:
                    b = _stack.Pop();
                    _stack.Push(_stack.Pop().GreaterThan(b));
                    break;

                case OperatorType.LessThan:
                    b = _stack.Pop();
                    _stack.Push(_stack.Pop().LessThan(b));
                    break;

                case OperatorType.GreaterThanOrEqual:
                    b = _stack.Pop();
                    _stack.Push(_stack.Pop().GreaterOrEqual(b));
                    break;

                case OperatorType.LessThanOrEqual:
                    b = _stack.Pop();
                    _stack.Push(_stack.Pop().LessOrEqual(b));
                    break;

                case OperatorType.IsEqual:
                    b = _stack.Pop();
                    _stack.Push(_stack.Pop().Equal(b));
                    break;

                case OperatorType.IsNotEqual:
                    b = _stack.Pop();
                    _stack.Push(_stack.Pop().NotEqual(b));
                    break;

                default:
                    throw new ParserException("Unimplemented arithmetic operator", Input, Index);
                }
                break;

            default:
                throw new ParserException("Unimplemented operator", Input, Index);
            }
        }
示例#2
0
        /// <summary>
        /// Execute an operator.
        /// </summary>
        /// <param name="op">The operator.</param>
        protected override void ExecuteOperator(Operator op)
        {
            Expression a, b;

            switch (op)
            {
            case TernaryOperator to:
                b = _stack.Pop();
                a = _stack.Pop();
                _stack.Push(Expression.Condition(_stack.Pop(), a, b));
                break;

            case ClosingTernaryOperator _:
                break;

            case FunctionOperator fo:

                // Extract all arguments for the method
                var arguments = new Expression[fo.Arguments];
                for (var i = fo.Arguments - 1; i >= 0; i--)
                {
                    arguments[i] = _stack.Pop();
                }
                var args = new FunctionFoundEventArgs <Expression>(fo.Name, null, arguments);

                // Ask around for the result of this method
                FunctionFound?.Invoke(this, args);
                if (args.Result == null)
                {
                    throw new ParserException("Unrecognized method '{0}()'".FormatString(fo.Name), Input, Index);
                }
                _stack.Push(args.Result);
                break;

            case BracketOperator _:
                break;

            case ArgumentOperator _:
                break;

            case ArithmeticOperator ao:
                switch (ao.Type)
                {
                case OperatorType.Positive:
                    break;

                case OperatorType.Negative:
                    _stack.Push(Expression.Negate(_stack.Pop()));
                    break;

                case OperatorType.Not:
                    _stack.Push(Expression.Condition(Expression.Equal(_stack.Pop(), Zero), Zero, One));
                    break;

                case OperatorType.Add:
                    a = _stack.Pop();
                    _stack.Push(Expression.Add(_stack.Pop(), a));
                    break;

                case OperatorType.Subtract:
                    a = _stack.Pop();
                    _stack.Push(Expression.Subtract(_stack.Pop(), a));
                    break;

                case OperatorType.Multiply:
                    _stack.Push(Expression.Multiply(_stack.Pop(), _stack.Pop()));
                    break;

                case OperatorType.Divide:
                    a = _stack.Pop();
                    _stack.Push(Expression.Divide(_stack.Pop(), a));
                    break;

                case OperatorType.Modulo:
                    a = _stack.Pop();
                    _stack.Push(Expression.Modulo(_stack.Pop(), a));
                    break;

                case OperatorType.Power:
                    a = _stack.Pop();
                    _stack.Push(Expression.Call(PowInfo, _stack.Pop(), a));
                    break;

                case OperatorType.ConditionalOr:
                    b = _stack.Pop();
                    a = _stack.Pop();
                    _stack.Push(Expression.Condition(Expression.And(
                                                         Expression.Equal(a, Zero),
                                                         Expression.Equal(b, Zero)), Zero, One));
                    break;

                case OperatorType.ConditionalAnd:
                    b = _stack.Pop();
                    a = _stack.Pop();
                    _stack.Push(Expression.Condition(Expression.Or(
                                                         Expression.Equal(a, Zero),
                                                         Expression.Equal(b, Zero)), Zero, One));
                    break;

                case OperatorType.GreaterThan:
                    a = _stack.Pop();
                    _stack.Push(Expression.GreaterThan(_stack.Pop(), a));
                    break;

                case OperatorType.LessThan:
                    a = _stack.Pop();
                    _stack.Push(Expression.LessThan(_stack.Pop(), a));
                    break;

                case OperatorType.GreaterThanOrEqual:
                    a = _stack.Pop();
                    _stack.Push(Expression.GreaterThanOrEqual(_stack.Pop(), a));
                    break;

                case OperatorType.LessThanOrEqual:
                    a = _stack.Pop();
                    _stack.Push(Expression.LessThanOrEqual(_stack.Pop(), a));
                    break;

                case OperatorType.OpenTernary:

                default:
                    throw new ParserException("Unimplemented arithmetic operator", Input, Index);
                }
                break;

            default:
                throw new ParserException("Unimplemented operator", Input, Index);
            }
        }
示例#3
0
        /// <summary>
        /// Execute an operator.
        /// </summary>
        /// <param name="op">The operator.</param>
        protected override void ExecuteOperator(Operator op)
        {
            double a, b;

            switch (op)
            {
            case TernaryOperator to:
                b = _stack.Pop();
                a = _stack.Pop();
                _stack.Push(_stack.Pop().Equals(0.0) ? b : a);
                break;

            case ClosingTernaryOperator _:
                break;

            case FunctionOperator fo:

                // Extract all arguments for the method
                var arguments = new double[fo.Arguments];
                for (var i = fo.Arguments - 1; i >= 0; i--)
                {
                    arguments[i] = _stack.Pop();
                }
                var args = new FunctionFoundEventArgs <double>(fo.Name, double.NaN, arguments);

                // Ask around for the result of this method
                FunctionFound?.Invoke(this, args);
                if (!args.Found)
                {
                    throw new ParserException("Unrecognized method '{0}()'".FormatString(fo.Name), Input, Index);
                }
                _stack.Push(args.Result);
                break;

            case BracketOperator _:
                break;

            case ArgumentOperator _:
                break;

            case ArithmeticOperator ao:
                switch (ao.Type)
                {
                case OperatorType.Positive:
                    break;

                case OperatorType.Negative:
                    _stack.Push(-_stack.Pop());
                    break;

                case OperatorType.Not:
                    _stack.Push(_stack.Pop().Equals(0.0) ? 0.0 : 1.0);
                    break;

                case OperatorType.Add:
                    _stack.Push(_stack.Pop() + _stack.Pop());
                    break;

                case OperatorType.Subtract:
                    a = _stack.Pop();
                    _stack.Push(_stack.Pop() - a);
                    break;

                case OperatorType.Multiply:
                    _stack.Push(_stack.Pop() * _stack.Pop());
                    break;

                case OperatorType.Divide:
                    a = _stack.Pop();
                    _stack.Push(_stack.Pop() / a);
                    break;

                case OperatorType.Modulo:
                    a = _stack.Pop();
                    _stack.Push(_stack.Pop() % a);
                    break;

                case OperatorType.Power:
                    a = _stack.Pop();
                    _stack.Push(Math.Pow(_stack.Pop(), a));
                    break;

                case OperatorType.ConditionalOr:
                    b = _stack.Pop();
                    a = _stack.Pop();
                    _stack.Push(a.Equals(0.0) && b.Equals(0.0) ? 0.0 : 1.0);
                    break;

                case OperatorType.ConditionalAnd:
                    b = _stack.Pop();
                    a = _stack.Pop();
                    _stack.Push(a.Equals(0.0) || b.Equals(0.0) ? 0.0 : 1.0);
                    break;

                case OperatorType.GreaterThan:
                    b = _stack.Pop();
                    a = _stack.Pop();
                    _stack.Push(a > b ? 1.0 : 0.0);
                    break;

                case OperatorType.LessThan:
                    b = _stack.Pop();
                    a = _stack.Pop();
                    _stack.Push(a < b ? 1.0 : 0.0);
                    break;

                case OperatorType.GreaterThanOrEqual:
                    b = _stack.Pop();
                    a = _stack.Pop();
                    _stack.Push(a >= b ? 1.0 : 0.0);
                    break;

                case OperatorType.LessThanOrEqual:
                    b = _stack.Pop();
                    a = _stack.Pop();
                    _stack.Push(a <= b ? 1.0 : 0.0);
                    break;

                case OperatorType.IsEqual:
                    b = _stack.Pop();
                    a = _stack.Pop();
                    _stack.Push(Math.Abs(a - b) <= EqualityTolerance ? 1.0 : 0.0);
                    break;

                case OperatorType.IsNotEqual:
                    b = _stack.Pop();
                    a = _stack.Pop();
                    _stack.Push(Math.Abs(a - b) > EqualityTolerance ? 1.0 : 0.0);
                    break;

                default:
                    throw new ParserException("Unimplemented arithmetic operator", Input, Index);
                }
                break;

            default:
                throw new ParserException("Unimplemented operator", Input, Index);
            }
        }