Skip to content

Commit

Permalink
feat: introduce the interface IContext and variables as Func<object> (#…
Browse files Browse the repository at this point in the history
…231)

feat: introduce the interface IContext
  • Loading branch information
Seddryck authored Dec 29, 2023
1 parent 10fc87a commit 6533e9c
Show file tree
Hide file tree
Showing 10 changed files with 42 additions and 57 deletions.
8 changes: 7 additions & 1 deletion Expressif/Context.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,14 @@

namespace Expressif;

public class Context
public class Context : IContext
{
public ContextVariables Variables { get; } = new ();
public ContextObject CurrentObject { get; } = new ();
}

public interface IContext
{
ContextVariables Variables { get; }
ContextObject CurrentObject { get; }
}
4 changes: 2 additions & 2 deletions Expressif/Expression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ public class Expression : IFunction
private readonly IFunction expression;
public Expression(string code)
: this(code, new Context()) { }
public Expression(string code, Context context)
public Expression(string code, IContext context)
: this(code, context, new ExpressionFactory()) { }
public Expression(string code, Context context, ExpressionFactory factory)
public Expression(string code, IContext context, ExpressionFactory factory)
=> expression = factory.Instantiate(code, context);

public object? Evaluate(object? value) => expression.Evaluate(value);
Expand Down
4 changes: 2 additions & 2 deletions Expressif/ExpressionBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ namespace Expressif;
public class ExpressionBuilder
{

private Context Context { get; }
private IContext Context { get; }
private ExpressionFactory Factory { get; }
private ExpressionSerializer Serializer { get; }

public ExpressionBuilder()
: this(new Context()) { }
public ExpressionBuilder(Context? context = null, ExpressionFactory? factory = null, ExpressionSerializer? serializer = null)
public ExpressionBuilder(IContext? context = null, ExpressionFactory? factory = null, ExpressionSerializer? serializer = null)
=> (Context, Factory, Serializer) = (context ?? new Context(), factory ?? new ExpressionFactory(), serializer ?? new ExpressionSerializer());

private Queue<IExpression> Pile { get; } = new();
Expand Down
14 changes: 7 additions & 7 deletions Expressif/Functions/BaseExpressionFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ public abstract class BaseExpressionFactory
protected BaseExpressionFactory(BaseTypeMapper typeSetter)
=> TypeMapper = typeSetter;

protected internal T Instantiate<T>(string functionName, IParameter[] parameters, Context context)
protected internal T Instantiate<T>(string functionName, IParameter[] parameters, IContext context)
=> Instantiate<T>(TypeMapper.Execute(functionName), parameters, context);

protected T Instantiate<T>(Type type, IParameter[] parameters, Context context)
protected T Instantiate<T>(Type type, IParameter[] parameters, IContext context)
{
var ctor = GetMatchingConstructor(type, parameters.Length);

Expand Down Expand Up @@ -53,9 +53,9 @@ protected internal ConstructorInfo GetMatchingConstructor(Type type, int paramCo
=> type.GetConstructors().SingleOrDefault(x => x.GetParameters().Length == paramCount)
?? throw new MissingOrUnexpectedParametersFunctionException(type.Name, paramCount);

protected Delegate InstantiateScalarDelegate(IParameter parameter, Type scalarType, Context context)
protected Delegate InstantiateScalarDelegate(IParameter parameter, Type scalarType, IContext context)
{
var instantiate = typeof(BaseExpressionFactory).GetMethod(nameof(InstantiateScalarResolver), BindingFlags.Static | BindingFlags.NonPublic, [typeof(IParameter), typeof(Context)])
var instantiate = typeof(BaseExpressionFactory).GetMethod(nameof(InstantiateScalarResolver), BindingFlags.Static | BindingFlags.NonPublic, [typeof(IParameter), typeof(IContext)])
?? throw new InvalidProgramException(nameof(InstantiateScalarResolver));
var instantiateGeneric = instantiate.MakeGenericMethod(scalarType);
var resolver = instantiateGeneric.Invoke(null, new object[] { parameter, context })!;
Expand All @@ -66,7 +66,7 @@ protected Delegate InstantiateScalarDelegate(IParameter parameter, Type scalarTy
return Delegate.CreateDelegate(funcType, resolver, execute);
}

private static IScalarResolver<T> InstantiateScalarResolver<T>(IParameter parameter, Context context)
private static IScalarResolver<T> InstantiateScalarResolver<T>(IParameter parameter, IContext context)
=> parameter switch
{
LiteralParameter l => InstantiateScalarResolver<T>(typeof(LiteralScalarResolver<T>), [l.Value]),
Expand All @@ -79,7 +79,7 @@ private static IScalarResolver<T> InstantiateScalarResolver<T>(IParameter parame
private static IScalarResolver<T> InstantiateScalarResolver<T>(Type generic, object[] parameters)
=> (Activator.CreateInstance(generic, parameters) as IScalarResolver<T>)!;

protected Delegate InstantiateIntervalDelegate(IParameter parameter, Type type, Context context)
protected Delegate InstantiateIntervalDelegate(IParameter parameter, Type type, IContext context)
{
if (parameter is not IntervalParameter i)
throw new ArgumentOutOfRangeException(nameof(parameter));
Expand All @@ -99,7 +99,7 @@ protected Delegate InstantiateIntervalDelegate(IParameter parameter, Type type,
return Delegate.CreateDelegate(funcType, resolver, execute);
}

protected Delegate InstantiateInputExpressionDelegate(InputExpressionParameter exp, Type type, Context context)
protected Delegate InstantiateInputExpressionDelegate(InputExpressionParameter exp, Type type, IContext context)
{
var functions = new List<IFunction>();
foreach (var member in exp.Expression.Members)
Expand Down
6 changes: 3 additions & 3 deletions Expressif/Functions/ExpressionFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class ExpressionFactory : BaseExpressionFactory
public ExpressionFactory()
: base(new FunctionTypeMapper()) { }

public IFunction Instantiate(string code, Context context)
public IFunction Instantiate(string code, IContext context)
{
var expression = Parser.Parse(code);

Expand All @@ -30,9 +30,9 @@ public IFunction Instantiate(string code, Context context)
return new ChainFunction(functions);
}

public IFunction Instantiate(string name, IParameter[] parameters, Context context)
public IFunction Instantiate(string name, IParameter[] parameters, IContext context)
=> Instantiate<IFunction>(name, parameters, context);

public IFunction Instantiate(Type type, IParameter[] parameters, Context context)
public IFunction Instantiate(Type type, IParameter[] parameters, IContext context)
=> Instantiate<IFunction>(type, parameters, context);
}
27 changes: 0 additions & 27 deletions Expressif/Functions/ExpressionMember.cs

This file was deleted.

10 changes: 5 additions & 5 deletions Expressif/Predicates/PredicationFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ protected internal PredicationFactory(PredicateTypeMapper mapper, UnaryOperatorF
public PredicationFactory()
: this(new PredicateTypeMapper(), new UnaryOperatorFactory(), new BinaryOperatorFactory()) { }

public virtual IPredicate Instantiate(string code, Context context)
public virtual IPredicate Instantiate(string code, IContext context)
{
var predication = Parser.Parse(code);
var predicate = Instantiate(predication, context);
return predicate;
}

public IPredicate Instantiate(IPredication predication, Context context)
public IPredicate Instantiate(IPredication predication, IContext context)
=> predication switch
{
SinglePredication single => Instantiate(single, context),
Expand All @@ -42,21 +42,21 @@ public IPredicate Instantiate(IPredication predication, Context context)
_ => throw new NotImplementedException()
};

internal IPredicate Instantiate(SinglePredication basic, Context context)
internal IPredicate Instantiate(SinglePredication basic, IContext context)
{
var predicates = new List<IPredicate>();
foreach (var predicate in basic.Members)
predicates.Add(Instantiate<IPredicate>(predicate.Name, predicate.Parameters, context));
return predicates[0];
}

internal IPredicate Instantiate(UnaryPredication unary, Context context)
internal IPredicate Instantiate(UnaryPredication unary, IContext context)
{
var predicate = Instantiate(unary.Member, context);
return UnaryOperatorFactory.Instantiate(unary.Operator.Name, predicate);
}

internal IPredicate Instantiate(BinaryPredication binary, Context context)
internal IPredicate Instantiate(BinaryPredication binary, IContext context)
{
var left = Instantiate(binary.LeftMember, context);
var right = Instantiate(binary.RightMember, context);
Expand Down
4 changes: 2 additions & 2 deletions Expressif/Predication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ public class Predication : IPredicate

public Predication(string code)
: this(code, new Context()) { }
public Predication(string code, Context context)
public Predication(string code, IContext context)
: this(code, context, new PredicationFactory()) { }
public Predication(string code, Context context, PredicationFactory factory)
public Predication(string code, IContext context, PredicationFactory factory)
=> predicate = factory.Instantiate(code, context);

public virtual bool Evaluate(object? value) => predicate.Evaluate(value)!;
Expand Down
4 changes: 2 additions & 2 deletions Expressif/PredicationBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ namespace Expressif;

public class PredicationBuilder
{
private Context Context { get; }
private IContext Context { get; }
private PredicationFactory Factory { get; }
private PredicationSerializer Serializer { get; }

public PredicationBuilder()
: this(new Context()) { }
public PredicationBuilder(Context? context = null, PredicationFactory? factory = null, PredicationSerializer? serializer = null)
public PredicationBuilder(IContext? context = null, PredicationFactory? factory = null, PredicationSerializer? serializer = null)
=> (Context, Factory, Serializer) = (context ?? new Context(), factory ?? new(), serializer ?? new());

private IPredication? Pile { get; set; }
Expand Down
18 changes: 12 additions & 6 deletions Expressif/Values/ContextVariables.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ namespace Expressif.Values;

public class ContextVariables
{
private IDictionary<string, IScalarResolver> Variables { get; } = new Dictionary<string, IScalarResolver>();
private IDictionary<string, Func<object?>> Variables { get; } = new Dictionary<string, Func<object?>>();

internal void Add(string name, IScalarResolver value)
public void Add(string name, Func<object?> value)
{
name = name.StartsWith('@') ? name[1..] : name;
if (Variables.ContainsKey(name))
Expand All @@ -20,9 +20,12 @@ internal void Add(string name, IScalarResolver value)
}

public void Add<T>(string name, object value)
=> Add(name, new LiteralScalarResolver<T>(value));
{
var resolver = new LiteralScalarResolver<T>(value);
Add(name, () => resolver.Execute());
}

internal void Set(string name, IScalarResolver value)
public void Set(string name, Func<object?> value)
{
name = name.StartsWith('@') ? name[1..] : name;
if (Variables.ContainsKey(name))
Expand All @@ -32,7 +35,10 @@ internal void Set(string name, IScalarResolver value)
}

public void Set<T>(string name, object value)
=> Set(name, new LiteralScalarResolver<T>(value));
{
var resolver = new LiteralScalarResolver<T>(value);
Set(name, () => resolver.Execute());
}

public void Remove(string name)
{
Expand All @@ -49,7 +55,7 @@ public object? this[string name]
{
name = name.StartsWith('@') ? name[1..] : name;
if (Variables.TryGetValue(name, out var value))
return value.Execute();
return value.Invoke();
throw new UnexpectedVariableException(name);
}
}
Expand Down

0 comments on commit 6533e9c

Please sign in to comment.