diff options
| author | Yong He <yonghe@outlook.com> | 2025-08-07 08:10:02 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-07 15:10:02 +0000 |
| commit | 7cd8130e1a3dbcca8746e0577fb8df3bf2975bf8 (patch) | |
| tree | 6da2b411da34039c3d0ec0e06fadd0e13f8f4842 /source/slang/slang-parser.cpp | |
| parent | 67a96920674d628f615532a302504544a45e8187 (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.cpp | 61 |
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; |
