diff options
| author | Yong He <yonghe@outlook.com> | 2025-04-30 14:17:45 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-04-30 14:17:45 -0700 |
| commit | 7f1df9d0b31413e59846cc955d2a955d3f361e2a (patch) | |
| tree | 8cfcb7b6dde96f90e9581f9a904a25158a7358cb /source/slang/slang-parser.cpp | |
| parent | 678de6547bc8cac15e31de30b400e9a3b45c216f (diff) | |
Initial support for immutable lambda expressions. (#6914)
* Initial support for immutable lambda expressions.
* More diagnostics, and langauge server fix.
* Language server fix.
* Fix bug identified in review.
* Add expected result.
* Update expected result.
Diffstat (limited to 'source/slang/slang-parser.cpp')
| -rw-r--r-- | source/slang/slang-parser.cpp | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp index a8573c909..c17a086a7 100644 --- a/source/slang/slang-parser.cpp +++ b/source/slang/slang-parser.cpp @@ -7149,6 +7149,36 @@ static bool tryParseExpression(Parser* parser, Expr*& outExpr, TokenType tokenTy return false; } +static Expr* parseLambdaExpr(Parser* parser) +{ + auto lambdaExpr = parser->astBuilder->create<LambdaExpr>(); + parser->ReadToken(TokenType::LParent); + lambdaExpr->paramScopeDecl = parser->astBuilder->create<ScopeDecl>(); + parser->pushScopeAndSetParent(lambdaExpr->paramScopeDecl); + while (!AdvanceIfMatch(parser, MatchedTokenType::Parentheses)) + { + AddMember(lambdaExpr->paramScopeDecl, parser->ParseParameter()); + if (AdvanceIf(parser, TokenType::RParent)) + break; + parser->ReadToken(TokenType::Comma); + } + parser->FillPosition(lambdaExpr); + parser->ReadToken(TokenType::DoubleRightArrow); + if (parser->LookAheadToken(TokenType::LBrace)) + { + lambdaExpr->bodyStmt = parser->parseBlockStatement(); + } + else + { + auto returnStmt = parser->astBuilder->create<ReturnStmt>(); + parser->FillPosition(returnStmt); + returnStmt->expression = parser->ParseArgExpr(); + lambdaExpr->bodyStmt = returnStmt; + } + parser->PopScope(); + return lambdaExpr; +} + static Expr* parseAtomicExpr(Parser* parser) { switch (peekTokenType(parser)) @@ -7161,12 +7191,22 @@ static Expr* parseAtomicExpr(Parser* parser) // Either: // - parenthesized expression `(exp)` // - cast `(type) exp` + // - lambda expressions (paramList)=>x // // Proper disambiguation requires mixing up parsing // and semantic checking (which we should do eventually) // but for now we will follow some heuristics. case TokenType::LParent: { + // Disambiguate between a lambda expression and other cases. + auto tokenReader = parser->tokenReader; + SkipBalancedToken(&tokenReader); + auto nextTokenAfterParent = tokenReader.peekTokenType(); + if (nextTokenAfterParent == TokenType::DoubleRightArrow) + { + return parseLambdaExpr(parser); + } + Token openParen = parser->ReadToken(TokenType::LParent); // Only handles cases of `(type)`, where type is a single identifier, |
