diff options
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, |
