|
//
// MarkupScript
// Author: Tom Englert
// Contact: mail@tom-englert.de
// Copyright (C) 2010 tom-englert.de
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
namespace MarkupScript
{
/// <summary>
/// Base class for all binary expressions like comparison, arithmetic and logical operations.
/// Binary expressions evaluate the left and right properties.
/// </summary>
public abstract class BinaryExpression : Statement, IExpression
{
/// <summary>
/// The left expression of the operation.
/// </summary>
public IExpression Left { get; set; }
/// <summary>
/// The right expression of the operation
/// </summary>
public IExpression Right { get; set; }
/// <summary>
/// The evaluator for the specific expression.
/// </summary>
private Func<object, object, object> evaluator;
protected BinaryExpression(Func<object, object, object> evaluator)
{
this.evaluator = evaluator;
}
#region Expression Members
public override object OnEvaluate()
{
if ((Left == null) || (Right == null))
{
throw new InvalidOperationException("Binary expressions require both Left and Right to be set!");
}
return evaluator(Left.Evaluate(), Right.Evaluate());
}
#endregion
}
#region Comparison
/// <summary>
/// Base class for comparisons.
/// </summary>
public abstract class ComparisonExpression : BinaryExpression
{
protected ComparisonExpression(Func<object, object, object> evaluator)
: base(evaluator)
{
}
/// <summary>
/// Compare left and right.
/// Try to cast the arguments first to boolean, to double, to IComparable and finaly to string.
/// </summary>
/// <param name="left">The left value.</param>
/// <param name="right">The right value</param>
/// <returns>The result as returned by IComparable.Compare</returns>
protected static int Compare(object left, object right)
{
try
{
return InternalCompare(ToBoolean(left), ToBoolean(right));
}
catch (InvalidCastException) { }
catch (FormatException) { }
try
{
return InternalCompare(ToDouble(left), ToDouble(right));
}
catch (InvalidCastException) { }
catch (FormatException) { }
try
{
return InternalCompare(left, right);
}
catch (InvalidCastException) { }
catch (FormatException) { }
catch (ArgumentException) { }
return InternalCompare(left.ToString(), right.ToString());
}
private static int InternalCompare(object left, object right)
{
return InternalCompare((IComparable)left, (IComparable)right);
}
private static int InternalCompare(IComparable left, IComparable right)
{
return left.CompareTo(right);
}
}
public class Equal : ComparisonExpression
{
public Equal() : base((a, b) => Compare(a, b) == 0) { }
}
public class NotEqual : ComparisonExpression
{
public NotEqual() : base((a, b) => Compare(a, b) != 0) { }
}
public class GreaterThanOrEqual : ComparisonExpression
{
public GreaterThanOrEqual() : base((a, b) => Compare(a, b) >= 0) { }
}
public class GreaterThan : ComparisonExpression
{
public GreaterThan() : base((a, b) => Compare(a, b) > 0) { }
}
public class LessThan : ComparisonExpression
{
public LessThan() : base((a, b) => Compare(a, b) < 0) { }
}
public class LessThanOrEqual : ComparisonExpression
{
public LessThanOrEqual() : base((a, b) => Compare(a, b) <= 0) { }
}
#endregion
#region Arithmetic
public class Add : BinaryExpression
{
public Add() : base((a, b) => ToDouble(a) + ToDouble(b)) { }
}
public class Divide : BinaryExpression
{
public Divide() : base((a, b) => ToDouble(a) / ToDouble(b)) { }
}
public class Modulo : BinaryExpression
{
public Modulo() : base((a, b) => ToDouble(a) % ToDouble(b)) { }
}
public class Multiply : BinaryExpression
{
public Multiply() : base((a, b) => ToDouble(a) * ToDouble(b)) { }
}
public class Power : BinaryExpression
{
public Power() : base((a, b) => Math.Pow(ToDouble(a), ToDouble(b))) { }
}
public class Subtract : BinaryExpression
{
public Subtract() : base((a, b) => ToDouble(a) - ToDouble(b)) { }
}
#endregion
#region Logical
public class And : BinaryExpression
{
public And() : base((a, b) => ToBoolean(a) && ToBoolean(b)) { }
}
public class Or : BinaryExpression
{
public Or() : base((a, b) => ToBoolean(a) || ToBoolean(b)) { }
}
public class ExclusiveOr : BinaryExpression
{
public ExclusiveOr() : base((a, b) => ToBoolean(a) != ToBoolean(b)) { }
}
#endregion
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.