public void DocTest3()
        {
            // Parse ...
            ExpressionParser parser = new ExpressionParser();
            var compiledExpression  = parser.Parse("(cabbages+onions)*bananas");

            Debug.WriteLine(compiledExpression.ToString());

            // Variables ...
            VariableSet vSet = new VariableSet();

            vSet.RegisterVariable(OperandType.Double, "cabbages", 6);
            vSet.RegisterVariable(OperandType.Long, "onions", 2);
            vSet.RegisterVariable(OperandType.Long, "bananas", 5);

            // Evaluate ...
            var resultStack = compiledExpression.Evaluate(vSet);

            Debug.WriteLine(TokenService.TokensAsString(resultStack));

            // Result ...
            IOperand result = resultStack.Pop();

            Debug.WriteLine($"{result.Type}, {result.GetValue()}");
            double answer = (double)result.GetValue();

            Debug.WriteLine(answer);
        }
        private static void DoPow(Stack <IOperand> stack, IBackingStore store, long paramCount)
        {
            IOperand second = OperatorActions.PopAndResolve(stack, store);
            IOperand first  = OperatorActions.PopAndResolve(stack, store);
            double   val    = (double)first.GetValue();
            var      result = Math.Pow(Convert.ToDouble(first.GetValue()), Convert.ToDouble(second.GetValue()));

            stack.Push(new Operand(-1, OperandType.Double, result));
        }
        private void DoStringContains(Stack <IOperand> operands, IBackingStore variables, long parserPosition)
        {
            IOperand second = OperatorActions.PopAndResolve(operands, variables);
            IOperand first  = OperatorActions.PopAndResolve(operands, variables);

            operands.Push(new Operand(-1, OperandType.Bool, ((string)first.GetValue()).Contains((string)second.GetValue())));
        }
        public void DocTest2()
        {
            ExpressionParser parser = new ExpressionParser();

            // Parse ...
            var compiledExpression = parser.Parse("(6+2)*5");

            Debug.WriteLine(compiledExpression.ToString());

            // Evaluate ...
            var resultStack = compiledExpression.Evaluate(null);

            Debug.WriteLine(resultStack.ToString());

            // Pop the result from the stack...
            IOperand result = resultStack.Pop();

            Debug.WriteLine($"{result.Type}, {result.GetValue()}");
            int answer = (int)result.GetValue();

            Debug.WriteLine(answer);
        }
示例#5
0
        /// <summary>
        /// Called by the Evaluator when it encounters 'StringContains'
        /// long StringContains(string source, string subString, bool isCaseSensitive)
        /// Returns index of subString, or -1
        /// </summary>
        private void DoStringContains(Stack <IOperand> operands, IBackingStore backingStore, long parserPosition)
        {
            // Pop the correct number of parameters from the operands stack, ** in reverse order **
            // If an operand is a variable, it is resolved from the variables provided
            IOperand third  = OperatorActions.PopAndResolve(operands, backingStore);
            IOperand second = OperatorActions.PopAndResolve(operands, backingStore);
            IOperand first  = OperatorActions.PopAndResolve(operands, backingStore);

            string           strSource    = (string)first.GetValue();
            string           strSubstring = (string)second.GetValue();
            StringComparison comparison   = (bool)third.GetValue() == true ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase;

            long result = strSource.IndexOf(strSubstring, comparison);

            operands.Push(new Operand(-1, OperandType.Long, result));
        }
示例#6
0
        /// <summary>
        /// Execute the operator with the specified state.
        /// </summary>
        /// <param name="state">State.</param>
        public bool Execute(object state)
        {
            var sourceValue   = m_source.GetValue(state);
            var containsValue = m_contains.GetValue(state);

            if (sourceValue == null && containsValue == null)
            {
                return(true);
            }

            if (sourceValue == null || containsValue == null)
            {
                return(false);
            }

            return(sourceValue.ToString().Contains(containsValue.ToString()));
        }
        private static void DoLerp(Stack <IOperand> operandStack, IBackingStore backingStore, long paramCount)
        {
            // Pop the correct number of parameters from the operands stack, ** in reverse order **
            // If an operand is a variable, it is resolved from the backing store provided
            IOperand third  = OperatorActions.PopAndResolve(operandStack, backingStore);
            IOperand second = OperatorActions.PopAndResolve(operandStack, backingStore);
            IOperand first  = OperatorActions.PopAndResolve(operandStack, backingStore);

            double a = Convert.ToDouble(first.GetValue());
            double b = Convert.ToDouble(second.GetValue());
            double t = Convert.ToDouble(third.GetValue());

            // The result is of type double
            double result = a + t * (b - a);

            // Push the result back onto the operand stack
            operandStack.Push(new Operand(-1, OperandType.Double, result));
        }
        /// <summary>
        /// This ought to be implemented with a FunctionMartix but it would be huge.
        /// This way is easier!
        /// </summary>
        internal static Tuple <OperandType, OperandType> DoSetEquals(DoubleOperandFunctionMatrix matrix, Stack <IOperand> stack, IBackingStore backingStore, long parserPosition)
        {
            IOperand second = PopAndResolve(stack, backingStore);
            IOperand first  = stack.Pop();      // Not PopAndResolve. LHS must be a variable.

            if (first.Type != OperandType.Variable)
            {
                throw new ExpressionEvaluatorException(parserPosition, ExpressionEvaluatorException.ExceptionCause.BadOperand, "LHS of '=' is a '" + first.Type + "' when it must be a variable");
            }
            else
            {
                string varName = (string)first.GetValue();

                (OperandType type, object value)valueAndType;
                try
                {
                    // We need the type, don't need the value because it's going to be overwritten.
                    valueAndType = backingStore.GetValue(varName);
                }
                catch (Exception ex)
                {
                    throw new ExpressionEvaluatorException(-1, ExpressionEvaluatorException.ExceptionCause.UndefinedVariable, $"'{varName}'");
                }

                // type is needed so we can pick out the correct martrix operation. Value is irrelevant as it is overwritten.
                var firstOperand = new Operand(first.ParserPosition, valueAndType.type, valueAndType.value);

                IOperand result = matrix.PerformDelegate(firstOperand, second);

                if (result != null)
                {
                    backingStore.SetValue(varName, result.GetValue());
                    stack.Push(result);
                    return(null);
                }
                else
                {
                    // Signal an error ...
                    return(new Tuple <OperandType, OperandType>(first.Type, second.Type));
                }
            }
        }
        /// <summary>
        /// Peeks an operand from the stack. If it's a variable it returns an operand holding the variable value, otherwise it returns the operand.
        /// </summary>
        /// <param name="stack"></param>
        /// <param name="variables"></param>
        /// <returns></returns>
        public static IOperand PeekAndResolve(Stack <IOperand> stack, IBackingStore backingStore)
        {
            IOperand operand = stack.Peek();

            if (operand.Type == OperandType.Variable)
            {
                //var variable = ResolveVariable(variables, retVal);

                try
                {
                    var valueAndType = backingStore.GetValue((string)operand.GetValue());
                    operand = new Operand(operand.ParserPosition, valueAndType.type, valueAndType.value);
                }
                catch// (KeyNotFoundException)
                {
                    throw new ExpressionEvaluatorException(operand.ParserPosition, ExpressionEvaluatorException.ExceptionCause.UndefinedVariable, $"'{operand.GetValue().ToString()}'");
                }
            }
            return(operand);
        }
        public decimal GetValue()
        {
            var left  = _left.GetValue();
            var right = _right.GetValue();

            switch (_operator)
            {
            case Operator.Add:
                return(left + right);

            case Operator.Minus:
                return(left - right);

            case Operator.Divide:
                return(left / right);

            case Operator.Multiply:
                return(left * right);

            default:
                throw new InvalidOperationException($"Operator {_operator} is not supported");
            }
        }