add logic expression classes for use with XML parsing
This commit is contained in:
parent
4272a80e4a
commit
731a050979
87
MBS.Framework/Logic/Expression.cs
Normal file
87
MBS.Framework/Logic/Expression.cs
Normal file
@ -0,0 +1,87 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MBS.Framework.Logic.Expressions;
|
||||
|
||||
namespace MBS.Framework.Logic
|
||||
{
|
||||
public abstract class Expression
|
||||
{
|
||||
public static Expression Empty { get; } = new EmptyExpression();
|
||||
|
||||
public class ExpressionCollection
|
||||
: System.Collections.ObjectModel.Collection<Expression>
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses the expression represented by <paramref name="value"/>.
|
||||
/// </summary>
|
||||
/// <returns>The parsed <see cref="Expression" />.</returns>
|
||||
/// <param name="value">The value to parse.</param>
|
||||
public static Expression Parse(string value)
|
||||
{
|
||||
Expression expr = Expression.Empty;
|
||||
if (String.IsNullOrEmpty(value))
|
||||
return expr;
|
||||
|
||||
if (value.ToLower() == "true")
|
||||
{
|
||||
return new BooleanExpression(true);
|
||||
}
|
||||
else if (value.ToLower() == "false")
|
||||
{
|
||||
return new BooleanExpression(false);
|
||||
}
|
||||
|
||||
// see if there are any variables
|
||||
if (value.Contains("$(") && value.Contains(")"))
|
||||
{
|
||||
int variableStartIndex = value.IndexOf("$(", StringComparison.Ordinal);
|
||||
int variableEndIndex = value.IndexOf(")", variableStartIndex, StringComparison.Ordinal);
|
||||
|
||||
string wleft = value.Substring(0, variableStartIndex);
|
||||
string wvar = value.Substring(variableStartIndex + 2, variableEndIndex - 2);
|
||||
string wright = value.Substring(variableEndIndex + 1);
|
||||
|
||||
Expression exprLeft = Expression.Parse(wleft);
|
||||
Expression exprRight = Expression.Parse(wright);
|
||||
|
||||
List<Expression> list = new List<Expression>();
|
||||
if (exprLeft != Expression.Empty) list.Add(exprLeft);
|
||||
list.Add(new VariableExpression(wvar));
|
||||
if (exprRight != Expression.Empty) list.Add(exprRight);
|
||||
|
||||
if (list.Count == 1)
|
||||
return list[0];
|
||||
|
||||
return new ComplexExpression(list.ToArray());
|
||||
}
|
||||
else
|
||||
{
|
||||
// first try parsing it as a double
|
||||
double doublevalue = 0.0;
|
||||
if (Double.TryParse(value, out doublevalue))
|
||||
{
|
||||
return new LiteralExpression<double>(doublevalue);
|
||||
}
|
||||
|
||||
// otherwise, idk
|
||||
return new LiteralExpression<string>(value);
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
public abstract Expression Evaluate(ExpressionContext context);
|
||||
|
||||
public T Evaluate<T>(ExpressionContext context)
|
||||
{
|
||||
Expression exprResult = Evaluate(context);
|
||||
if (exprResult is LiteralExpression<T>)
|
||||
{
|
||||
return ((LiteralExpression<T>)exprResult).Value;
|
||||
}
|
||||
throw new InvalidCastException("expression cannot be evaluated to LiteralExpression<" + typeof(T).Name + ">");
|
||||
}
|
||||
}
|
||||
}
|
||||
21
MBS.Framework/Logic/ExpressionContext.cs
Normal file
21
MBS.Framework/Logic/ExpressionContext.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MBS.Framework.Logic
|
||||
{
|
||||
public class ExpressionContext
|
||||
{
|
||||
public Variable.VariableCollection Variables { get; } = new Variable.VariableCollection();
|
||||
|
||||
public void SetVariableValue<T>(string variableName, T value)
|
||||
{
|
||||
Variables[variableName].Expression = new Expressions.LiteralExpression<T>(value);
|
||||
}
|
||||
|
||||
public event VariableRequestedEventHandler VariableRequested;
|
||||
protected virtual void OnVariableRequested(VariableRequestedEventArgs e)
|
||||
{
|
||||
VariableRequested?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
38
MBS.Framework/Logic/Expressions/ArithmeticExpression.cs
Normal file
38
MBS.Framework/Logic/Expressions/ArithmeticExpression.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using System;
|
||||
namespace MBS.Framework.Logic.Expressions
|
||||
{
|
||||
public enum ArithmeticOperation
|
||||
{
|
||||
None = 0,
|
||||
Addition,
|
||||
Subtraction,
|
||||
Multiplication,
|
||||
Division,
|
||||
And,
|
||||
Or,
|
||||
Xor,
|
||||
Modulus
|
||||
}
|
||||
public class ArithmeticExpression : Expression
|
||||
{
|
||||
public ArithmeticOperation Operation { get; set; } = ArithmeticOperation.Addition;
|
||||
public Expression PrimaryExpression { get; set; } = null;
|
||||
public Expression SecondaryExpression { get; set; } = null;
|
||||
|
||||
public ArithmeticExpression()
|
||||
{
|
||||
}
|
||||
public ArithmeticExpression(ArithmeticOperation operation, Expression primary, Expression secondary)
|
||||
{
|
||||
Operation = operation;
|
||||
PrimaryExpression = primary;
|
||||
SecondaryExpression = secondary;
|
||||
}
|
||||
|
||||
public override Expression Evaluate(ExpressionContext context)
|
||||
{
|
||||
// TODO: implement Evaluate() on ArithmeticExpression
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
25
MBS.Framework/Logic/Expressions/BooleanExpression.cs
Normal file
25
MBS.Framework/Logic/Expressions/BooleanExpression.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using System;
|
||||
namespace MBS.Framework.Logic.Expressions
|
||||
{
|
||||
public enum BooleanExpressionComparison
|
||||
{
|
||||
Equal,
|
||||
LessThan,
|
||||
GreaterThan,
|
||||
LessThanOrEqual,
|
||||
GreaterThanOrEqual
|
||||
}
|
||||
public class BooleanExpression : Expression
|
||||
{
|
||||
public BooleanExpression(bool value = false)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
public bool Value { get; set; } = false;
|
||||
|
||||
public override Expression Evaluate(ExpressionContext context)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
21
MBS.Framework/Logic/Expressions/ComplexExpression.cs
Normal file
21
MBS.Framework/Logic/Expressions/ComplexExpression.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System;
|
||||
namespace MBS.Framework.Logic.Expressions
|
||||
{
|
||||
public class ComplexExpression : Expression
|
||||
{
|
||||
public ComplexExpression(Expression[] exprs)
|
||||
{
|
||||
for (int i = 0; i < exprs.Length; i++)
|
||||
{
|
||||
Expressions.Add(exprs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public Expression.ExpressionCollection Expressions { get; } = new Expression.ExpressionCollection();
|
||||
|
||||
public override Expression Evaluate(ExpressionContext context)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
MBS.Framework/Logic/Expressions/EmptyExpression.cs
Normal file
11
MBS.Framework/Logic/Expressions/EmptyExpression.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using System;
|
||||
namespace MBS.Framework.Logic.Expressions
|
||||
{
|
||||
public class EmptyExpression : Expression
|
||||
{
|
||||
public override Expression Evaluate(ExpressionContext context)
|
||||
{
|
||||
return Expression.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
18
MBS.Framework/Logic/Expressions/LiteralExpression.cs
Normal file
18
MBS.Framework/Logic/Expressions/LiteralExpression.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System;
|
||||
namespace MBS.Framework.Logic.Expressions
|
||||
{
|
||||
public class LiteralExpression<T> : Expression
|
||||
{
|
||||
public T Value { get; set; } = default(T);
|
||||
|
||||
public LiteralExpression(T value = default(T))
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public override Expression Evaluate(ExpressionContext context)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
23
MBS.Framework/Logic/Expressions/VariableExpression.cs
Normal file
23
MBS.Framework/Logic/Expressions/VariableExpression.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using System;
|
||||
namespace MBS.Framework.Logic.Expressions
|
||||
{
|
||||
public class VariableExpression : Expression
|
||||
{
|
||||
public VariableExpression(string variableName)
|
||||
{
|
||||
VariableName = variableName;
|
||||
}
|
||||
|
||||
public string VariableName { get; set; } = null;
|
||||
|
||||
public override Expression Evaluate(ExpressionContext context)
|
||||
{
|
||||
Variable varr = context.Variables[VariableName];
|
||||
if (varr != null)
|
||||
{
|
||||
return varr.Expression;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
48
MBS.Framework/Logic/Variable.cs
Normal file
48
MBS.Framework/Logic/Variable.cs
Normal file
@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MBS.Framework.Logic
|
||||
{
|
||||
public class Variable
|
||||
{
|
||||
public class VariableCollection
|
||||
: System.Collections.ObjectModel.Collection<Variable>
|
||||
{
|
||||
private Dictionary<string, Variable> _itemsByName = new Dictionary<string, Variable>();
|
||||
public Variable this[string name]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_itemsByName.ContainsKey(name))
|
||||
return _itemsByName[name];
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ClearItems()
|
||||
{
|
||||
base.ClearItems();
|
||||
_itemsByName.Clear();
|
||||
}
|
||||
protected override void InsertItem(int index, Variable item)
|
||||
{
|
||||
base.InsertItem(index, item);
|
||||
_itemsByName[item.Name] = item;
|
||||
}
|
||||
protected override void RemoveItem(int index)
|
||||
{
|
||||
_itemsByName.Remove(this[index].Name);
|
||||
base.RemoveItem(index);
|
||||
}
|
||||
}
|
||||
|
||||
public string Name { get; set; } = null;
|
||||
public Expression Expression { get; set; } = null;
|
||||
|
||||
public Variable(string name, Expression expression)
|
||||
{
|
||||
Name = name;
|
||||
Expression = expression;
|
||||
}
|
||||
}
|
||||
}
|
||||
16
MBS.Framework/Logic/VariableRequestedEvent.cs
Normal file
16
MBS.Framework/Logic/VariableRequestedEvent.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using System;
|
||||
namespace MBS.Framework.Logic
|
||||
{
|
||||
public class VariableRequestedEventArgs : EventArgs
|
||||
{
|
||||
public bool Handled { get; set; } = false;
|
||||
public string VariableName { get; set; } = null;
|
||||
public object Value { get; set; } = null;
|
||||
|
||||
public VariableRequestedEventArgs(string variableName)
|
||||
{
|
||||
VariableName = variableName;
|
||||
}
|
||||
}
|
||||
public delegate void VariableRequestedEventHandler(object sender, VariableRequestedEventArgs e);
|
||||
}
|
||||
@ -50,6 +50,20 @@
|
||||
<Compile Include="ArrayExtensions.cs" />
|
||||
<Compile Include="Reflection.cs" />
|
||||
<Compile Include="Security\Cryptography\ExtensionMethods.cs" />
|
||||
<Compile Include="Logic\Expression.cs" />
|
||||
<Compile Include="Logic\Expressions\BooleanExpression.cs" />
|
||||
<Compile Include="Logic\Expressions\LiteralExpression.cs" />
|
||||
<Compile Include="Logic\Expressions\ComplexExpression.cs" />
|
||||
<Compile Include="Logic\Expressions\VariableExpression.cs" />
|
||||
<Compile Include="Logic\ExpressionContext.cs" />
|
||||
<Compile Include="Logic\Variable.cs" />
|
||||
<Compile Include="Logic\Expressions\EmptyExpression.cs" />
|
||||
<Compile Include="Logic\Expressions\ArithmeticExpression.cs" />
|
||||
<Compile Include="Logic\VariableRequestedEvent.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Logic\" />
|
||||
<Folder Include="Logic\Expressions\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user