summaryrefslogtreecommitdiff
path: root/source/slang/lexer.h
diff options
context:
space:
mode:
authorTim Foley <tfoley@nvidia.com>2017-08-09 12:57:37 -0700
committerTim Foley <tfoley@nvidia.com>2017-08-10 13:05:04 -0700
commita5a436c4783fb75a0d089a6483219c06db91f593 (patch)
tree224c16ad374c5ed533a497beeb75753e7ce2d771 /source/slang/lexer.h
parent6e4830f4d74adef0a47c6503d84dc114240fafa3 (diff)
Make source location lightweight
Fixes #24 So far the code has used a representation for source locations that is heavy-weight, but typical of research or hobby compilers: a `struct` type containing a line number and a (heap-allocated) string. This is actually very convenient for debugging, but it means that any data structure that might contain a source location needs careful memory management (because of those strings) and has a tendency to bloat. The new represnetation is that a source location is just a pointer-sized integer. In the simplest mental model, you can think of this as just counting every byte of source text that is passed in, and using those to name locations. Finding the path and line number that corresponds to a location involves a lookup step, but we can arrange to store all the files in an array sorted by their start locations, and do a binary search. Finding line numbers inside a file is similarly fast (one you pay a one-time cost to build an array of starting offsets for lines). More advanced compilers like clang actually go further and create a unique range of source locations to represent a file each time it gets included, so that they can track the include stack and reproduce it in diagnostic messages. I'm not doing anything that clever here.
Diffstat (limited to 'source/slang/lexer.h')
-rw-r--r--source/slang/lexer.h30
1 files changed, 23 insertions, 7 deletions
diff --git a/source/slang/lexer.h b/source/slang/lexer.h
index 71b2e85b1..9bb4d34aa 100644
--- a/source/slang/lexer.h
+++ b/source/slang/lexer.h
@@ -47,7 +47,7 @@ namespace Slang
bool IsAtEnd() const { return mCursor == mEnd; }
Token PeekToken() const;
TokenType PeekTokenType() const;
- CodePosition PeekLoc() const;
+ SourceLoc PeekLoc() const;
Token AdvanceToken();
@@ -66,9 +66,8 @@ namespace Slang
struct Lexer
{
- Lexer(
- String const& path,
- String const& content,
+ void initialize(
+ SourceFile* sourceFile,
DiagnosticSink* sink);
~Lexer();
@@ -77,13 +76,30 @@ namespace Slang
TokenList lexAllTokens();
- String path;
- String content;
+ // Begin overriding the reported locations of tokens,
+ // based on a `#line` directives
+ void startOverridingSourceLocations(SourceLoc loc);
+
+ // Stop overriding source locations, and go back
+ // to reporting source locations in the original file
+ void stopOverridingSourceLocations();
+
+ SourceFile* sourceFile;
DiagnosticSink* sink;
char const* cursor;
+
+ char const* begin;
char const* end;
- CodePosition loc;
+
+ // The starting source location for the code as written,
+ // which cannot be overridden.
+ SourceLoc spellingStartLoc;
+
+ // The nominal starting location for the file, taking
+ // any active `#line` directive into account.
+ SourceLoc presumedStartLoc;
+
TokenFlags tokenFlags;
LexerFlags lexerFlags;
};