summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorYong He <yonghe@google.com>2019-02-05 14:20:14 -0800
committerYong He <yonghe@google.com>2019-02-05 16:14:14 -0800
commitc198eaba351850fcb3d82c2f5117efc0e2e2bf1e (patch)
tree2b77d16367773207d25106c1d449565e02c6f077 /source
parent314795b5d8ff5845624f93e152face325659dd0c (diff)
Allow generics to close with >>
Diffstat (limited to 'source')
-rw-r--r--source/slang/lexer.cpp33
-rw-r--r--source/slang/lexer.h24
-rw-r--r--source/slang/parser.cpp21
3 files changed, 46 insertions, 32 deletions
diff --git a/source/slang/lexer.cpp b/source/slang/lexer.cpp
index 3d87dd7ea..b6745b15f 100644
--- a/source/slang/lexer.cpp
+++ b/source/slang/lexer.cpp
@@ -12,7 +12,7 @@
namespace Slang
{
- static Token GetEndOfFileToken()
+ Token TokenReader::GetEndOfFileToken()
{
return Token(TokenType::EndOfFile, UnownedStringSlice::fromLiteral(""), SourceLoc());
}
@@ -41,31 +41,19 @@ namespace Slang
{}
- Token TokenReader::PeekToken() const
+ Token& TokenReader::PeekToken()
{
- if (!mCursor)
- return GetEndOfFileToken();
-
- Token token = *mCursor;
- if (mCursor == mEnd)
- token.type = TokenType::EndOfFile;
- return token;
+ return nextToken;
}
TokenType TokenReader::PeekTokenType() const
{
- if (mCursor == mEnd)
- return TokenType::EndOfFile;
- SLANG_ASSERT(mCursor);
- return mCursor->type;
+ return nextToken.type;
}
SourceLoc TokenReader::PeekLoc() const
{
- if (!mCursor)
- return SourceLoc();
- SLANG_ASSERT(mCursor);
- return mCursor->loc;
+ return nextToken.loc;
}
Token TokenReader::AdvanceToken()
@@ -73,11 +61,14 @@ namespace Slang
if (!mCursor)
return GetEndOfFileToken();
- Token token = *mCursor;
- if (mCursor == mEnd)
- token.type = TokenType::EndOfFile;
- else
+ Token token = nextToken;
+ if (mCursor < mEnd)
+ {
mCursor++;
+ nextToken = *mCursor;
+ }
+ else
+ nextToken.type = TokenType::EndOfFile;
return token;
}
diff --git a/source/slang/lexer.h b/source/slang/lexer.h
index 593e07c22..8587cc904 100644
--- a/source/slang/lexer.h
+++ b/source/slang/lexer.h
@@ -38,18 +38,37 @@ namespace Slang
struct TokenReader
{
+ Token nextToken;
TokenReader();
explicit TokenReader(TokenSpan const& tokens)
: mCursor(tokens.begin())
, mEnd (tokens.end ())
+ , nextToken(tokens.begin() ? *tokens.begin() : GetEndOfFileToken())
{}
explicit TokenReader(TokenList const& tokens)
: mCursor(tokens.begin())
, mEnd (tokens.end ())
+ , nextToken(tokens.begin() ? *tokens.begin() : GetEndOfFileToken())
{}
-
+ struct ParsingCursor
+ {
+ Token nextToken;
+ Token* tokenReaderCursor = nullptr;
+ };
+ ParsingCursor getCursor()
+ {
+ ParsingCursor rs;
+ rs.nextToken = nextToken;
+ rs.tokenReaderCursor = mCursor;
+ return rs;
+ }
+ void setCursor(ParsingCursor cursor)
+ {
+ mCursor = cursor.tokenReaderCursor;
+ nextToken = cursor.nextToken;
+ }
bool IsAtEnd() const { return mCursor == mEnd; }
- Token PeekToken() const;
+ Token& PeekToken();
TokenType PeekTokenType() const;
SourceLoc PeekLoc() const;
@@ -59,6 +78,7 @@ namespace Slang
Token* mCursor;
Token* mEnd;
+ static Token GetEndOfFileToken();
};
typedef unsigned int LexerFlags;
diff --git a/source/slang/parser.cpp b/source/slang/parser.cpp
index 076111711..06c7e8a1c 100644
--- a/source/slang/parser.cpp
+++ b/source/slang/parser.cpp
@@ -138,7 +138,6 @@ namespace Slang
}
RefPtr<ModuleDecl> Parse();
-
Token ReadToken();
Token ReadToken(TokenType type);
Token ReadToken(const char * string);
@@ -1667,11 +1666,15 @@ namespace Slang
}
parser->genericDepth--;
- // TODO: probably want to suppot `>>` and `>=` here as well,
- // and split up those tokens as needed.
- //
- parser->ReadToken(TokenType::OpGreater);
-
+ if (parser->tokenReader.PeekToken().type == TokenType::OpRsh)
+ {
+ parser->tokenReader.PeekToken().type = TokenType::OpGreater;
+ parser->tokenReader.PeekToken().loc.setRaw(parser->tokenReader.PeekToken().loc.getRaw() + 1);
+ }
+ else if (parser->LookAheadToken(TokenType::OpGreater))
+ parser->ReadToken(TokenType::OpGreater);
+ else
+ parser->sink->diagnose(parser->tokenReader.PeekToken(), Diagnostics::tokenTypeExpected, "'>'");
return genericApp;
}
@@ -3444,7 +3447,7 @@ namespace Slang
//
// We'll solve this with backtracking for now.
- Token* startPos = tokenReader.mCursor;
+ TokenReader::ParsingCursor startPos = tokenReader.getCursor();
// Try to parse a type (knowing that the type grammar is
// a subset of the expression grammar, and so this should
@@ -3466,13 +3469,13 @@ namespace Slang
// Reset the cursor and try to parse a declaration now.
// Note: the declaration will consume any modifiers
// that had been in place on the statement.
- tokenReader.mCursor = startPos;
+ tokenReader.setCursor(startPos);
statement = parseVarDeclrStatement(modifiers);
return statement;
}
// Fallback: reset and parse an expression
- tokenReader.mCursor = startPos;
+ tokenReader.setCursor(startPos);
statement = ParseExpressionStatement();
}
else if (LookAheadToken(TokenType::Semicolon))