internal object Evaluate(object[] variables, out bool evaluated) { evaluated = true; ListStack evaluationstack = new ListStack(); for (int j = 0; j < ExpressionStack.Count; j++) { Expression e = ExpressionStack[j]; if (e.Valuable) { VariableExpression v = e as VariableExpression; if (v != null) { e = new ConstExpression(variables[v.Ordinal]); } evaluationstack.Push(e); } else { Expression[] values = new Expression[e.ArgumentsCount]; if (ExpressionStack.Count < e.ArgumentsCount) { throw new EvaluateException("Syntax Error"); } for (int i = e.ArgumentsCount - 1; i >= 0; i--) { values[i] = evaluationstack.Pop(); } evaluated = true; Expression[] ret = e.Evaluate(values, out evaluated); if (evaluated && ret != null) { for (int i = 0; i < ret.Length; i++) { evaluationstack.Push(ret[i]); } } else { break; } } } if (evaluated) { if (evaluationstack.Count == 1) { if (evaluationstack[0].NumericValue.HasValue) { return(evaluationstack[0].NumericValue.Value); } else if (evaluationstack[0].BoolValue.HasValue) { return(evaluationstack[0].BoolValue.Value); } else if (evaluationstack[0].ArrayValue != null) { return(evaluationstack[0].ArrayValue); } else if (evaluationstack[0].DataTimeValue != null) { return(evaluationstack[0].DataTimeValue); } else if (evaluationstack[0].StringValue != null) { return(evaluationstack[0].StringValue); } else { return(null); } } else { throw new EvaluateException("Syntax Error"); } } else { return(null); } }
private void DoParse(IEnumerator <Token> input) { InitializeTab(); Stack <Token> ts = new Stack <Token>(); List <Token> tokens = new List <Token>(); ts.Push(new BareToken(TokenKind.End)); ts.Push(new NonterminalSymbol(NonterminalSymbolKind.C)); input.MoveNext(); Token c = input.Current; tokens.Add(c); Token X; while (true) { X = ts.Pop(); if (X.Kind == TokenKind.End) { break; } else if (X.Kind == TokenKind.Translation) { TranslationSymbol ns = (TranslationSymbol)X; Expression e3 = null; Expression e2 = null; Expression e1 = null; switch (ns.KindTR) { case TranslationSymbolKind.PlusOperator: case TranslationSymbolKind.MinusOperator: case TranslationSymbolKind.MultiplyOperator: case TranslationSymbolKind.DivideOpearator: case TranslationSymbolKind.PowerOperator: case TranslationSymbolKind.GreaterOperator: case TranslationSymbolKind.GreaterOrEqualOperator: case TranslationSymbolKind.LessOperator: case TranslationSymbolKind.LessOrEqualOperator: case TranslationSymbolKind.EqualOperator: case TranslationSymbolKind.NotEqualOperator: case TranslationSymbolKind.AndOperator: case TranslationSymbolKind.OrOperator: case TranslationSymbolKind.MaxOperator: case TranslationSymbolKind.MinOperator: case TranslationSymbolKind.LogOperator: case TranslationSymbolKind.RoundOperator: case TranslationSymbolKind.BusulfanCalculationOperator: e2 = es.Pop(); break; case TranslationSymbolKind.AvgOperator: case TranslationSymbolKind.StdOperator: case TranslationSymbolKind.CVOperator: case TranslationSymbolKind.AgeOfThePatientOperator: e3 = e2; e2 = es.Pop(); e1 = es.Pop(); break; } e1 = es.Pop(); Expression ex = null; switch (ns.KindTR) { case TranslationSymbolKind.PlusOperator: ex = BinaryExpression.trySimplify( new PlusExpression(e1, e2), es); break; case TranslationSymbolKind.MinusOperator: ex = BinaryExpression.trySimplify( new MinusExpression(e1, e2), es); break; case TranslationSymbolKind.MultiplyOperator: ex = BinaryExpression.trySimplify( new MultiplyExpression(e1, e2), es); break; case TranslationSymbolKind.DivideOpearator: ex = BinaryExpression.trySimplify( new DivideExpression(e1, e2), es); break; case TranslationSymbolKind.PowerOperator: ex = BinaryExpression.trySimplify( new PowerExpression(e1, e2), es); break; case TranslationSymbolKind.SqrtOperator: ex = UnaryExpression.trySimplify( new SqrtExpression(e1), es); break; case TranslationSymbolKind.Log10Operator: ex = UnaryExpression.trySimplify( new Log10Expression(e1), es); break; case TranslationSymbolKind.SinOperator: ex = UnaryExpression.trySimplify( new SinExpression(e1), es); break; case TranslationSymbolKind.CosOperator: ex = UnaryExpression.trySimplify( new CosExpression(e1), es); break; case TranslationSymbolKind.TanOperator: ex = UnaryExpression.trySimplify( new TanExpression(e1), es); break; case TranslationSymbolKind.AbsOperator: ex = UnaryExpression.trySimplify( new AbsExpression(e1), es); break; case TranslationSymbolKind.AcosOperator: ex = UnaryExpression.trySimplify( new AcosExpression(e1), es); break; case TranslationSymbolKind.AsinOperator: ex = UnaryExpression.trySimplify( new AsinExpression(e1), es); break; case TranslationSymbolKind.AtanOperator: ex = UnaryExpression.trySimplify( new AtanExpression(e1), es); break; case TranslationSymbolKind.CeilingOperator: ex = UnaryExpression.trySimplify( new CeilingExpression(e1), es); break; case TranslationSymbolKind.CoshOperator: ex = UnaryExpression.trySimplify( new CoshExpression(e1), es); break; case TranslationSymbolKind.ExpOperator: ex = UnaryExpression.trySimplify( new ExpExpression(e1), es); break; case TranslationSymbolKind.FloorOperator: ex = UnaryExpression.trySimplify( new FloorExpression(e1), es); break; case TranslationSymbolKind.MaxOperator: ex = BinaryExpression.trySimplify( new MaxExpression(e1, e2), es); break; case TranslationSymbolKind.MinOperator: ex = BinaryExpression.trySimplify( new MinExpression(e1, e2), es); break; case TranslationSymbolKind.RoundOperator: ex = BinaryExpression.trySimplify( new RoundExpression(e1, e2), es); break; case TranslationSymbolKind.LogOperator: ex = BinaryExpression.trySimplify( new LogExpression(e1, e2), es); break; case TranslationSymbolKind.SinhOperator: ex = UnaryExpression.trySimplify( new SinhExpression(e1), es); break; case TranslationSymbolKind.TanhOperator: ex = UnaryExpression.trySimplify( new TanhExpression(e1), es); break; case TranslationSymbolKind.TruncateOperator: ex = UnaryExpression.trySimplify( new TruncateExpression(e1), es); break; case TranslationSymbolKind.UnaryMinusOperator: ex = UnaryExpression.trySimplify( new UnaryMinusExpression(e1), es); break; case TranslationSymbolKind.GreaterOperator: ex = BinaryExpression.trySimplify( new GreterExpression(e1, e2), es); break; case TranslationSymbolKind.LessOperator: ex = BinaryExpression.trySimplify( new LessExpression(e1, e2), es); break; case TranslationSymbolKind.LessOrEqualOperator: ex = BinaryExpression.trySimplify( new LessOrEqualExpression(e1, e2), es); break; case TranslationSymbolKind.EqualOperator: ex = BinaryExpression.trySimplify( new EqualExpression(e1, e2), es); break; case TranslationSymbolKind.NotEqualOperator: ex = BinaryExpression.trySimplify( new NotEqualExpression(e1, e2), es); break; case TranslationSymbolKind.GreaterOrEqualOperator: ex = BinaryExpression.trySimplify( new GreaterOrEqualExpression(e1, e2), es); break; case TranslationSymbolKind.NegativeOperator: ex = UnaryExpression.trySimplify( new NegativExpression(e1), es); break; case TranslationSymbolKind.AndOperator: ex = BinaryExpression.trySimplify( new AndExpression(e1, e2), es); break; case TranslationSymbolKind.OrOperator: ex = BinaryExpression.trySimplify( new OrExpression(e1, e2), es); break; case TranslationSymbolKind.IfOperator: ex = UnaryExpression.trySimplify( new IfElseExpression(e1, true), es); break; case TranslationSymbolKind.ElseOperator: ex = UnaryExpression.trySimplify( new IfElseExpression(e1, false), es); break; case TranslationSymbolKind.ForEachOperator: ex = UnaryExpression.trySimplify( new ForEachExpression(e1), es); break; case TranslationSymbolKind.CountItemsOperator: ex = UnaryExpression.trySimplify( new CountItemsExpression(e1), es); break; case TranslationSymbolKind.CheckOperator: ex = UnaryExpression.trySimplify( new CheckExpression(e1), es); break; /*case TranslationSymbolKind.AvgOperator: * ex = ThreeArgumentsExpression.trySimplify( * new AvgExpression(e1, e2, e3), es.Stack)); * break; * case TranslationSymbolKind.StdOperator: * ex = ThreeArgumentsExpression.trySimplify( * new StdExpression(e1, e2, e3), es.Stack)); * break; * case TranslationSymbolKind.CVOperator: * ex = ThreeArgumentsExpression.trySimplify( * new CVExpression(e1, e2, e3), es.Stack)); * break; * case TranslationSymbolKind.AgeOfThePatientOperator: * ex = ThreeArgumentsExpression.trySimplify( * new AgeOfThePatientExpression(e1, e2, e3), es.Stack)); * break; * case TranslationSymbolKind.IsNotNullOperator: * ex = UnaryExpression.trySimplify( * new IsNotNullExpression(e2, (ILogic)operators[OperatorKind.Logic]), es.Stack)); * break; * case TranslationSymbolKind.IsNullOperator: * ex = UnaryExpression.trySimplify( * new IsNullExpression(e1), es)); * break; * case TranslationSymbolKind.BusulfanCalculationOperator: * ex = BinaryExpression.trySimplify( * new BusulfanCalculationExpression(e1, e2, (IFunction)operators[OperatorKind.Function]), es.Stack)); * break; * case TranslationSymbolKind.ConvertToDaysOperator: * ex = UnaryExpression.trySimplify( * new ConvertToDaysExpression(e2), es.Stack)); * break; * case TranslationSymbolKind.SumColOperator: * ex = UnaryExpression.trySimplify( * new SumColExpression(e2), es.Stack)); * break; * case TranslationSymbolKind.SumRowOperator: * ex = UnaryExpression.trySimplify( * new SumRowExpression(e2), es.Stack)); * break; * case TranslationSymbolKind.AvgWksOperator: * ex = UnaryExpression.trySimplify( * new AvgWksExpression(e2), es.Stack)); * break; * case TranslationSymbolKind.SumWksOperator: * ex = UnaryExpression.trySimplify( * new SumWksExpression(e2), es.Stack)); * break; * case TranslationSymbolKind.CountSigOperator: * ex = UnaryExpression.trySimplify( * new CountSigExpression(e2), es.Stack)); * break; * case TranslationSymbolKind.SumOperator: * ex = UnaryExpression.trySimplify( * new SumExpression(e2), es.Stack)); * break; */ } if (ex != null) { es.Push(ex); } } else if (X.Kind == TokenKind.Nonterminal) { LinkedList <Token> lst; if ((lst = M[(int)c.Kind, (int)((NonterminalSymbol)X).KindNT]) != null) { LinkedListNode <Token> nd = lst.Last; while (nd != null) { ts.Push(nd.Value); nd = nd.Previous; } } else { throw new ParseErrorException ("Unexpected token: " + c.Kind + "."); } } else { if (X.Kind == c.Kind) { Expression ex = null; switch (c.Kind) { case TokenKind.Double: ex = new ConstExpression(((DoubleToken)c).Value); break; case TokenKind.String: ex = new ConstExpression(((StringToken)c).Value); break; case TokenKind.DateTime: ex = new ConstExpression(((DateTimeToken)c).Value); break; case TokenKind.Variable: ex = new VariableExpression(((VariableToken)c).Name); break; case TokenKind.E: ex = new ConstExpression(Math.E); break; case TokenKind.PI: ex = new ConstExpression(Math.PI); break; case TokenKind.RightBrace: ex = new RightBraceExpression(); break; } if (ex != null) { es.Push(ex); } input.MoveNext(); Token prev = c; c = input.Current; tokens.Add(c); if (previoustoken.ContainsKey(c.Group)) { bool find = false; foreach (TokenGroup group in previoustoken[c.Group]) { if (prev.Group == group) { find = true; break; } } if (!find) { throw new ParseErrorException ("UnExpected " + prev.Group + " - " + c.Group + "."); } } } else { throw new ParseErrorException ("Expected " + X.Kind + ", got " + c.Kind + "."); } } } es.SetVariablesOrdinal(); }