diff options
| author | Tim Foley <tfoley@nvidia.com> | 2017-06-26 09:32:40 -0700 |
|---|---|---|
| committer | Tim Foley <tfoley@nvidia.com> | 2017-06-26 12:06:54 -0700 |
| commit | 7d3bfe403362b294cc2a1f2607d51dfcd447aafd (patch) | |
| tree | 4dac8dcdb29a0d8e74f78f12c0bbe63e669b2b0c /source/slang/preprocessor.cpp | |
| parent | 3f316dcbd9274efc74f817cf36f17a511ff2e21e (diff) | |
Replace "auto-import" with `#import`
Right now `#import` only differs from `#include` in that it takes a string literal for a file name instead of a raw identifier (to which `.slang` gets appended).
The next step is to make `#import` respect preprocessor state, while `__import` doesn't.
Diffstat (limited to 'source/slang/preprocessor.cpp')
| -rw-r--r-- | source/slang/preprocessor.cpp | 116 |
1 files changed, 74 insertions, 42 deletions
diff --git a/source/slang/preprocessor.cpp b/source/slang/preprocessor.cpp index 00abb3fe5..b93e47ec2 100644 --- a/source/slang/preprocessor.cpp +++ b/source/slang/preprocessor.cpp @@ -1489,9 +1489,8 @@ static void expectEndOfDirective(PreprocessorDirectiveContext* context) AdvanceRawToken(context->preprocessor); } - -// Handle a `#include` directive -static void HandleIncludeDirective(PreprocessorDirectiveContext* context) +// Handle a `#import` directive +static void HandleImportDirective(PreprocessorDirectiveContext* context) { Token pathToken; if(!Expect(context, TokenType::StringLiterial, Diagnostics::expectedTokenInPreprocessorDirective, &pathToken)) @@ -1507,7 +1506,7 @@ static void HandleIncludeDirective(PreprocessorDirectiveContext* context) IncludeHandler* includeHandler = context->preprocessor->includeHandler; if (!includeHandler) { - GetSink(context)->diagnose(pathToken.Position, Diagnostics::includeFailed, path); + GetSink(context)->diagnose(pathToken.Position, Diagnostics::importFailed, path); GetSink(context)->diagnose(pathToken.Position, Diagnostics::noIncludeHandlerSpecified); return; } @@ -1517,10 +1516,10 @@ static void HandleIncludeDirective(PreprocessorDirectiveContext* context) { case IncludeResult::NotFound: case IncludeResult::Error: - GetSink(context)->diagnose(pathToken.Position, Diagnostics::includeFailed, path); + GetSink(context)->diagnose(pathToken.Position, Diagnostics::importFailed, path); return; - case IncludeResult::FoundIncludeFile: + case IncludeResult::Found: break; } @@ -1529,50 +1528,82 @@ static void HandleIncludeDirective(PreprocessorDirectiveContext* context) // a switch of input stream expectEndOfDirective(context); - switch( includeResult ) - { - case IncludeResult::FoundIncludeFile: - { - // Push the new file onto our stack of input streams - // TODO(tfoley): check if we have made our include stack too deep - PreprocessorInputStream* inputStream = CreateInputStreamForSource(context->preprocessor, foundSource, foundPath); - inputStream->parent = context->preprocessor->inputStream; - context->preprocessor->inputStream = inputStream; - } - break; - - case IncludeResult::FoundAutoImportFile: - { - // - - String autoImportName = autoImportModule( - context->preprocessor->compileRequest, - foundPath, - foundSource, - GetDirectiveLoc(context)); + // Import code from the chosen file + String autoImportName = autoImportModule( + context->preprocessor->compileRequest, + foundPath, + foundSource, + GetDirectiveLoc(context)); - SourceTextInputStream* inputStream = new SourceTextInputStream(); + // Now create a dummy token stream to represent the import request, + // so that it can be manifest in the user's program + SourceTextInputStream* inputStream = new SourceTextInputStream(); - Token token; - token.Type = TokenType::AutoImport; - token.Position = GetDirectiveLoc(context); - token.flags = 0; - token.Content = autoImportName; + Token token; + token.Type = TokenType::PoundImport; + token.Position = GetDirectiveLoc(context); + token.flags = 0; + token.Content = autoImportName; - inputStream->lexedTokens.mTokens.Add(token); + inputStream->lexedTokens.mTokens.Add(token); - token.Type = TokenType::EndOfFile; - token.flags = TokenFlag::AfterWhitespace | TokenFlag::AtStartOfLine; - inputStream->lexedTokens.mTokens.Add(token); + token.Type = TokenType::EndOfFile; + token.flags = TokenFlag::AfterWhitespace | TokenFlag::AtStartOfLine; + inputStream->lexedTokens.mTokens.Add(token); - inputStream->tokenReader = TokenReader(inputStream->lexedTokens); + inputStream->tokenReader = TokenReader(inputStream->lexedTokens); - inputStream->parent = context->preprocessor->inputStream; - context->preprocessor->inputStream = inputStream; - } + inputStream->parent = context->preprocessor->inputStream; + context->preprocessor->inputStream = inputStream; +} + + + +// Handle a `#include` directive +static void HandleIncludeDirective(PreprocessorDirectiveContext* context) +{ + Token pathToken; + if(!Expect(context, TokenType::StringLiterial, Diagnostics::expectedTokenInPreprocessorDirective, &pathToken)) + return; + + String path = getFileNameTokenValue(pathToken); + + // TODO(tfoley): make this robust in presence of `#line` + String pathIncludedFrom = GetDirectiveLoc(context).FileName; + String foundPath; + String foundSource; + + IncludeHandler* includeHandler = context->preprocessor->includeHandler; + if (!includeHandler) + { + GetSink(context)->diagnose(pathToken.Position, Diagnostics::includeFailed, path); + GetSink(context)->diagnose(pathToken.Position, Diagnostics::noIncludeHandlerSpecified); + return; + } + auto includeResult = includeHandler->TryToFindIncludeFile(path, pathIncludedFrom, &foundPath, &foundSource); + + switch (includeResult) + { + case IncludeResult::NotFound: + case IncludeResult::Error: + GetSink(context)->diagnose(pathToken.Position, Diagnostics::includeFailed, path); + return; + + case IncludeResult::Found: break; } - } + + // Do all checking related to the end of this directive before we push a new stream, + // just to avoid complications where that check would need to deal with + // a switch of input stream + expectEndOfDirective(context); + + // Push the new file onto our stack of input streams + // TODO(tfoley): check if we have made our include stack too deep + PreprocessorInputStream* inputStream = CreateInputStreamForSource(context->preprocessor, foundSource, foundPath); + inputStream->parent = context->preprocessor->inputStream; + context->preprocessor->inputStream = inputStream; +} // Handle a `#define` directive static void HandleDefineDirective(PreprocessorDirectiveContext* context) @@ -1878,6 +1909,7 @@ static const PreprocessorDirective kDirectives[] = { "elif", &HandleElifDirective, ProcessWhenSkipping }, { "endif", &HandleEndIfDirective, ProcessWhenSkipping }, + { "import", &HandleImportDirective, 0 }, { "include", &HandleIncludeDirective, 0 }, { "define", &HandleDefineDirective, 0 }, { "undef", &HandleUndefDirective, 0 }, |
