private Expression AndExpression() { Expression ret = EqualityExpression(); while (Current.Kind == TokenKind.OpAnd) { Consume(); // Or Expression rhs = EqualityExpression(); ret = new BinaryExpression(ret.Line, ret.Column, ret, TokenKind.OpAnd, rhs); } return ret; }
private Expression EqualityExpression() { Expression ret = RelationalExpression(); while (Current.Kind == TokenKind.OpIs || Current.Kind == TokenKind.OpIsNot) { Token tok = Consume(); // consume operator Expression rhs = RelationalExpression(); ret = new BinaryExpression(ret.Line, ret.Column, ret, tok.Kind, rhs); } return ret; }
private Expression RelationalExpression() { Expression ret = PrimaryExpression(); while (Current.Kind == TokenKind.OpLt || Current.Kind == TokenKind.OpLte || Current.Kind == TokenKind.OpGt || Current.Kind == TokenKind.OpGte) { Token tok = Consume(); // consume operator Expression rhs = PrimaryExpression(); ret = new BinaryExpression(ret.Line, ret.Column, ret, tok.Kind, rhs); } return ret; }
private object EvaluateBinaryExpression(BinaryExpression expression) { switch (expression.Operator) { case TokenKind.OpOr: { object lhsValue = EvaluateExpression(expression.Left); if (Util.ToBoolean(lhsValue)) return true; object rhsValue = EvaluateExpression(expression.Right); return Util.ToBoolean(rhsValue); } case TokenKind.OpAnd: { object lhsValue = EvaluateExpression(expression.Left); if (!Util.ToBoolean(lhsValue)) return false; object rhsValue = EvaluateExpression(expression.Right); return Util.ToBoolean(rhsValue); } case TokenKind.OpIs: { object lhsValue = EvaluateExpression(expression.Left); object rhsValue = EvaluateExpression(expression.Right); return lhsValue.Equals(rhsValue); } case TokenKind.OpIsNot: { object lhsValue = EvaluateExpression(expression.Left); object rhsValue = EvaluateExpression(expression.Right); return !lhsValue.Equals(rhsValue); } case TokenKind.OpGt: { object lhsValue = EvaluateExpression(expression.Left); object rhsValue = EvaluateExpression(expression.Right); IComparable c1 = lhsValue as IComparable; IComparable c2 = rhsValue as IComparable; if (c1 == null || c2 == null) return false; return c1.CompareTo(c2) == 1; } case TokenKind.OpLt: { object lhsValue = EvaluateExpression(expression.Left); object rhsValue = EvaluateExpression(expression.Right); IComparable c1 = lhsValue as IComparable; IComparable c2 = rhsValue as IComparable; if (c1 == null || c2 == null) return false; return c1.CompareTo(c2) == -1; } case TokenKind.OpGte: { object lhsValue = EvaluateExpression(expression.Left); object rhsValue = EvaluateExpression(expression.Right); IComparable c1 = lhsValue as IComparable; IComparable c2 = rhsValue as IComparable; if (c1 == null || c2 == null) return false; return c1.CompareTo(c2) >= 0; } case TokenKind.OpLte: { object lhsValue = EvaluateExpression(expression.Left); object rhsValue = EvaluateExpression(expression.Right); IComparable c1 = lhsValue as IComparable; IComparable c2 = rhsValue as IComparable; if (c1 == null || c2 == null) return false; return c1.CompareTo(c2) <= 0; } default: throw new TemplateException("Operator " + expression.Operator.ToString() + " is not supported.", expression.Line, expression.Column); } }