public static CasExpressionTree ToExpressionTree(this MathematicaExpression expr, IntegerSequenceGenerator seqGen, SortedDictionary <string, CasExpressionTreeNode> subExprDict, string lhsVarName) { var srcStk = new Stack <Expr>(); var dstStk = new Stack <CasExpressionTreeNode>(); var rootExpr = expr.Expression; var rootNode = new CasExpressionTreeNode(lhsVarName, expr); var tree = new CasExpressionTree(rootNode, subExprDict); var rootExprText = rootExpr.ToString(); if (subExprDict.ContainsKey(rootExprText) == false) { subExprDict.Add(rootExprText, rootNode); } srcStk.Push(rootExpr); dstStk.Push(rootNode); while (srcStk.Count > 0) { var curExpr = srcStk.Pop(); var curNode = dstStk.Pop(); if (curExpr.Args.Length > 0) { var newArgs = new object[curExpr.Args.Length]; var i = 0; foreach (var childExpr in curExpr.Args) { var childExprText = childExpr.ToString(); CasExpressionTreeNode childNode; if (subExprDict.TryGetValue(childExprText, out childNode) == false) { var childArgName = seqGen.GetNewStringId(); var childCasExpr = MathematicaExpression.Create(expr.CasInterface, childExpr); childNode = new CasExpressionTreeNode(childArgName, childCasExpr); subExprDict.Add(childExprText, childNode); } curNode.AddChild(childNode); srcStk.Push(childExpr); dstStk.Push(childNode); if (childExpr.AtomQ()) { newArgs[i] = childExpr; } else { newArgs[i] = new Expr(ExpressionType.Symbol, childNode.LhsVariableName); } i++; } curNode.RhsReducedExpression = MathematicaExpression.Create( expr.CasInterface, new Expr(curExpr.Head, newArgs) ); } else { curNode.RhsReducedExpression = curNode.RhsExpression; } } return(tree); }
/// <summary> /// A factory for returning the appropriate generator /// </summary> /// <param name="thisCustomAttribute">The decoration defining the generator</param> /// <param name="thisPropInfo">The reflected values of the property</param> /// <returns>IRandomGenerator</returns> private IDataGenerator GetGenerator(CustomAttributeData thisCustomAttribute, PropertyInfo thisPropInfo) { IDataGenerator generator = null; switch (thisCustomAttribute.AttributeType.Name) { case "IntegerGenerator": generator = new IntegerGenerator(); break; case "SingleGenerator": generator = new SingleGenerator(); break; case "SingleRangeGenerator": generator = GetPropertyInfoAttribute <SingleRangeGenerator>(thisPropInfo); if (generator == null) { generator = new DoubleRangeGenerator(Single.MinValue, Single.MaxValue); } break; case "DoubleGenerator": generator = new DoubleGenerator(); break; case "NormallyDistributedDoubleGenerator": generator = GetPropertyInfoAttribute <NormallyDistributedDoubleGenerator>(thisPropInfo); if (generator == null) { generator = new NormallyDistributedDoubleGenerator(0, 1); } break; case "DoubleRangeGenerator": generator = GetPropertyInfoAttribute <DoubleRangeGenerator>(thisPropInfo); if (generator == null) { generator = new DoubleRangeGenerator(double.MinValue, double.MaxValue); } break; case "BoolGenerator": generator = new BoolGenerator(); break; case "IntegerRangeGenerator": generator = GetPropertyInfoAttribute <IntegerRangeGenerator>(thisPropInfo); if (generator == null) { generator = new IntegerRangeGenerator(int.MinValue, int.MaxValue); } break; case "StringRangeGenerator": generator = GetPropertyInfoAttribute <StringRangeGenerator>(thisPropInfo); if (generator == null) { generator = new StringRangeGenerator(new string[] { "" }); } break; case "DateRangeGenerator": generator = GetPropertyInfoAttribute <DateRangeGenerator>(thisPropInfo); if (generator == null) { generator = new DateRangeGenerator(DateTime.MinValue, DateTime.MaxValue); } break; case "StringFromFileGenerator": string pathAsKey = thisCustomAttribute.ConstructorArguments.First().ToString(); // this is a cached generator, stored for the sake of not having to re-process the file if (cacheGenerators.ContainsKey(pathAsKey)) { generator = cacheGenerators[pathAsKey]; } else { // process the gerneator generator = GetPropertyInfoAttribute <StringFromFileGenerator>(thisPropInfo); // add to a cache cacheGenerators.Add(pathAsKey, generator); } if (generator == null) { generator = new StringRangeGenerator(new string[] { "" }); } break; case "IntegerSequenceGenerator": var key = thisPropInfo.Name + "/" + thisCustomAttribute.AttributeType.Name; if (cacheGenerators.ContainsKey(key)) { generator = cacheGenerators[key]; } else { // process the gerneator generator = GetPropertyInfoAttribute <IntegerSequenceGenerator>(thisPropInfo); // add to a cache cacheGenerators.Add(key, generator); } if (generator == null) { generator = new IntegerSequenceGenerator(); } break; case "DecimalGenerator": generator = new DecimalGenerator(); break; case "DecimalRangeGenerator": generator = GetPropertyInfoAttribute <DecimalRangeGenerator>(thisPropInfo); if (generator == null) { generator = new DecimalRangeGenerator(double.MinValue, double.MaxValue); } break; default: break; } return(generator); }