From 7f1df9d0b31413e59846cc955d2a955d3f361e2a Mon Sep 17 00:00:00 2001 From: Yong He Date: Wed, 30 Apr 2025 14:17:45 -0700 Subject: 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. --- source/slang/slang-parser.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'source/slang/slang-parser.cpp') 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(); + parser->ReadToken(TokenType::LParent); + lambdaExpr->paramScopeDecl = parser->astBuilder->create(); + 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(); + 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, -- cgit v1.2.3