private object ProcessBinaryExpression(BinaryExpression exp) { object lhsValue; object rhsValue; IComparable c1; IComparable c2; switch (exp.Operator) { case Igs.Hcms.Tmpl.TokenKind.OpOr: lhsValue = EvalExpression(exp.Lhs); if (Util.ToBoolean(lhsValue)) { return true; } rhsValue = EvalExpression(exp.Rhs); return Util.ToBoolean(rhsValue); case Igs.Hcms.Tmpl.TokenKind.OpLet: lhsValue = exp.Lhs; if (exp.Lhs is Name) { string _Name = ((Name) exp.Lhs).Id; rhsValue = EvalExpression(exp.Rhs); this.SetValue(_Name, rhsValue); return string.Empty; } else if (exp.Lhs is FieldAccess) { FieldAccess fa = (FieldAccess)exp.Lhs; rhsValue = EvalExpression(exp.Rhs); object obj = EvalExpression(fa.Exp); string propertyName = fa.Field; setProperty(obj, propertyName, rhsValue); return string.Empty; } else { throw new TmplException("variable name." + lhsValue.ToString(), exp.Line, exp.Col); } case Igs.Hcms.Tmpl.TokenKind.OpAnd: lhsValue = EvalExpression(exp.Lhs); if (!Util.ToBoolean(lhsValue)) { return false; } rhsValue = EvalExpression(exp.Rhs); return Util.ToBoolean(rhsValue); case Igs.Hcms.Tmpl.TokenKind.OpIs: lhsValue = EvalExpression(exp.Lhs); rhsValue = EvalExpression(exp.Rhs); c1 = lhsValue as IComparable; c2 = rhsValue as IComparable; if (c1 == null && c2 == null) { return null; } else if (c1 == null || c2 == null) { return false; } else if (lhsValue is int && rhsValue is int) { return (int)lhsValue == (int)rhsValue; } else if (lhsValue is double && rhsValue is double) { return (double)lhsValue == (double)rhsValue; } else if (lhsValue is int && rhsValue is double) { return (int)lhsValue == (double)rhsValue; } else if (lhsValue is double && rhsValue is int) { return (double)lhsValue == (int)rhsValue; } else if (lhsValue is string && rhsValue is string) { return lhsValue.ToString() == rhsValue.ToString(); } else { return c1.CompareTo(c2) == 0; } case Igs.Hcms.Tmpl.TokenKind.OpIsNot: lhsValue = EvalExpression(exp.Lhs); rhsValue = EvalExpression(exp.Rhs); return !lhsValue.Equals(rhsValue); case Igs.Hcms.Tmpl.TokenKind.OpGt: lhsValue = EvalExpression(exp.Lhs); rhsValue = EvalExpression(exp.Rhs); c1 = lhsValue as IComparable; c2 = rhsValue as IComparable; if (c1 == null || c2 == null) { return false; } else { return c1.CompareTo(c2) == 1; } case Igs.Hcms.Tmpl.TokenKind.OpAdd: lhsValue = EvalExpression(exp.Lhs); rhsValue = EvalExpression(exp.Rhs); if (lhsValue == null || rhsValue == null) { return null; } else if (lhsValue is int && rhsValue is int) { return (int)lhsValue + (int)rhsValue; } else if (lhsValue is double && rhsValue is double) { return (double)lhsValue + (double)rhsValue; } else if (lhsValue is int && rhsValue is double) { return (int)lhsValue + (double)rhsValue; } else if (lhsValue is double && rhsValue is int) { return (double)lhsValue + (int)rhsValue; } else if (lhsValue is string || rhsValue is string) { return lhsValue.ToString() + rhsValue.ToString(); } else { return Convert.ToDouble(lhsValue) + Convert.ToDouble(rhsValue); } case Igs.Hcms.Tmpl.TokenKind.OpConcat: lhsValue = EvalExpression(exp.Lhs); rhsValue = EvalExpression(exp.Rhs); if (lhsValue == null || rhsValue == null) { return null; } else { return lhsValue.ToString() + rhsValue.ToString(); } case Igs.Hcms.Tmpl.TokenKind.OpMul: lhsValue = EvalExpression(exp.Lhs); rhsValue = EvalExpression(exp.Rhs); if (lhsValue == null || rhsValue == null) { return null; } else if (lhsValue is int && rhsValue is int) { return (int)lhsValue * (int)rhsValue; } else if (lhsValue is double && rhsValue is double) { return (double)lhsValue * (double)rhsValue; } else if (lhsValue is int && rhsValue is double) { return (int)lhsValue * (double)rhsValue; } else if (lhsValue is double && rhsValue is int) { return (double)lhsValue * (int)rhsValue; } else { return Convert.ToDouble(lhsValue) * Convert.ToDouble(rhsValue); } case Igs.Hcms.Tmpl.TokenKind.OpDiv: lhsValue = EvalExpression(exp.Lhs); rhsValue = EvalExpression(exp.Rhs); if (lhsValue == null || rhsValue == null) { return null; } else if (lhsValue is int && rhsValue is int) { return (int)lhsValue / (int)rhsValue; } else if (lhsValue is double && rhsValue is double) { return (double)lhsValue / (double)rhsValue; } else if (lhsValue is int && rhsValue is double) { return (int)lhsValue / (double)rhsValue; } else if (lhsValue is double && rhsValue is int) { return (double)lhsValue / (int)rhsValue; } else { return Convert.ToDouble(lhsValue) / Convert.ToDouble(rhsValue); } case Igs.Hcms.Tmpl.TokenKind.OpMod: lhsValue = EvalExpression(exp.Lhs); rhsValue = EvalExpression(exp.Rhs); if (lhsValue == null || rhsValue == null) { return null; } else if (lhsValue is int && rhsValue is int) { return (int)lhsValue % (int)rhsValue; } else if (lhsValue is double && rhsValue is double) { return (double)lhsValue % (double)rhsValue; } else if (lhsValue is int && rhsValue is double) { return (int)lhsValue % (double)rhsValue; } else if (lhsValue is double && rhsValue is int) { return (double)lhsValue % (int)rhsValue; } else { return Convert.ToDouble(lhsValue) % Convert.ToDouble(rhsValue); } case Igs.Hcms.Tmpl.TokenKind.OpPow: lhsValue = EvalExpression(exp.Lhs); rhsValue = EvalExpression(exp.Rhs); if (lhsValue == null || rhsValue == null) { return null; } else if (lhsValue is int && rhsValue is int) { return Math.Pow((int)lhsValue , (int)rhsValue); } else if (lhsValue is double && rhsValue is double) { return Math.Pow((double)lhsValue , (double)rhsValue); } else if (lhsValue is int && rhsValue is double) { return Math.Pow((int)lhsValue , (double)rhsValue); } else if (lhsValue is double && rhsValue is int) { return Math.Pow((double)lhsValue , (int)rhsValue); } else { return Math.Pow(Convert.ToDouble(lhsValue) , Convert.ToDouble(rhsValue)); } case Igs.Hcms.Tmpl.TokenKind.OpLt: lhsValue = EvalExpression(exp.Lhs); rhsValue = EvalExpression(exp.Rhs); c1 = lhsValue as IComparable; c2 = rhsValue as IComparable; if (c1 == null && c2 == null) { return false; } else if (c1 == null || c2 == null) { return false; } else if (lhsValue is int && rhsValue is int) { return (int)lhsValue < (int)rhsValue; } else if (lhsValue is double && rhsValue is double) { return (double)lhsValue < (double)rhsValue; } else if (lhsValue is int && rhsValue is double) { return (int)lhsValue < (double)rhsValue; } else if (lhsValue is double && rhsValue is int) { return (double)lhsValue < (int)rhsValue; } else { return c1.CompareTo(c2) == -1; } case Igs.Hcms.Tmpl.TokenKind.OpGte: lhsValue = EvalExpression(exp.Lhs); rhsValue = EvalExpression(exp.Rhs); c1 = lhsValue as IComparable; c2 = rhsValue as IComparable; if (c1 == null && c2 == null) { return false; } else if (c1 == null || c2 == null) { return false; } else if (lhsValue is int && rhsValue is int) { return (int)lhsValue >= (int)rhsValue; } else if (lhsValue is double && rhsValue is double) { return (double)lhsValue >= (double)rhsValue; } else if (lhsValue is int && rhsValue is double) { return (int)lhsValue >= (double)rhsValue; } else if (lhsValue is double && rhsValue is int) { return (double)lhsValue >= (int)rhsValue; } else { return c1.CompareTo(c2) >= 0; } case Igs.Hcms.Tmpl.TokenKind.OpLte: lhsValue = EvalExpression(exp.Lhs); rhsValue = EvalExpression(exp.Rhs); c1 = lhsValue as IComparable; c2 = rhsValue as IComparable; if (c1 == null && c2 == null) { return false; } else if (c1 == null || c2 == null) { return false; } else if (lhsValue is int && rhsValue is int) { return (int)lhsValue <= (int)rhsValue; } else if (lhsValue is double && rhsValue is double) { return (double)lhsValue <= (double)rhsValue; } else if (lhsValue is int && rhsValue is double) { return (int)lhsValue <= (double)rhsValue; } else if (lhsValue is double && rhsValue is int) { return (double)lhsValue <= (int)rhsValue; } else { return c1.CompareTo(c2) <= 0; } default: throw new TmplException("Operator " + exp.Operator.ToString() + " is not supported.", exp.Line, exp.Col); } }
private Expression AddSubExpression() { Expression ret = MulDivExpression(); while (Current.TokenKind == TokenKind.OpAdd || Current.TokenKind == TokenKind.OpSub ) { Token tok = Consume(); Expression rhs = MulDivExpression(); ret = new BinaryExpression(ret.Line, ret.Col, ret, tok.TokenKind, rhs); } return ret; }
private Expression AndExpression() { Expression ret = EqualityExpression(); while (Current.TokenKind == TokenKind.OpAnd) { Consume(); Expression rhs = EqualityExpression(); ret = new BinaryExpression(ret.Line, ret.Col, ret, TokenKind.OpAnd, rhs); } return ret; }
private Expression RelationalExpression() { Expression ret = AddSubExpression(); while (Current.TokenKind == TokenKind.OpLt || Current.TokenKind == TokenKind.OpLte || Current.TokenKind == TokenKind.OpGt || Current.TokenKind == TokenKind.OpGte) { Token tok = Consume(); Expression rhs = AddSubExpression(); ret = new BinaryExpression(ret.Line, ret.Col, ret, tok.TokenKind, rhs); } return ret; }
private Expression PowerExpression() { Expression ret = AtomExpression(); while (Current.TokenKind == TokenKind.OpPow ) { Token tok = Consume(); Expression rhs = AtomExpression(); ret = new BinaryExpression(ret.Line, ret.Col, ret, tok.TokenKind, rhs); } return ret; }
private Expression OrExpression() { Expression ret = AndExpression(); while (Current.TokenKind == TokenKind.OpOr) { Consume(); Expression rhs = AndExpression(); ret = new BinaryExpression(ret.Line, ret.Col, ret, TokenKind.OpOr, rhs); } return ret; }
private Expression MulDivExpression() { Expression ret = PowerExpression(); while (Current.TokenKind == TokenKind.OpMul || Current.TokenKind == TokenKind.OpDiv || Current.TokenKind == TokenKind.OpMod ) { Token tok = Consume(); Expression rhs = PowerExpression(); ret = new BinaryExpression(ret.Line, ret.Col, ret, tok.TokenKind, rhs); } return ret; }
private Expression EqualityExpression() { Expression ret = RelationalExpression(); while (Current.TokenKind == TokenKind.OpIs || Current.TokenKind == TokenKind.OpIsNot) { Token tok = Consume(); Expression rhs = RelationalExpression(); ret = new BinaryExpression(ret.Line, ret.Col, ret, tok.TokenKind, rhs); } return ret; }