private ExpressionContainer GetOrAddExpressionContainer(IfDefSet ifDefs) { ExpressionContainer container; if (_knownReferences.TryGetValue(ifDefs, out container)) { return(container); } if (ifDefs.Count == 1) { return(AddIfDefExpressionContainer(ifDefs.First())); } container = new ExpressionContainer(); var listContainers = new List <ExpressionContainer>(ifDefs.Count); foreach (var ifDef in ifDefs) { listContainers.Add(GetOrAddExpressionContainer(new IfDefSet(ifDef))); } var operands = new Operands(listContainers.Select(_ => _.FlatExpression.Operands).SelectMany(_ => _) .Distinct().OrderBy(_ => _).ToArray()); var flatExpr = new FlatExpression(operands); foreach (var c in listContainers) { flatExpr = flatExpr.Or(c.FlatExpression); } container.FlatExpression = flatExpr; _knownReferences.Add(ifDefs, container); return(container); }
public void Clone_FlatMultExpression() { //Arrange var expression = new FlatMultExpression(); expression.Add(new VariableExpression("x", 1)); expression.Add(new NumberExpression(3)); //Act var clone = (FlatMultExpression)expression.Clone(); //Assert Assert.IsTrue(DimensionKey.Compare(expression.DimensionKey, clone.DimensionKey)); Assert.IsTrue(FlatExpression.Compare(expression, clone)); }
/// <summary> /// Obtains a lambda expression of the form "x => x.ExpFieldName" given its flattened form. /// </summary> public static LambdaExpression Unflatten(this FlatExpression flatExp) { // We create a single parameter "x" expression var paramExp = Expression.Parameter(flatExp.ExpFieldDeclaringType, "x"); // We obtain the property of the original object, and we create an expression of form "x.ExpFieldName" var property = flatExp.ExpFieldDeclaringType.GetProperty(flatExp.ExpFieldName).DeclaringType.GetProperty(flatExp.ExpFieldName); var memberExp = Expression.MakeMemberAccess(paramExp, property); // We create a function Func<ObjectType, PropertyType> to be used in the lambda expression var funcType = typeof(Func <,>).MakeGenericType(new Type[] { flatExp.ExpFieldDeclaringType, flatExp.ExpFieldType }); // The final lambda expression is created return(Expression.Lambda(funcType, memberExp, paramExp)); }
public void Clone_FlatAddExpression_Inversed() { //Arrange var flatAdd = new FlatAddExpression(); flatAdd.Add(new VariableExpression("x", 1)); flatAdd.Add(new NumberExpression(3)); var expression = (FlatAddExpression)(new BinaryExpression(flatAdd, OperatorTypes.Power, new NumberExpression(-1)).Execute()); //Act var clone = (FlatAddExpression)expression.Clone(); //Assert Assert.IsTrue(DimensionKey.Compare(expression.DimensionKey, clone.DimensionKey)); Assert.IsTrue(FlatExpression.Compare(expression, clone)); }
private ExpressionContainer AddIfDefExpressionContainer(IfDefReference ifdef) { var expr = new FlatExpression(new Operands(ifdef.Node.Value), new FlatExpressionLine(ifdef.Defined ? 1ul : 0ul)); if (ifdef.Node.Extra.Define.IfDefs?.Count > 0) { var parentIfDefs = ifdef.Node.Extra.Define.IfDefs; var listContainers = new List <ExpressionContainer>(parentIfDefs.Count); foreach (var ifDef in parentIfDefs) { listContainers.Add(GetOrAddExpressionContainer(new IfDefSet(ifDef))); } var operands = new Operands(listContainers .Select(_ => _.FlatExpression.Operands.Concat(expr.Operands)) .SelectMany(_ => _) .Distinct() .OrderBy(_ => _) .ToArray()); var flatExpr = new FlatExpression(operands); foreach (var c in listContainers) { flatExpr = flatExpr.Or(c.FlatExpression); } expr = flatExpr.And(expr); } if (ifdef.Defined) { ifdef.Node.Extra.Define.IfDefExpression = expr.AsTreeExpression().ToString(); } else { ifdef.Node.Extra.Define.IfNotDefExpression = expr.AsTreeExpression().ToString(); } var container = new ExpressionContainer { FlatExpression = expr }; _knownReferences.Add(new IfDefSet(ifdef), container); return(container); }