Skip to content

Commit c198eab

Browse files
author
Yong He
committed
Allow generics to close with >>
1 parent 314795b commit c198eab

File tree

5 files changed

+91
-32
lines changed

5 files changed

+91
-32
lines changed

source/slang/lexer.cpp

+12-21
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
namespace Slang
1414
{
15-
static Token GetEndOfFileToken()
15+
Token TokenReader::GetEndOfFileToken()
1616
{
1717
return Token(TokenType::EndOfFile, UnownedStringSlice::fromLiteral(""), SourceLoc());
1818
}
@@ -41,43 +41,34 @@ namespace Slang
4141
{}
4242

4343

44-
Token TokenReader::PeekToken() const
44+
Token& TokenReader::PeekToken()
4545
{
46-
if (!mCursor)
47-
return GetEndOfFileToken();
48-
49-
Token token = *mCursor;
50-
if (mCursor == mEnd)
51-
token.type = TokenType::EndOfFile;
52-
return token;
46+
return nextToken;
5347
}
5448

5549
TokenType TokenReader::PeekTokenType() const
5650
{
57-
if (mCursor == mEnd)
58-
return TokenType::EndOfFile;
59-
SLANG_ASSERT(mCursor);
60-
return mCursor->type;
51+
return nextToken.type;
6152
}
6253

6354
SourceLoc TokenReader::PeekLoc() const
6455
{
65-
if (!mCursor)
66-
return SourceLoc();
67-
SLANG_ASSERT(mCursor);
68-
return mCursor->loc;
56+
return nextToken.loc;
6957
}
7058

7159
Token TokenReader::AdvanceToken()
7260
{
7361
if (!mCursor)
7462
return GetEndOfFileToken();
7563

76-
Token token = *mCursor;
77-
if (mCursor == mEnd)
78-
token.type = TokenType::EndOfFile;
79-
else
64+
Token token = nextToken;
65+
if (mCursor < mEnd)
66+
{
8067
mCursor++;
68+
nextToken = *mCursor;
69+
}
70+
else
71+
nextToken.type = TokenType::EndOfFile;
8172
return token;
8273
}
8374

source/slang/lexer.h

+22-2
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,37 @@ namespace Slang
3838

3939
struct TokenReader
4040
{
41+
Token nextToken;
4142
TokenReader();
4243
explicit TokenReader(TokenSpan const& tokens)
4344
: mCursor(tokens.begin())
4445
, mEnd (tokens.end ())
46+
, nextToken(tokens.begin() ? *tokens.begin() : GetEndOfFileToken())
4547
{}
4648
explicit TokenReader(TokenList const& tokens)
4749
: mCursor(tokens.begin())
4850
, mEnd (tokens.end ())
51+
, nextToken(tokens.begin() ? *tokens.begin() : GetEndOfFileToken())
4952
{}
50-
53+
struct ParsingCursor
54+
{
55+
Token nextToken;
56+
Token* tokenReaderCursor = nullptr;
57+
};
58+
ParsingCursor getCursor()
59+
{
60+
ParsingCursor rs;
61+
rs.nextToken = nextToken;
62+
rs.tokenReaderCursor = mCursor;
63+
return rs;
64+
}
65+
void setCursor(ParsingCursor cursor)
66+
{
67+
mCursor = cursor.tokenReaderCursor;
68+
nextToken = cursor.nextToken;
69+
}
5170
bool IsAtEnd() const { return mCursor == mEnd; }
52-
Token PeekToken() const;
71+
Token& PeekToken();
5372
TokenType PeekTokenType() const;
5473
SourceLoc PeekLoc() const;
5574

@@ -59,6 +78,7 @@ namespace Slang
5978

6079
Token* mCursor;
6180
Token* mEnd;
81+
static Token GetEndOfFileToken();
6282
};
6383

6484
typedef unsigned int LexerFlags;

source/slang/parser.cpp

+12-9
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,6 @@ namespace Slang
138138
}
139139

140140
RefPtr<ModuleDecl> Parse();
141-
142141
Token ReadToken();
143142
Token ReadToken(TokenType type);
144143
Token ReadToken(const char * string);
@@ -1667,11 +1666,15 @@ namespace Slang
16671666
}
16681667
parser->genericDepth--;
16691668

1670-
// TODO: probably want to suppot `>>` and `>=` here as well,
1671-
// and split up those tokens as needed.
1672-
//
1673-
parser->ReadToken(TokenType::OpGreater);
1674-
1669+
if (parser->tokenReader.PeekToken().type == TokenType::OpRsh)
1670+
{
1671+
parser->tokenReader.PeekToken().type = TokenType::OpGreater;
1672+
parser->tokenReader.PeekToken().loc.setRaw(parser->tokenReader.PeekToken().loc.getRaw() + 1);
1673+
}
1674+
else if (parser->LookAheadToken(TokenType::OpGreater))
1675+
parser->ReadToken(TokenType::OpGreater);
1676+
else
1677+
parser->sink->diagnose(parser->tokenReader.PeekToken(), Diagnostics::tokenTypeExpected, "'>'");
16751678
return genericApp;
16761679
}
16771680

@@ -3444,7 +3447,7 @@ namespace Slang
34443447
//
34453448
// We'll solve this with backtracking for now.
34463449

3447-
Token* startPos = tokenReader.mCursor;
3450+
TokenReader::ParsingCursor startPos = tokenReader.getCursor();
34483451

34493452
// Try to parse a type (knowing that the type grammar is
34503453
// a subset of the expression grammar, and so this should
@@ -3466,13 +3469,13 @@ namespace Slang
34663469
// Reset the cursor and try to parse a declaration now.
34673470
// Note: the declaration will consume any modifiers
34683471
// that had been in place on the statement.
3469-
tokenReader.mCursor = startPos;
3472+
tokenReader.setCursor(startPos);
34703473
statement = parseVarDeclrStatement(modifiers);
34713474
return statement;
34723475
}
34733476

34743477
// Fallback: reset and parse an expression
3475-
tokenReader.mCursor = startPos;
3478+
tokenReader.setCursor(startPos);
34763479
statement = ParseExpressionStatement();
34773480
}
34783481
else if (LookAheadToken(TokenType::Semicolon))

tests/compute/generic-closer.slang

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute
2+
//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12
3+
//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute
4+
5+
//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):dxbinding(0),glbinding(0),out
6+
7+
interface IGetter
8+
{
9+
int get();
10+
}
11+
struct Gen0 : IGetter
12+
{
13+
int get() { return 1; }
14+
};
15+
struct Gen1<TGetter : IGetter> : IGetter
16+
{
17+
TGetter g;
18+
int get() { return g.get(); }
19+
};
20+
21+
RWStructuredBuffer<int> outputBuffer;
22+
void writeArray(inout float3 a[4])
23+
{
24+
a[0] = float3(1, 1, 1);
25+
a[1] = float3(1, 1, 1);
26+
a[2] = float3(1, 1, 1);
27+
a[3] = float3(1, 1, 1);
28+
}
29+
30+
[numthreads(4, 1, 1)]
31+
void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
32+
{
33+
Gen1<Gen1<Gen1<Gen0>>> g;
34+
Gen1<Gen1<Gen1<Gen1<Gen0>>>> g2;
35+
Gen1<Gen1<Gen0>> g3;
36+
37+
int a = 0;
38+
int b = 5;
39+
if (a< b && b > a)
40+
outputBuffer[dispatchThreadID.x] = (g.get() >> 1) + g2.get() + g3.get();
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2
2+
2
3+
2
4+
2

0 commit comments

Comments
 (0)