public double Eval(Expression es) { switch (Kind) { case TokenKind.Number: return Num; case TokenKind.Identifier: return es.GetVar(Ident); case TokenKind.Add: return Tok1.Eval(es) + Tok2.Eval(es); case TokenKind.Mul: return Tok1.Eval(es) * Tok2.Eval(es); case TokenKind.Sub: return (Tok2==null) ? -Tok1.Eval(es) : (Tok1.Eval(es) - Tok2.Eval(es)); case TokenKind.Div: return Tok1.Eval(es) / Tok2.Eval(es); case TokenKind.Eq: return (Math.Abs(Tok1.Eval(es)-Tok2.Eval(es)) < 1e-6) ? 1:0; case TokenKind.Neq: return (Math.Abs(Tok1.Eval(es)-Tok2.Eval(es)) < 1e-6) ? 0:1; case TokenKind.Leq: return (Tok1.Eval(es) <= Tok2.Eval(es)) ? 1:0; case TokenKind.Geq: return(Tok1.Eval(es) >= Tok2.Eval(es)) ? 1:0; case TokenKind.Le: return (Tok1.Eval(es) < Tok2.Eval(es)) ? 1:0; case TokenKind.Ge: return(Tok1.Eval(es) > Tok2.Eval(es)) ? 1:0; case TokenKind.Mod: return(Tok1.Eval(es) % Tok2.Eval(es)); case TokenKind.If: return (Math.Abs(Tok1.Eval(es))>1e-6) ? Tok2.Eval(es):Tok3.Eval(es); case TokenKind.Shl: return (int)Tok1.Eval(es)<<(int)Tok2.Eval(es); case TokenKind.Shr: return (int)Tok1.Eval(es)>>(int)Tok2.Eval(es); case TokenKind.And: return (Math.Abs(Tok1.Eval(es))>1e-6 && Math.Abs(Tok2.Eval(es))>1e-6) ?1:0; case TokenKind.Or: return (Math.Abs(Tok1.Eval(es))>1e-6 || Math.Abs(Tok2.Eval(es))>1e-6) ?1:0; case TokenKind.BitAnd: return (int)Tok1.Eval(es)&(int)Tok2.Eval(es); case TokenKind.BitOr: return (int)Tok1.Eval(es)|(int)Tok2.Eval(es); case TokenKind.BitXor: return (int)Tok1.Eval(es)^(int)Tok2.Eval(es); default: throw new ExpressionException("Unknown operator: " + Kind.ToString()); } }