void CheckCircularReference(ContextValue contextValue, ISet <string> chain, T input) { foreach (string dependee in contextValue.Dependees) { if (chain.Contains(dependee)) { throw new CircularReferenceException(dependee, string.IsNullOrEmpty(contextValue.Name) ? Convert.ToString(contextValue.Value) : contextValue.Name); } ContextValue value; if (TryGetContext(dependee, input, out value) && value.ContextType == Albatross.Expression.ContextType.Expression) { ISet <string> newChain = NewSet(); foreach (var item in chain) { newChain.Add(item); } newChain.Add(dependee); if (value.Tree == null) { Build(value, newChain); } CheckCircularReference(value, newChain, input); } } }
bool TryGetExternal(string name, T input, out ContextValue value) { object data; if (TryGetExternalData != null && TryGetExternalData(name, input, out data)) { if (data is ContextValue) { value = (ContextValue)data; } else { value = new ContextValue() { Name = name, Value = data, ContextType = ContextType.Value, }; } value.External = true; if (value.ContextType == ContextType.Expression || CacheExternalValue) { Store.Add(name, value); } return(true); } else { value = null; return(false); } }
object GetContextValue(ContextValue contextValue, T input) { if (contextValue.ContextType == Albatross.Expression.ContextType.Expression) { ISet <string> chain = NewSet(); if (!string.IsNullOrEmpty(contextValue.Name)) { chain.Add(contextValue.Name); } if (contextValue.Tree == null) { Build(contextValue, chain); } CheckCircularReference(contextValue, chain, input); object data = Parser.Eval(contextValue.Tree, new Func <string, object>(name => GetValue(name, input))); if (data != null && contextValue.DataType != null && contextValue.DataType != data.GetType()) { data = Convert.ChangeType(data, contextValue.DataType); } return(data); } else { return(contextValue.Value); } }
public void Set(ContextValue value) { Store[value.Name] = value; if (value.ContextType == ContextType.Expression) { Compiled = false; } }
public object Eval(string expression, T input, Type outputDataType = null) { ContextValue value; if (!_expressions.TryGetValue(expression, out value)) { value = new ContextValue() { Value = expression, DataType = outputDataType, ContextType = ContextType.Expression, }; _expressions.Add(expression, value); } return(GetContextValue(value, input)); }
void Build(ContextValue contextValue, ISet <string> chain) { contextValue.Tree = null; Queue <IToken> queue = Parser.Tokenize(Convert.ToString(contextValue.Value)); contextValue.Dependees = NewSet(); foreach (IToken token in queue) { if (token.IsVariable()) { contextValue.Dependees.Add(token.Name); } } Stack <IToken> stack = Parser.BuildStack(queue); contextValue.Tree = Parser.CreateTree(stack); }
public static ContextValue Set <T>(this IExecutionContext <T> context, string assignmentExpression) { ContextValue value = new ContextValue { ContextType = ContextType.Expression, }; IToken token = context.Parser.VariableToken(); int start = 0, next; if (token.Match(assignmentExpression, start, out next)) { start = assignmentExpression.SkipSpace(start); value.Name = assignmentExpression.Substring(start, next - start); start = next; if (new AssignmentToken().Match(assignmentExpression, start, out next)) { value.Value = assignmentExpression.Substring(next); context.Set(value); return(value); } } throw new Exceptions.TokenParsingException("Invalid assignment expression"); }
bool TryGetExternal(string name, object input, bool contextOnly, out object data) { ContextValue value; if (TryGetExternalData != null && TryGetExternalData(name, input, out data)) { if (data is ContextValue) { value = (ContextValue)data; if (CacheExternalValue) { Store.Add(name, value); } if (!contextOnly) { data = value.GetValue(Parser, this, input); } } else { value = new ContextValue() { Name = name, Value = data, ContextType = ContextType.Value, }; if (CacheExternalValue) { Store.Add(name, value); } if (contextOnly) { data = value; } } return true; } else { data = null; return false; } }
internal bool TryGetContext(string name, object input, out ContextValue value) { Object data; if (Store.TryGetValue(name, out value)) { return true; } else if (TryGetExternal(name, input, true, out data)) { value = (ContextValue)data; return true; } else { value = null; return false; } }
public void Set(ContextValue value) { Store[value.Name] = value; }
public object Eval(string expression, object input, Type outputDataType = null) { ContextValue value; if (!_evalStacks.TryGetValue(expression, out value)) { value = new ContextValue() { Value = expression, DataType = outputDataType, ContextType = ContextType.Expression, }; _evalStacks.Add(expression, value); } return value.GetValue(Parser, this, input); }
bool TryGetContext(string name, T input, out ContextValue value) { return(Store.TryGetValue(name, out value) || TryGetExternal(name, input, out value)); }