@@ -83,35 +83,48 @@ bool ForStatement(out AstStatement node)
8383 AstExpression ? ofTarget = null ;
8484 AstExpression ? test = null ;
8585 AstExpression ? update = null ;
86-
87- if ( stream . CheckAndConsume ( TokenTypes . In ) )
86+
87+ // we need to check if beginNode contains `in` expression
88+ // as `a in b` is a valid single expression
89+ if ( beginNode is AstBinaryExpression b
90+ && b . Operator == TokenTypes . In
91+ && stream . CheckAndConsume ( TokenTypes . BracketEnd ) )
8892 {
8993 @in = true ;
90- if ( ! Expression ( out inTarget ) )
91- throw stream . Unexpected ( ) ;
92- stream . Expect ( TokenTypes . BracketEnd ) ;
93- }
94- else if ( stream . CheckAndConsumeContextualKeyword ( FastKeywords . of ) )
95- {
96- of = true ;
97- if ( ! Expression ( out ofTarget ) )
98- throw stream . Unexpected ( ) ;
99- stream . Expect ( TokenTypes . BracketEnd ) ;
94+ beginNode = b . Left ;
95+ inTarget = b . Right ;
10096 }
101- else if ( ExpressionSequence ( out test , TokenTypes . SemiColon , true ) )
97+ else
10298 {
103- // case of automatic semicolon insertion
104- if ( test . End . Type == TokenTypes . BracketEnd )
105- throw stream . Unexpected ( ) ;
106- if ( test . Type == FastNodeType . EmptyExpression )
107- test = null ;
108- if ( ! ExpressionSequence ( out update , TokenTypes . BracketEnd , true ) )
109- throw stream . Unexpected ( ) ;
110- if ( update . Type == FastNodeType . EmptyExpression )
111- update = null ;
112- }
113- else stream . Unexpected ( ) ;
11499
100+ if ( stream . CheckAndConsume ( TokenTypes . In ) )
101+ {
102+ @in = true ;
103+ if ( ! Expression ( out inTarget ) )
104+ throw stream . Unexpected ( ) ;
105+ stream . Expect ( TokenTypes . BracketEnd ) ;
106+ }
107+ else if ( stream . CheckAndConsumeContextualKeyword ( FastKeywords . of ) )
108+ {
109+ of = true ;
110+ if ( ! Expression ( out ofTarget ) )
111+ throw stream . Unexpected ( ) ;
112+ stream . Expect ( TokenTypes . BracketEnd ) ;
113+ }
114+ else if ( ExpressionSequence ( out test , TokenTypes . SemiColon , true ) )
115+ {
116+ // case of automatic semicolon insertion
117+ if ( test . End . Type == TokenTypes . BracketEnd )
118+ throw stream . Unexpected ( ) ;
119+ if ( test . Type == FastNodeType . EmptyExpression )
120+ test = null ;
121+ if ( ! ExpressionSequence ( out update , TokenTypes . BracketEnd , true ) )
122+ throw stream . Unexpected ( ) ;
123+ if ( update . Type == FastNodeType . EmptyExpression )
124+ update = null ;
125+ }
126+ else stream . Unexpected ( ) ;
127+ }
115128
116129 AstStatement statement ;
117130 if ( stream . CheckAndConsume ( TokenTypes . CurlyBracketStart ) )
0 commit comments