コード例 #1
0
        public LocalizedLibraryView GetOrImportLibrary(ParserContext parser, Token throwToken, string fullImportNameWithDots)
        {
            LocalizedLibraryView libView = this.GetOrImportLibraryImpl(parser, throwToken, fullImportNameWithDots);

            if (libView != null && libView.LibraryScope != parser.CurrentScope)
            {
                parser.CurrentScope.AddDependency(throwToken, libView);
            }
            return(libView);
        }
コード例 #2
0
ファイル: CompilationScope.cs プロジェクト: elimisteve/crayon
 public void AddDependency(Token throwToken, LocalizedLibraryView libraryView)
 {
     if (this == libraryView.LibraryScope)
     {
         throw new System.Exception();                                   // This should not happen.
     }
     if (this.dependenciesAndViews.ContainsKey(libraryView.LibraryScope))
     {
         if (this.dependenciesAndViews[libraryView.LibraryScope] != libraryView)
         {
             throw new ParserException(throwToken, "Cannot import the same library multiple times from different locales.");
         }
     }
     this.dependenciesAndViews[libraryView.LibraryScope] = libraryView;
 }
コード例 #3
0
        public void ParseInterpretedCode(string filename, string code)
        {
            FileScope fileScope = new FileScope(filename, this.CurrentScope);
            int       fileId    = this.GetNextFileId();

            this.RegisterFileUsed(filename, code, fileId);
            Token[]     tokenList = Tokenizer.Tokenize(filename, code, fileId, true);
            TokenStream tokens    = new TokenStream(tokenList, filename);

            List <string> namespaceImportsBuilder = new List <string>();

            // Implicitly import the Core library for the current locale.
            LocalizedLibraryView implicitCoreImport = this.LibraryManager.GetCoreLibrary(this);

            namespaceImportsBuilder.Add(implicitCoreImport.Name);
            fileScope.Imports.Add(new ImportStatement(null, implicitCoreImport.Name, this.CurrentLibrary, fileScope));

            while (tokens.HasMore && tokens.IsNext(this.Keywords.IMPORT))
            {
                ImportStatement importStatement = this.ExecutableParser.ParseTopLevel(tokens, null, fileScope) as ImportStatement;
                if (importStatement == null)
                {
                    throw new Exception();
                }
                namespaceImportsBuilder.Add(importStatement.ImportPath);
                LocalizedLibraryView localizedLibraryView = this.LibraryManager.GetOrImportLibrary(this, importStatement.FirstToken, importStatement.ImportPath);
                if (localizedLibraryView == null)
                {
                    this.unresolvedImports.Add(importStatement);
                }
            }

            string[] namespaceImports = namespaceImportsBuilder.ToArray();

            while (tokens.HasMore)
            {
                TopLevelConstruct executable = this.ExecutableParser.ParseTopLevel(tokens, null, fileScope);

                if (executable is ImportStatement)
                {
                    throw this.GenerateParseError(
                              ErrorMessages.ALL_IMPORTS_MUST_OCCUR_AT_BEGINNING_OF_FILE,
                              executable.FirstToken);
                }

                this.CurrentScope.AddExecutable(executable);
            }
        }
コード例 #4
0
 public void AddDependency(Token throwToken, LocalizedLibraryView libraryView)
 {
     if (this == libraryView.LibraryScope)
     {
         throw new System.Exception();                                   // This should not happen.
     }
     if (this.dependenciesAndViews.ContainsKey(libraryView.LibraryScope))
     {
         if (this.dependenciesAndViews[libraryView.LibraryScope] != libraryView)
         {
             throw ParserException.ThrowException(
                       libraryView.Locale,
                       ErrorMessages.CANNOT_IMPORT_SAME_LIBRARY_FROM_DIFFERENT_LOCALES,
                       throwToken);
         }
     }
     this.dependenciesAndViews[libraryView.LibraryScope] = libraryView;
 }
コード例 #5
0
        private LocalizedLibraryView GetOrImportLibraryImpl(ParserContext parser, Token throwToken, string fullImportNameWithDots)
        {
            // TODO: allow importing from a user-specified locale
            Locale fromLocale = parser.CurrentLocale;
            string name       = fullImportNameWithDots.Contains('.') ? fullImportNameWithDots.Split('.')[0] : fullImportNameWithDots;

            string          secondAttemptedKey = name;
            LibraryMetadata libraryMetadata    = this.libraryFinder.GetLibraryMetadataFromAnyPossibleKey(fromLocale.ID + ":" + name);
            Locale          effectiveLocale    = fromLocale;

            if (libraryMetadata == null)
            {
                libraryMetadata = this.libraryFinder.GetLibraryMetadataFromAnyPossibleKey(name);
                if (libraryMetadata != null &&
                    libraryMetadata.SupportedLocales.Contains(fromLocale) &&
                    libraryMetadata.InternalLocale != fromLocale)
                {
                    // Coincidental cross-language collision.
                    return(null);
                }

                if (libraryMetadata == null)
                {
                    // Simply no matches at all.
                    return(null);
                }

                effectiveLocale = libraryMetadata.InternalLocale;
            }

            // Are there any restrictions on importing that library from this location?
            if (!libraryMetadata.IsAllowedImport(parser.CurrentLibrary))
            {
                throw new ParserException(throwToken, "This library cannot be imported from here.");
            }

            // Ensure all secondary lookups for each locale is instantiated to make the upcoming code more readable.
            if (!this.importedLibrariesByLocalizedName.ContainsKey(effectiveLocale))
            {
                this.importedLibrariesByLocalizedName[effectiveLocale] = new Dictionary <string, LocalizedLibraryView>();
            }
            if (!this.importedLibrariesByLocalizedName.ContainsKey(libraryMetadata.InternalLocale))
            {
                this.importedLibrariesByLocalizedName[libraryMetadata.InternalLocale] = new Dictionary <string, LocalizedLibraryView>();
            }

            // Check to see if this library has been imported before.
            if (this.importedLibrariesById.ContainsKey(libraryMetadata.ID))
            {
                // Is it imported by the same locale?
                if (this.importedLibrariesByLocalizedName[effectiveLocale].ContainsKey(name))
                {
                    // Then just return the previous instance as-is.
                    return(this.importedLibrariesByLocalizedName[effectiveLocale][name]);
                }

                // Wrap the previous instance in the new locale.
                LocalizedLibraryView output = new LocalizedLibraryView(effectiveLocale, this.importedLibrariesById[libraryMetadata.ID]);
                this.importedLibrariesByLocalizedName[effectiveLocale][output.Name] = output;
                return(output);
            }

            // If the library exists but hasn't been imported before, instantiate it and
            // add it to all the lookups. This needs to happen before parsing the embedded
            // code to prevent infinite recursion.
            LibraryCompilationScope libraryScope = new LibraryCompilationScope(parser.BuildContext, libraryMetadata);

            this.librariesAlreadyImportedIndexByKey[libraryMetadata.CanonicalKey] = this.ImportedLibraries.Count;
            this.ImportedLibraries.Add(libraryScope);
            this.importedLibrariesById[libraryMetadata.ID] = libraryScope;
            LocalizedLibraryView localizedView = new LocalizedLibraryView(effectiveLocale, libraryScope);

            this.importedLibrariesByLocalizedName[effectiveLocale][name] = localizedView;

            // Parse the library.
            parser.PushScope(libraryScope);
            Dictionary <string, string> embeddedCode = libraryMetadata.GetEmbeddedCode();

            foreach (string embeddedFile in embeddedCode.Keys.OrderBy(s => s.ToLower()))
            {
                string fakeName = "[" + embeddedFile + "]";
                string code     = embeddedCode[embeddedFile];
                parser.ParseInterpretedCode(fakeName, code);
            }
            parser.PopScope();

            return(localizedView);
        }