Skip to content

Commit e05355a

Browse files
committed
yeast: Remove support for fresh literals
We don't use these, and have no immediate plans to do so either, so in the interest of cleaning things up, I'm getting rid of this now. We can always add them back later if necessary.
1 parent 9269141 commit e05355a

7 files changed

Lines changed: 43 additions & 206 deletions

File tree

‎shared/yeast-macros/src/lib.rs‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ pub fn query(input: TokenStream) -> TokenStream {
4040
/// ```text
4141
/// (kind "literal") - leaf with static content
4242
/// (kind #{expr}) - leaf with computed content (expr.to_string())
43-
/// (kind $fresh) - leaf with auto-generated unique name
4443
/// {expr} - embed a Rust expression, dispatched via
4544
/// the `IntoFieldIds` trait: `Id` pushes a
4645
/// single id; iterables (`Vec<Id>`,

‎shared/yeast-macros/src/parse.rs‎

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ fn parse_direct_node(
422422
}
423423

424424
/// Parse the inside of a parenthesized node: `kind fields... children...`
425-
/// or `kind "literal"` or `kind $fresh`.
425+
/// or `kind "literal"`.
426426
fn parse_direct_node_inner(
427427
tokens: &mut Tokens,
428428
ctx: &Ident,
@@ -474,14 +474,6 @@ fn parse_direct_node_inner(
474474
});
475475
}
476476

477-
// Check for (kind $fresh)
478-
if peek_is_dollar(tokens) {
479-
tokens.next();
480-
let name = expect_ident(tokens, "expected fresh variable name after $")?;
481-
let name_str = name.to_string();
482-
return Ok(quote! { #ctx.fresh(#kind_str, #name_str) });
483-
}
484-
485477
// Parse named fields
486478
let mut stmts = Vec::new();
487479
let mut field_args = Vec::new();
@@ -973,7 +965,7 @@ pub fn parse_rule_top(input: TokenStream) -> Result<TokenStream> {
973965
let #ctx_ident = __user_ctx;
974966
Ok(#guard)
975967
}),
976-
Box::new(|__ast: &mut yeast::Ast, mut __captures: yeast::captures::Captures, __fresh: &yeast::tree_builder::FreshScope, __source_range: Option<yeast::Range>, __user_ctx: &mut _, __translator: yeast::TranslatorHandle<'_, _>| {
968+
Box::new(|__ast: &mut yeast::Ast, mut __captures: yeast::captures::Captures, __source_range: Option<yeast::Range>, __user_ctx: &mut _, __translator: yeast::TranslatorHandle<'_, _>| {
977969
// Auto-translation prefix: recursively translate every
978970
// captured node before invoking the user's transform body,
979971
// except for `@@name` captures listed in `__skip` which the
@@ -985,7 +977,7 @@ pub fn parse_rule_top(input: TokenStream) -> Result<TokenStream> {
985977
__translator.auto_translate_captures(&mut __captures, __ast, __user_ctx, __skip)?;
986978
#(#raw_bindings)*
987979
#(#translated_bindings)*
988-
let mut #ctx_ident = yeast::build::BuildCtx::with_translator(__ast, &__captures, __fresh, __source_range, __user_ctx, __translator);
980+
let mut #ctx_ident = yeast::build::BuildCtx::with_translator(__ast, &__captures, __source_range, __user_ctx, __translator);
989981
let __result: Vec<yeast::Id> = { #transform_body };
990982
let __result = #ctx_ident.finish_rule(__result);
991983
Ok(__result)
@@ -1048,10 +1040,6 @@ fn peek_is_literal(tokens: &mut Tokens) -> bool {
10481040
matches!(tokens.peek(), Some(TokenTree::Literal(_)))
10491041
}
10501042

1051-
fn peek_is_dollar(tokens: &mut Tokens) -> bool {
1052-
matches!(tokens.peek(), Some(TokenTree::Punct(p)) if p.as_char() == '$')
1053-
}
1054-
10551043
fn peek_is_hash(tokens: &mut Tokens) -> bool {
10561044
matches!(tokens.peek(), Some(TokenTree::Punct(p)) if p.as_char() == '#')
10571045
}

‎shared/yeast/doc/yeast.md‎

Lines changed: 2 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,8 @@ yeast::rule!(
184184
);
185185

186186
// Standalone — explicit context
187-
let fresh = yeast::tree_builder::FreshScope::new();
188-
let mut ctx = BuildCtx::new(ast, &captures, &fresh);
187+
let mut user_ctx = ();
188+
let mut ctx = BuildCtx::new(ast, &captures, &mut user_ctx);
189189
let id = yeast::tree!(ctx,
190190
(assignment
191191
left: {ctx.capture("lhs")}
@@ -374,25 +374,6 @@ Outside a `?`, interpolating an `Option` with `#{expr}` remains a compile error.
374374
That is deliberate: it keeps the choice between "leave the field unset" and
375375
"unwrap it" explicit at every interpolation.
376376

377-
### Fresh identifiers
378-
379-
`(kind $name)` creates a leaf node with an auto-generated unique name. All
380-
occurrences of the same `$name` within one `BuildCtx` share the same value:
381-
382-
```rust
383-
(block
384-
parameters: (block_parameters
385-
(identifier $tmp) // generates e.g. "$tmp-0"
386-
)
387-
body: (block_body
388-
(assignment
389-
left: {pat}
390-
right: (identifier $tmp) // same "$tmp-0" value
391-
)
392-
)
393-
)
394-
```
395-
396377
### Embedded Rust expressions
397378

398379
`{expr}` embeds a Rust expression whose value is appended to the
@@ -479,43 +460,6 @@ Mix `@` and `@@` freely in the same rule. In a Repeating phase both
479460
markers are equivalent (auto-translation is a no-op for repeating
480461
rules).
481462

482-
## Complete example: for-loop desugaring
483-
484-
This rule rewrites Ruby's `for pat in val do body end` into
485-
`val.each { |tmp| pat = tmp; body }`:
486-
487-
```rust
488-
let for_rule = yeast::rule!(
489-
(for
490-
pattern: (_) @pat
491-
value: (in (_) @val)
492-
body: (do (_)* @body)
493-
)
494-
=>
495-
(call
496-
receiver: {val}
497-
method: (identifier "each")
498-
block: (block
499-
parameters: (block_parameters
500-
(identifier $tmp)
501-
)
502-
body: (block_body
503-
(assignment
504-
left: {pat}
505-
right: (identifier $tmp)
506-
)
507-
{..body}
508-
)
509-
)
510-
)
511-
);
512-
```
513-
514-
Captures from the query (`@pat`, `@val`, `@body`) become Rust variables
515-
automatically: single captures bind as `Id`, repeated captures (after
516-
`*` or `+`) as `Vec<Id>`, and optional captures (after `?`) as
517-
`Option<Id>`.
518-
519463
## The `rule!` macro
520464

521465
`rule!` combines a query and a transform into a single declaration.

‎shared/yeast/src/build.rs‎

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
use std::collections::{BTreeMap, BTreeSet};
22

33
use crate::captures::Captures;
4-
use crate::tree_builder::FreshScope;
54
use crate::{Ast, FieldId, Id, KindId, NodeContent, Range, TranslatorHandle};
65

76
/// Context for building new AST nodes during a transformation.
87
///
98
/// Used by the `tree!` and `trees!` macros. Holds a mutable reference to the
10-
/// AST, a reference to the captures from a query match, a `FreshScope` for
11-
/// generating unique identifiers, and a mutable reference to a user-defined
12-
/// context of type `C`.
9+
/// AST, a reference to the captures from a query match, and a mutable reference
10+
/// to a user-defined context of type `C`.
1311
///
1412
/// The user context `C` is shared across rules via the framework's driver:
1513
/// outer rules can write to it before recursive translation, and inner rules
@@ -32,7 +30,6 @@ use crate::{Ast, FieldId, Id, KindId, NodeContent, Range, TranslatorHandle};
3230
pub struct BuildCtx<'a, C: 'a = ()> {
3331
pub ast: &'a mut Ast,
3432
pub captures: &'a Captures,
35-
pub fresh: &'a FreshScope,
3633
/// Source range of the node matched by the current rule.
3734
///
3835
/// The `rule!` macro applies this range to locally-created result roots
@@ -54,16 +51,10 @@ pub struct BuildCtx<'a, C: 'a = ()> {
5451
}
5552

5653
impl<'a, C> BuildCtx<'a, C> {
57-
pub fn new(
58-
ast: &'a mut Ast,
59-
captures: &'a Captures,
60-
fresh: &'a FreshScope,
61-
user_ctx: &'a mut C,
62-
) -> Self {
54+
pub fn new(ast: &'a mut Ast, captures: &'a Captures, user_ctx: &'a mut C) -> Self {
6355
Self {
6456
ast,
6557
captures,
66-
fresh,
6758
source_range: None,
6859
user_ctx,
6960
translator: None,
@@ -75,14 +66,12 @@ impl<'a, C> BuildCtx<'a, C> {
7566
pub fn with_source_range(
7667
ast: &'a mut Ast,
7768
captures: &'a Captures,
78-
fresh: &'a FreshScope,
7969
source_range: Option<Range>,
8070
user_ctx: &'a mut C,
8171
) -> Self {
8272
Self {
8373
ast,
8474
captures,
85-
fresh,
8675
source_range,
8776
user_ctx,
8877
translator: None,
@@ -95,15 +84,13 @@ impl<'a, C> BuildCtx<'a, C> {
9584
pub fn with_translator(
9685
ast: &'a mut Ast,
9786
captures: &'a Captures,
98-
fresh: &'a FreshScope,
9987
source_range: Option<Range>,
10088
user_ctx: &'a mut C,
10189
translator: TranslatorHandle<'a, C>,
10290
) -> Self {
10391
Self {
10492
ast,
10593
captures,
106-
fresh,
10794
source_range,
10895
user_ctx,
10996
translator: Some(translator),
@@ -262,12 +249,6 @@ impl<'a, C> BuildCtx<'a, C> {
262249
let source_range = self.source_range_of(source).map(Range::empty_at_start);
263250
self.literal_with_source_range(kind, value, source_range)
264251
}
265-
266-
/// Create a leaf node with an auto-generated unique name.
267-
pub fn fresh(&mut self, kind: &'static str, name: &str) -> Id {
268-
let generated = self.fresh.resolve(name);
269-
self.create_named_token_with_range(kind, generated, None)
270-
}
271252
}
272253

273254
impl<C: Clone> BuildCtx<'_, C> {
@@ -302,7 +283,7 @@ impl<C: Clone> BuildCtx<'_, C> {
302283

303284
/// Run `f` with a temporary child [`BuildCtx`] whose `user_ctx` is
304285
/// a fresh clone of the current one, sharing everything else
305-
/// (`ast`, `captures`, `fresh`, source ranges, `translator`) by re-borrow.
286+
/// (`ast`, `captures`, source ranges, `translator`) by re-borrow.
306287
/// Nodes constructed through the child remain part of the current rule
307288
/// invocation. Any mutations `f` makes to the child's `user_ctx`
308289
/// are discarded when it returns — no restore needed, because the
@@ -334,7 +315,6 @@ impl<C: Clone> BuildCtx<'_, C> {
334315
let mut child = BuildCtx {
335316
ast: &mut *self.ast,
336317
captures: self.captures,
337-
fresh: self.fresh,
338318
source_range: self.source_range,
339319
user_ctx: &mut child_user_ctx,
340320
translator: self.translator,

0 commit comments

Comments
 (0)