public static double Eval(string expression) { expression = Normalize(expression); string rpn = GetRPN(expression); Stack stVals = new Stack(); RPNEnumerator rpnEnum = new RPNEnumerator(rpn); while (rpnEnum.MoveNext()) { RPNValue rpnVal = (RPNValue)rpnEnum.Current; if (rpnVal.type == RPNValueType.OPERAND) { stVals.Push(Double.Parse(rpnVal.val, new CultureInfo("en-US"))); } else { double v2 = (double)stVals.Pop(); double v1 = (double)stVals.Pop(); if (rpnVal.val == "+") { stVals.Push(v1 + v2); } else if (rpnVal.val == "-") { stVals.Push(v1 - v2); } else if (rpnVal.val == "*") { stVals.Push(v1 * v2); } else if (rpnVal.val == "/") { stVals.Push(v1 / v2); } } } return (double)stVals.Pop(); }
public static IExpression GenerateExpressionFromString(string strExpr, IMetadataHost host, IMethodDefinition method) { strExpr = Normalize(strExpr); string rpn = GetRPN(strExpr); Stack<IExpression> stVals = new Stack<IExpression>(); RPNEnumerator rpnEnum = new RPNEnumerator(rpn); var int32Type = host.PlatformType.SystemInt32; var boolType = host.PlatformType.SystemBoolean; while (rpnEnum.MoveNext()) { RPNValue rpnVal = (RPNValue)rpnEnum.Current; if (rpnVal.type == RPNValueType.OPERAND) { if (reNum.IsMatch(rpnVal.val)) { stVals.Push(new CompileTimeConstant() { Type = int32Type, Value = int.Parse(rpnVal.val.Replace(':', '-')) }); } else { IExpression expr = null; var exprParts = rpnVal.val.Split('.'); if (exprParts[0] == "this") { expr = new ThisReference() { Type = method.ContainingType.ResolvedType }; } else { foreach (var arg in method.Parameters) { if (arg.Name.Value == exprParts[0]) { expr = new BoundExpression() { Type = arg.Type.ResolvedType, Definition = arg }; break; } } } if (expr != null && exprParts.Length > 1) { for (int i = 1; i < exprParts.Length; i++) { expr = GetExprWithAccesor(expr, exprParts[i], host); } } if (expr == null || expr.Type.ResolvedType != int32Type.ResolvedType) { return null; } stVals.Push(expr); } } else { var v1 = stVals.Pop(); var v2 = stVals.Pop(); if (rpnVal.val == "+") stVals.Push(new Addition() { Type = int32Type, LeftOperand = v2, RightOperand = v1 }); else if (rpnVal.val == "-") stVals.Push(new Subtraction() { Type = int32Type, LeftOperand = v2, RightOperand = v1 }); else if (rpnVal.val == "*") stVals.Push(new Multiplication() { Type = int32Type, LeftOperand = v2, RightOperand = v1 }); else if (rpnVal.val == "/") stVals.Push(new Division() { Type = int32Type, LeftOperand = v2, RightOperand = v1 }); else if (rpnVal.val == "=") stVals.Push(new Equality() { Type = int32Type, LeftOperand = v2, RightOperand = v1 }); else if (rpnVal.val == "&") stVals.Push(new Conditional() { Type = boolType, Condition = v2, ResultIfTrue = v1, ResultIfFalse = new CompileTimeConstant() { Type = int32Type, Value = 0 } }); else if (rpnVal.val == "|") stVals.Push(new Conditional() { Type = boolType, Condition = v2, ResultIfTrue = new CompileTimeConstant() { Type = int32Type, Value = 1 }, ResultIfFalse = v1 }); else if (rpnVal.val == ">") stVals.Push(new GreaterThan() { Type = boolType, LeftOperand = v2, RightOperand = v1 }); else if (rpnVal.val == "<") stVals.Push(new LessThan() { Type = boolType, LeftOperand = v2, RightOperand = v1 }); else if (rpnVal.val == "%") stVals.Push(new GreaterThanOrEqual() { Type = boolType, LeftOperand = v2, RightOperand = v1 }); else if (rpnVal.val == "#") stVals.Push(new LessThanOrEqual() { Type = boolType, LeftOperand = v2, RightOperand = v1 }); else return null; } } if (stVals.Count > 0) { return stVals.Pop(); } return null; }