Skip to content

Commit 8a3bb91

Browse files
committed
unified/swift: Use tree! instead of ctx.node
Cleans up a few places where we were constructing trees piece by piece rather than using the `tree!` macro. In the process, Copilot noticed an issue that should probably be addressed: the labeled_statement rule can never fire, since there are no such nodes in the input. This is possibly a simple as making _labeled_statement (which _does_ exist) named, but I haven't attempted this. Finally, a small change to yeast makes it so that the contents of a {} interpolation can be a Rust block (previously it could only be a single expression). This avoids the need to double-wrap instances where you want to interpolate a single node produced as the final value of some block.
1 parent ded5cc2 commit 8a3bb91

3 files changed

Lines changed: 29 additions & 22 deletions

File tree

shared/yeast-macros/src/parse.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ fn parse_direct_node(tokens: &mut Tokens, ctx: &Ident) -> Result<TokenStream> {
359359
Some(TokenTree::Group(g)) if g.delimiter() == Delimiter::Brace => {
360360
let group = expect_group(tokens, Delimiter::Brace)?;
361361
let expr = group.stream();
362-
Ok(quote! { ::std::convert::Into::<usize>::into(#expr) })
362+
Ok(quote! { ::std::convert::Into::<usize>::into({ #expr }) })
363363
}
364364
Some(TokenTree::Group(g)) if g.delimiter() == Delimiter::Parenthesis => {
365365
let group = expect_group(tokens, Delimiter::Parenthesis)?;
@@ -396,7 +396,7 @@ fn parse_direct_node_inner(tokens: &mut Tokens, ctx: &Ident) -> Result<TokenStre
396396
let expr = group.stream();
397397
return Ok(quote! {
398398
{
399-
let __expr = (#expr);
399+
let __expr = { #expr };
400400
let __value = yeast::YeastDisplay::yeast_to_string(&__expr, &*#ctx.ast);
401401
let __source_range = yeast::YeastSourceRange::yeast_source_range(&__expr, &*#ctx.ast);
402402
#ctx.literal_with_source_range(#kind_str, &__value, __source_range)
@@ -448,11 +448,11 @@ fn parse_direct_node_inner(tokens: &mut Tokens, ctx: &Ident) -> Result<TokenStre
448448
inner.next(); // consume second .
449449
let expr: TokenStream = inner.collect();
450450
quote! {
451-
(#expr).into_iter().map(::std::convert::Into::<usize>::into)
451+
{ #expr }.into_iter().map(::std::convert::Into::<usize>::into)
452452
}
453453
} else {
454454
let expr = group.stream();
455-
quote! { (#expr).into_iter() }
455+
quote! { { #expr }.into_iter() }
456456
};
457457
let chained = parse_chain_suffix(tokens, ctx, base)?;
458458
stmts.push(quote! {
@@ -617,11 +617,11 @@ fn parse_direct_list(tokens: &mut Tokens, ctx: &Ident) -> Result<Vec<TokenStream
617617
inner.next(); // consume second .
618618
let expr: TokenStream = inner.collect();
619619
quote! {
620-
(#expr).into_iter().map(::std::convert::Into::<usize>::into)
620+
{ #expr }.into_iter().map(::std::convert::Into::<usize>::into)
621621
}
622622
} else {
623623
let expr = group.stream();
624-
quote! { (#expr).into_iter() }
624+
quote! { { #expr }.into_iter() }
625625
};
626626
let chained = parse_chain_suffix(tokens, ctx, base)?;
627627
items.push(quote! {
@@ -630,7 +630,7 @@ fn parse_direct_list(tokens: &mut Tokens, ctx: &Ident) -> Result<Vec<TokenStream
630630
} else {
631631
let expr = group.stream();
632632
items.push(quote! {
633-
__nodes.push(::std::convert::Into::<usize>::into(#expr));
633+
__nodes.push(::std::convert::Into::<usize>::into({ #expr }));
634634
});
635635
}
636636
continue;

shared/yeast/doc/yeast.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,21 @@ occurrences of the same `$name` within one `BuildCtx` share the same value:
265265
)
266266
```
267267

268-
`{..expr}` splices a `Vec<Id>` (or any iterable of `Id`):
268+
The contents of `{…}` are treated as a Rust block, so multi-statement
269+
expressions (with `let` bindings) work too:
270+
271+
```rust
272+
(assignment
273+
left: {tmp}
274+
right: {
275+
let lit = ctx.literal("integer", "0");
276+
tree!((binary_expr op: (operator "+") left: {tmp} right: {lit}))
277+
})
278+
```
279+
280+
`{..expr}` splices a `Vec<Id>` (or any iterable of `Id`); the contents
281+
are likewise a Rust block, so the splice can be the result of arbitrary
282+
computation:
269283

270284
```rust
271285
yeast::trees!(ctx,

unified/extractor/src/languages/swift/swift.rs

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -725,11 +725,11 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
725725
body: (block stmt: {..body}))
726726
),
727727
// Labeled statement (e.g. `outer: for ...`). Strip the trailing ':' from the label token.
728-
rule!((labeled_statement label: (statement_label) @lbl statement: @stmt) => {..{
728+
rule!((labeled_statement label: (statement_label) @lbl statement: @stmt) => {
729729
let text = ctx.ast.source_text(lbl.into());
730-
let name = ctx.literal("identifier", &text[..text.len() - 1]);
731-
vec![ctx.node("labeled_stmt", vec![("label", vec![name]), ("stmt", vec![stmt.into()])])]
732-
}}),
730+
let name = &text[..text.len() - 1];
731+
tree!((labeled_stmt label: (identifier #{name}) stmt: {stmt}))
732+
}),
733733
// ---- Collections ----
734734
// Array literal
735735
rule!((array_literal element: _* @elems) => (array_literal element: {..elems})),
@@ -739,16 +739,9 @@ fn translation_rules() -> Vec<Rule<SwiftContext>> {
739739
rule!(
740740
(dictionary_literal key: _* @keys value: _* @vals)
741741
=>
742-
(map_literal element: {..{
743-
keys.iter().zip(vals.iter()).map(|(&k, &v)| {
744-
let k_id: usize = k.into();
745-
let v_id: usize = v.into();
746-
ctx.node("key_value_pair", vec![
747-
("key", vec![k_id]),
748-
("value", vec![v_id]),
749-
])
750-
}).collect::<Vec<_>>()
751-
}})
742+
(map_literal element: {..keys.into_iter().zip(vals).map(|(k, v)|
743+
tree!((key_value_pair key: {k} value: {v}))
744+
)})
752745
),
753746
rule!((dictionary_literal element: _* @elems) => (map_literal element: {..elems})),
754747
rule!((dictionary_literal_item key: @k value: @v) => (key_value_pair key: {k} value: {v})),

0 commit comments

Comments
 (0)