/// <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); } }
/// <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); } }
/// <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); } }