@@ -20,7 +20,7 @@ extension TokenConsumer {
20
20
backtrack. eat ( handle)
21
21
22
22
// These can be parsed as expressions with try/await.
23
- if backtrack. at ( anyIn: IfOrSwitch . self) != nil {
23
+ if backtrack. at ( anyIn: SingleValueStatementExpression . self) != nil {
24
24
return true
25
25
}
26
26
// Note we currently pass `preferExpr: false` to prefer diagnosing `try then`
@@ -525,21 +525,20 @@ extension Parser {
525
525
flavor: ExprFlavor ,
526
526
pattern: PatternContext = . none
527
527
) -> RawExprSyntax {
528
- // First check to see if we have the start of a regex literal `/.../`.
529
- // tryLexRegexLiteral(/*forUnappliedOperator*/ false)
530
-
531
- // Try parse an 'if' or 'switch' as an expression. Note we do this here in
532
- // parseUnaryExpression as we don't allow postfix syntax to hang off such
533
- // expressions to avoid ambiguities such as postfix '.member', which can
534
- // currently be parsed as a static dot member for a result builder.
535
- if self . at ( . keyword( . switch) ) {
536
- return RawExprSyntax (
537
- parseSwitchExpression ( switchHandle: . constant( . keyword( . switch) ) )
538
- )
539
- } else if self . at ( . keyword( . if) ) {
540
- return RawExprSyntax (
541
- parseIfExpression ( ifHandle: . constant( . keyword( . if) ) )
542
- )
528
+ // Try parse a single value statement as an expression (e.g do/if/switch).
529
+ // Note we do this here in parseUnaryExpression as we don't allow postfix
530
+ // syntax to hang off such expressions to avoid ambiguities such as postfix
531
+ // '.member', which can currently be parsed as a static dot member for a
532
+ // result builder.
533
+ switch self . at ( anyIn: SingleValueStatementExpression . self) {
534
+ case ( . do, let handle) ? :
535
+ return RawExprSyntax ( self . parseDoExpression ( doHandle: . noRecovery( handle) ) )
536
+ case ( . if, let handle) ? :
537
+ return RawExprSyntax ( self . parseIfExpression ( ifHandle: . noRecovery( handle) ) )
538
+ case ( . switch, let handle) ? :
539
+ return RawExprSyntax ( self . parseSwitchExpression ( switchHandle: . noRecovery( handle) ) )
540
+ default :
541
+ break
543
542
}
544
543
545
544
switch self . at ( anyIn: ExpressionPrefixOperator . self) {
@@ -2045,6 +2044,33 @@ extension Parser.Lookahead {
2045
2044
}
2046
2045
}
2047
2046
2047
+ // MARK: Do-Catch Expressions
2048
+
2049
+ extension Parser {
2050
+ /// Parse a do expression.
2051
+ mutating func parseDoExpression( doHandle: RecoveryConsumptionHandle ) -> RawDoExprSyntax {
2052
+ precondition ( experimentalFeatures. contains ( . doExpressions) )
2053
+ let ( unexpectedBeforeDoKeyword, doKeyword) = self . eat ( doHandle)
2054
+ let body = self . parseCodeBlock ( introducer: doKeyword)
2055
+
2056
+ // If the next token is 'catch', this is a 'do'/'catch'.
2057
+ var elements = [ RawCatchClauseSyntax] ( )
2058
+ var loopProgress = LoopProgressCondition ( )
2059
+ while self . at ( . keyword( . catch) ) && self . hasProgressed ( & loopProgress) {
2060
+ // Parse 'catch' clauses
2061
+ elements. append ( self . parseCatchClause ( ) )
2062
+ }
2063
+
2064
+ return RawDoExprSyntax (
2065
+ unexpectedBeforeDoKeyword,
2066
+ doKeyword: doKeyword,
2067
+ body: body,
2068
+ catchClauses: RawCatchClauseListSyntax ( elements: elements, arena: self . arena) ,
2069
+ arena: self . arena
2070
+ )
2071
+ }
2072
+ }
2073
+
2048
2074
// MARK: Conditional Expressions
2049
2075
2050
2076
extension Parser {
0 commit comments