Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/mbe/src/expander/transcriber.rs')
| -rw-r--r-- | crates/mbe/src/expander/transcriber.rs | 50 |
1 files changed, 46 insertions, 4 deletions
diff --git a/crates/mbe/src/expander/transcriber.rs b/crates/mbe/src/expander/transcriber.rs index 9fccf5f424..d1bcf3dbcc 100644 --- a/crates/mbe/src/expander/transcriber.rs +++ b/crates/mbe/src/expander/transcriber.rs @@ -131,8 +131,9 @@ pub(super) fn transcribe<S: Span>( template: &MetaTemplate<S>, bindings: &Bindings<S>, marker: impl Fn(&mut S) + Copy, + new_meta_vars: bool, ) -> ExpandResult<tt::Subtree<S>> { - let mut ctx = ExpandCtx { bindings, nesting: Vec::new() }; + let mut ctx = ExpandCtx { bindings, nesting: Vec::new(), new_meta_vars }; let mut arena: Vec<tt::TokenTree<S>> = Vec::new(); expand_subtree(&mut ctx, template, None, &mut arena, marker) } @@ -152,6 +153,7 @@ struct NestingState { struct ExpandCtx<'a, S> { bindings: &'a Bindings<S>, nesting: Vec<NestingState>, + new_meta_vars: bool, } fn expand_subtree<S: Span>( @@ -232,6 +234,21 @@ fn expand_subtree<S: Span>( .into(), ); } + Op::Length { depth } => { + let length = ctx.nesting.get(ctx.nesting.len() - 1 - depth).map_or(0, |_nest| { + // FIXME: to be implemented + 0 + }); + arena.push( + tt::Leaf::Literal(tt::Literal { + text: length.to_string().into(), + // FIXME + #[allow(deprecated)] + span: S::DUMMY, + }) + .into(), + ); + } Op::Count { name, depth } => { let mut binding = match ctx.bindings.get(name.as_str()) { Ok(b) => b, @@ -269,7 +286,13 @@ fn expand_subtree<S: Span>( } } - let c = match count(ctx, binding, 0, *depth) { + let res = if ctx.new_meta_vars { + count(ctx, binding, 0, depth.unwrap_or(0)) + } else { + count_old(ctx, binding, 0, *depth) + }; + + let c = match res { Ok(c) => c, Err(e) => { // XXX: It *might* make sense to emit a dummy integer value like `0` here. @@ -518,14 +541,33 @@ fn fix_up_and_push_path_tt<S: Span>(buf: &mut Vec<tt::TokenTree<S>>, subtree: tt fn count<S>( ctx: &ExpandCtx<'_, S>, binding: &Binding<S>, + depth_curr: usize, + depth_max: usize, +) -> Result<usize, CountError> { + match binding { + Binding::Nested(bs) => { + if depth_curr == depth_max { + Ok(bs.len()) + } else { + bs.iter().map(|b| count(ctx, b, depth_curr + 1, depth_max)).sum() + } + } + Binding::Empty => Ok(0), + Binding::Fragment(_) | Binding::Missing(_) => Ok(1), + } +} + +fn count_old<S>( + ctx: &ExpandCtx<'_, S>, + binding: &Binding<S>, our_depth: usize, count_depth: Option<usize>, ) -> Result<usize, CountError> { match binding { Binding::Nested(bs) => match count_depth { - None => bs.iter().map(|b| count(ctx, b, our_depth + 1, None)).sum(), + None => bs.iter().map(|b| count_old(ctx, b, our_depth + 1, None)).sum(), Some(0) => Ok(bs.len()), - Some(d) => bs.iter().map(|b| count(ctx, b, our_depth + 1, Some(d - 1))).sum(), + Some(d) => bs.iter().map(|b| count_old(ctx, b, our_depth + 1, Some(d - 1))).sum(), }, Binding::Empty => Ok(0), Binding::Fragment(_) | Binding::Missing(_) => { |