public SizeExpr Clone(string renaming = null) { //// Note: Recursive implementation. Depth of sizeExpr not expected to be large. if (string.IsNullOrEmpty(renaming)) { return(this); } switch (Kind) { case SizeExprKind.Infinity: return(this); case SizeExprKind.Count: return(new SizeExpr(string.Format("{0}.{1}", renaming, (string)Raw))); case SizeExprKind.Sum: { var tup = (Tuple <BigInteger, LinkedList <SizeExpr> >)Raw; var clonedSum = new LinkedList <SizeExpr>(); foreach (var e in tup.Item2) { clonedSum.AddLast(e.Clone(renaming)); } return(new SizeExpr(tup.Item1, clonedSum)); } case SizeExprKind.Prod: { var args = (SizeExpr[])Raw; var clonedArgs = new SizeExpr[args.Length]; for (int i = 0; i < args.Length; ++i) { clonedArgs[i] = args[i].Clone(renaming); } return(new SizeExpr(clonedArgs)); } default: throw new NotImplementedException(); } }
internal bool TryAddSymbol( UserSymbol symbol, Func <int> idGetter, List <Flag> flags, SizeExpr sizeExpr = null) { Contract.Requires(symbol != null && symbol.Namespace == this && idGetter != null); UserSymbol existingSym; if (!symbols.TryFindValue(symbol.Name, out existingSym)) { if (!symbol.IsAutoGen && !API.ASTQueries.ASTSchema.Instance.IsId(symbol.Name, false, false, false, false)) { var ast = symbol.Definitions.First <AST <Node> >(); var flag = new Flag( SeverityKind.Error, ast.Node, Constants.BadId.ToString(symbol.Name, "symbol"), Constants.BadId.Code, ast.Root.NodeKind == NodeKind.Program ? ((Program)ast.Root).Name : null); flags.Add(flag); return(false); } symbol.Id = idGetter(); symbols.Add(symbol.Name, symbol); if (symbol.Kind == SymbolKind.ConSymb) { var conSymb = ((ConSymb)symbol); var usrSort = new UserSortSymb(symbol); usrSort.Id = idGetter(); conSymb.SortSymbol = usrSort; if (sizeExpr != null) { usrSort.Size = sizeExpr; } } else if (symbol.Kind == SymbolKind.MapSymb) { var mapSymb = ((MapSymb)symbol); var usrSort = new UserSortSymb(symbol); usrSort.Id = idGetter(); mapSymb.SortSymbol = usrSort; if (sizeExpr != null) { usrSort.Size = sizeExpr; } } return(true); } if (!existingSym.IsCompatibleDefinition(symbol)) { var ast1 = symbol.Definitions.First <AST <Node> >(); var ast2 = existingSym.Definitions.First <AST <Node> >(); var flag = new Flag( SeverityKind.Error, ast1.Node, MessageHelpers.MkDupErrMsg(string.Format("symbol {0}", symbol.Name), ast1, ast2, SymbolTable.Env.Parameters), Constants.DuplicateDefs.Code, ast1.Root.NodeKind == NodeKind.Program ? ((Program)ast1.Root).Name : null); flags.Add(flag); return(false); } existingSym.MergeSymbolDefinition(symbol); return(true); }