diff options
| author | Tim Foley <tfoley@nvidia.com> | 2017-06-26 10:11:00 -0700 |
|---|---|---|
| committer | Tim Foley <tfoley@nvidia.com> | 2017-06-26 12:06:54 -0700 |
| commit | 6e99b81c98f8c76444563d959536073befc7d8ca (patch) | |
| tree | 84bb72a43c0a9725e7ada37f7df369e80ee6a62f /source/slang/slang.cpp | |
| parent | 7d3bfe403362b294cc2a1f2607d51dfcd447aafd (diff) | |
Make `#import` work with preprocessor macros
With this change, there is now a meaningful semantic difference between `__import` and `#import`.
An `__import` compiles the target file in a fresh environment, only providing it any macro definitions passed via command line or API. Any macros defined in the imported file are not made visible at the import site. One can think of an `__import` as a bit like `using namespace` in C++.
A `#import` will tokenize the input in the same preprocessor environment as the importing file, and any macros defined along the way will be visible in the parent file.
It is a *bit* like a `#include` with two big differences:
- The imported code is always parsed as Slang, and as its own module with default flags, etc. (so semantic checks are on even if we are in "rewriter" mode). It is pulled into the outer namespace just as for `__import`.
- A given file will only get `#import`ed once for a translation unit, so it behaves a bit like there is an implicit `#pragma once` in the target file
Diffstat (limited to 'source/slang/slang.cpp')
| -rw-r--r-- | source/slang/slang.cpp | 47 |
1 files changed, 28 insertions, 19 deletions
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index 76cb502c0..5e80dabf5 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -405,21 +405,39 @@ RefPtr<ProgramSyntaxNode> CompileRequest::loadModule( } -String CompileRequest::autoImportModule( +void CompileRequest::handlePoundImport( + String const& name, String const& path, - String const& source, - CodePosition const& loc) + TokenList const& tokens) { - // TODO: may want to have some kind of canonicalization step here - String name = path; + RefPtr<TranslationUnitRequest> translationUnit = new TranslationUnitRequest(); + translationUnit->compileRequest = this; - // Have we already loaded a module matching this name? - if (loadedModulesMap.TryGetValue(name)) - return name; + // Imported code is always native Slang code + RefPtr<Scope> languageScope = mSession->slangLanguageScope; + + RefPtr<ProgramSyntaxNode> translationUnitSyntax = new ProgramSyntaxNode(); + translationUnit->SyntaxNode = translationUnitSyntax; + + parseSourceFile( + translationUnit.Ptr(), + tokens, + &mSink, + path, + languageScope); + + // TODO: handle errors + + checkTranslationUnit(translationUnit.Ptr()); + + // Skip code generation + + // - loadModule(name, path, source, loc); + RefPtr<ProgramSyntaxNode> moduleDecl = translationUnit->SyntaxNode; - return name; + loadedModulesMap.Add(name, moduleDecl); + loadedModulesList.Add(moduleDecl); } RefPtr<ProgramSyntaxNode> CompileRequest::findOrImportModule( @@ -494,15 +512,6 @@ RefPtr<ProgramSyntaxNode> findOrImportModule( return request->findOrImportModule(name, loc); } -String autoImportModule( - CompileRequest* request, - String const& path, - String const& source, - CodePosition const& loc) -{ - return request->autoImportModule(path, source, loc); -} - void Session::addBuiltinSource( RefPtr<Scope> const& scope, String const& path, |
