Ejemplo n.º 1
0
        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);
        }