Пример #1
0
        private Dictionary <string, TopLevelConstruct> CreateFullyQualifiedLookup(IList <TopLevelConstruct> code)
        {
            using (new PerformanceSection(""))
            {
                HashSet <string> namespaces = new HashSet <string>();

                Dictionary <string, TopLevelConstruct> lookup = new Dictionary <string, TopLevelConstruct>();
                bool mainFound = false;
                foreach (TopLevelConstruct item in code)
                {
                    string ns;
                    string memberName;
                    if (item is FunctionDefinition)
                    {
                        FunctionDefinition fd = (FunctionDefinition)item;
                        ns         = fd.Namespace;
                        memberName = fd.NameToken.Value;
                        if (memberName == "main")
                        {
                            if (mainFound)
                            {
                                throw new ParserException(item.FirstToken, "Multiple main methods found.");
                            }
                            mainFound   = true;
                            lookup["~"] = item;
                        }
                    }
                    else if (item is ClassDefinition)
                    {
                        ClassDefinition cd = (ClassDefinition)item;
                        ns         = cd.Namespace;
                        memberName = cd.NameToken.Value;

                        // TODO: nested classes, constants, and enums.
                    }
                    else if (item is EnumDefinition)
                    {
                        EnumDefinition ed = (EnumDefinition)item;
                        ns         = ed.Namespace;
                        memberName = ed.Name;
                    }
                    else if (item is ConstStatement)
                    {
                        ConstStatement cs = (ConstStatement)item;
                        ns         = cs.Namespace;
                        memberName = cs.Name;
                    }
                    else
                    {
                        string error = "This sort of expression cannot exist outside of function or field definitions.";
                        throw new ParserException(item.FirstToken, error);
                    }

                    if (ns.Length > 0)
                    {
                        string accumulator = "";
                        foreach (string nsPart in ns.Split('.'))
                        {
                            if (accumulator.Length > 0)
                            {
                                accumulator += ".";
                            }
                            accumulator += nsPart;
                            namespaces.Add(accumulator);
                        }
                    }

                    string fullyQualifiedName = (ns.Length > 0 ? (ns + ".") : "") + memberName;

                    if (lookup.ContainsKey(fullyQualifiedName))
                    {
                        // TODO: token information from two locations
                        throw new ParserException(item.FirstToken, "Two items have identical fully-qualified names: '" + fullyQualifiedName + "'");
                    }
                    lookup[fullyQualifiedName] = item;
                }

                foreach (string key in lookup.Keys)
                {
                    if (namespaces.Contains(key))
                    {
                        throw new ParserException(lookup[key].FirstToken, "This name collides with a namespace definition.");
                    }
                }

                // Go through and fill in all the partially qualified namespace names.
                foreach (string ns in namespaces)
                {
                    Namespace nsInstance          = new Namespace(null, ns, null, null, null);
                    string    possibleLibraryName = ns.Split('.')[0];

                    TODO.EnglishLocaleAssumed();
                    Library library = this.parser.LibraryManager.GetLibraryFromName(possibleLibraryName);
                    if (library != null)
                    {
                        // TODO: once you get rid of this line, make the Library setter protected
                        nsInstance.Library = library;
                    }
                    lookup[ns] = nsInstance;
                }

                if (lookup.ContainsKey("~"))
                {
                    FunctionDefinition mainFunc = (FunctionDefinition)lookup["~"];
                    if (mainFunc.ArgNames.Length > 1)
                    {
                        throw new ParserException(mainFunc.FirstToken, "The main function must accept 0 or 1 arguments.");
                    }
                }
                else
                {
                    throw new InvalidOperationException("No main(args) function was defined.");
                }

                return(lookup);
            }
        }