summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-parser.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2025-08-07 08:10:02 -0700
committerGitHub <noreply@github.com>2025-08-07 15:10:02 +0000
commit7cd8130e1a3dbcca8746e0577fb8df3bf2975bf8 (patch)
tree6da2b411da34039c3d0ec0e06fadd0e13f8f4842 /source/slang/slang-parser.cpp
parent67a96920674d628f615532a302504544a45e8187 (diff)
Support `expand` on concrete tuple values. (#8106)
Closes #8061. Along with the fix, also enhanced coercion/overload resolution to filter candidates based on the target type, allowing `tests\language-feature\higher-order-functions\overloaded.slang` to pass.
Diffstat (limited to 'source/slang/slang-parser.cpp')
-rw-r--r--source/slang/slang-parser.cpp61
1 files changed, 34 insertions, 27 deletions
diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp
index 7f7c39929..7e9740b53 100644
--- a/source/slang/slang-parser.cpp
+++ b/source/slang/slang-parser.cpp
@@ -118,10 +118,6 @@ public:
bool hasSeenCompletionToken = false;
- // Track whether or not we are inside a generics that has variadic parameters.
- // If so we will enable the new `expand` and `each` keyword.
- bool isInVariadicGenerics = false;
-
TokenReader tokenReader;
DiagnosticSink* sink;
SourceLoc lastErrorLoc;
@@ -1619,9 +1615,6 @@ static void ParseGenericDeclImpl(Parser* parser, GenericDecl* decl, const TFunc&
{
parser->ReadToken(TokenType::OpLess);
parser->genericDepth++;
- bool oldIsInVariadicGenerics = parser->isInVariadicGenerics;
- SLANG_DEFER(parser->isInVariadicGenerics = oldIsInVariadicGenerics);
-
for (;;)
{
const TokenType tokenType = parser->tokenReader.peekTokenType();
@@ -1635,11 +1628,6 @@ static void ParseGenericDeclImpl(Parser* parser, GenericDecl* decl, const TFunc&
auto genericParam = ParseGenericParamDecl(parser, decl);
AddMember(decl, genericParam);
- if (as<GenericTypePackParamDecl>(genericParam))
- {
- parser->isInVariadicGenerics = true;
- }
-
// Make sure we make forward progress.
if (parser->tokenReader.getCursor() == currentCursor)
advanceToken(parser);
@@ -1869,7 +1857,6 @@ static Stmt* parseOptBody(Parser* parser)
unparsedStmt->currentScope = parser->currentScope;
unparsedStmt->outerScope = parser->outerScope;
unparsedStmt->sourceLanguage = parser->getSourceLanguage();
- unparsedStmt->isInVariadicGenerics = parser->isInVariadicGenerics;
parser->FillPosition(unparsedStmt);
List<Token>& tokens = unparsedStmt->tokens;
int braceDepth = 0;
@@ -8616,6 +8603,32 @@ static Expr* parseEachExpr(Parser* parser, SourceLoc loc)
return eachExpr;
}
+// Check if a specific contextual keyword is available and not shadowed by user-defined decls.
+static bool isKeywordAvailable(Parser* parser, const char* keyword)
+{
+ if (!parser->semanticsVisitor || !parser->currentLookupScope)
+ return true;
+ if (lookUp(
+ parser->astBuilder,
+ parser->semanticsVisitor,
+ parser->semanticsVisitor->getName(keyword),
+ parser->currentLookupScope)
+ .isValid())
+ return false;
+ return true;
+}
+
+// Advance the token reader if the next token is a keyword and the keyword is not shadowed.
+static bool advanceIfAvailableKeyword(Parser* parser, const char* keyword)
+{
+ if (parser->LookAheadToken(keyword) && isKeywordAvailable(parser, keyword))
+ {
+ parser->ReadToken();
+ return true;
+ }
+ return false;
+}
+
static Expr* parsePrefixExpr(Parser* parser)
{
auto tokenType = peekTokenType(parser);
@@ -8650,18 +8663,13 @@ static Expr* parsePrefixExpr(Parser* parser)
{
return parseSPIRVAsmExpr(parser, tokenLoc);
}
- else if (parser->isInVariadicGenerics)
+ else if (advanceIfAvailableKeyword(parser, "expand"))
{
- // If we are inside a variadic generic, we also need to recognize
- // the new `expand` and `each` keyword for dealing with variadic packs.
- if (AdvanceIf(parser, "expand"))
- {
- return parseExpandExpr(parser, tokenLoc);
- }
- else if (AdvanceIf(parser, "each"))
- {
- return parseEachExpr(parser, tokenLoc);
- }
+ return parseExpandExpr(parser, tokenLoc);
+ }
+ else if (advanceIfAvailableKeyword(parser, "each"))
+ {
+ return parseEachExpr(parser, tokenLoc);
}
return parsePostfixExpr(parser);
}
@@ -8795,7 +8803,6 @@ Stmt* parseUnparsedStmt(
SemanticsVisitor* semanticsVisitor,
TranslationUnitRequest* translationUnit,
SourceLanguage sourceLanguage,
- bool isInVariadicGenerics,
TokenSpan const& tokens,
DiagnosticSink* sink,
Scope* currentScope,
@@ -8819,7 +8826,6 @@ Stmt* parseUnparsedStmt(
parser.semanticsVisitor = semanticsVisitor;
parser.currentScope = parser.currentLookupScope = currentScope;
parser.currentModule = semanticsVisitor->getShared()->getModule()->getModuleDecl();
- parser.isInVariadicGenerics = isInVariadicGenerics;
return parser.parseBlockStatement();
}
@@ -9388,7 +9394,8 @@ static NodeBase* parseMagicTypeModifier(Parser* parser, void* /*userData*/)
{
modifier->magicNodeType = syntaxClass;
}
- // TODO: print diagnostic if the magic type name doesn't correspond to an actual ASTNodeType.
+ // TODO: print diagnostic if the magic type name doesn't correspond to an actual
+ // ASTNodeType.
parser->ReadToken(TokenType::RParent);
return modifier;