@@ -133,8 +133,99 @@ fn translation_rules() -> Vec<yeast::Rule> {
133133 ( line_string_literal) @lit
134134 =>
135135 ( string_literal #{ lit} )
136+ ) , // ---- Lambdas / closures ----
137+ // Map a `lambda_literal` whose body is a single statement to
138+ // `lambda_expr`. Multi-statement bodies fall through to
139+ // `unsupported_node` because `lambda_expr.body` is single-valued
140+ // in the current `ast_types.yml`. Parameters from explicit-typed
141+ // closures (`{ (x: Int) -> Int in ... }`) are not yet captured.
142+ rule!(
143+ ( lambda_literal
144+ ( statements ( _) @body) )
145+ =>
146+ ( lambda_expr
147+ body: { body} )
148+ ) ,
149+ // ---- Block / statement wrapping ----
150+ // A `(statements ...)` node corresponds to a brace-delimited block.
151+ // Each child is mapped through translation; bare expression results
152+ // get wrapped in `expr_stmt`.
153+ rule!(
154+ ( statements ( _) * @stmts)
155+ =>
156+ ( block_stmt body: { ..stmts} )
157+ ) ,
158+ // ---- Guard statement ----
159+ // `guard let x = e else { ... }` — currently only handles the
160+ // let-binding form, since plain `guard cond else { ... }` is not
161+ // exercised by any existing corpus test.
162+ rule!(
163+ ( guard_statement
164+ bound_identifier: ( simple_identifier) @id
165+ condition: ( _) * @cond_children
166+ ( else)
167+ ( statements) @else_branch)
168+ =>
169+ ( guard_if_stmt
170+ condition: ( let_pattern_condition
171+ pattern: ( var_pattern identifier: ( identifier #{ id} ) )
172+ value: { * cond_children. last( ) . unwrap( ) } )
173+ else: { else_branch} )
174+ ) ,
175+ // ---- If statement ----
176+ // if-let binding (with optional else branch). The Swift parser puts
177+ // the bound name in `bound_identifier` and the source expression as
178+ // the last child of the multi-child `condition` field.
179+ rule!(
180+ ( if_statement
181+ bound_identifier: ( simple_identifier) @id
182+ condition: ( _) * @cond_children
183+ ( statements) @then
184+ ( else)
185+ ( _) @else_branch)
186+ =>
187+ ( if_stmt
188+ condition: ( let_pattern_condition
189+ pattern: ( var_pattern identifier: ( identifier #{ id} ) )
190+ value: { * cond_children. last( ) . unwrap( ) } )
191+ then: { then}
192+ else: { else_branch} )
193+ ) ,
194+ rule!(
195+ ( if_statement
196+ bound_identifier: ( simple_identifier) @id
197+ condition: ( _) * @cond_children
198+ ( statements) @then)
199+ =>
200+ ( if_stmt
201+ condition: ( let_pattern_condition
202+ pattern: ( var_pattern identifier: ( identifier #{ id} ) )
203+ value: { * cond_children. last( ) . unwrap( ) } )
204+ then: { then} )
136205 ) ,
137- // ---- Patterns ----
206+ // With explicit else branch (block or chained if).
207+ rule!(
208+ ( if_statement
209+ condition: ( _) @cond
210+ ( statements) @then
211+ ( else)
212+ ( _) @else_branch)
213+ =>
214+ ( if_stmt
215+ condition: ( expr_condition expr: { cond} )
216+ then: { then}
217+ else: { else_branch} )
218+ ) ,
219+ // Without else branch.
220+ rule!(
221+ ( if_statement
222+ condition: ( _) @cond
223+ ( statements) @then)
224+ =>
225+ ( if_stmt
226+ condition: ( expr_condition expr: { cond} )
227+ then: { then} )
228+ ) , // ---- Patterns ----
138229 // The Swift parser uses a `pattern` node with a `bound_identifier`
139230 // field for simple bindings such as `let x = ...`.
140231 rule!(
@@ -143,26 +234,45 @@ fn translation_rules() -> Vec<yeast::Rule> {
143234 ( var_pattern
144235 identifier: ( identifier #{ id} ) )
145236 ) ,
146- // ---- Variable declarations ----
147- // `let x = e` / `var x = e` (with initializer ).
237+ // Inside tuple patterns, the inner `pattern` node holds a bare
238+ // `simple_identifier` (with no `bound_identifier` field ).
148239 rule!(
149- ( property_declaration
150- name: ( _) @pat
151- value: ( _) @value)
240+ ( pattern ( simple_identifier) @id)
152241 =>
153- ( variable_declaration_stmt
154- variable_declarator: ( variable_declarator
155- pattern: { pat}
156- value: { value} ) )
242+ ( var_pattern
243+ identifier: ( identifier #{ id} ) )
157244 ) ,
158- // `var x: T` (no initializer).
245+ // Tuple destructuring pattern, e.g. `let (a, b) = pair`. The parser
246+ // emits a `pattern` node whose unnamed children are themselves
247+ // `pattern` nodes. We synthesize a `tuple` constructor since the
248+ // syntax has no name.
249+ rule!(
250+ ( pattern ( pattern) + @parts)
251+ =>
252+ ( apply_pattern
253+ constructor: ( name_expr identifier: ( identifier "tuple" ) )
254+ argument: { ..parts} )
255+ ) ,
256+ // ---- Variable declarations ----
257+ // Handles single (`let x = e`), multiple (`let x = 1, y = 2`),
258+ // and uninitialized (`var x: T`) bindings.
159259 rule!(
160260 ( property_declaration
161- name: ( _) @pat)
261+ name: ( _) * @pats
262+ value: ( _) * @vals)
162263 =>
163264 ( variable_declaration_stmt
164- variable_declarator: ( variable_declarator
165- pattern: { pat} ) )
265+ variable_declarator: { ..pats. iter( ) . enumerate( ) . map( |( i, & pat) | {
266+ match vals. get( i) . copied( ) {
267+ Some ( val) => yeast:: tree!(
268+ ( variable_declarator
269+ pattern: { pat}
270+ value: { val} ) ) ,
271+ None => yeast:: tree!(
272+ ( variable_declarator
273+ pattern: { pat} ) ) ,
274+ }
275+ } ) } )
166276 ) ,
167277 // ---- Fallbacks ----
168278 rule!(
0 commit comments