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