move tt-iter into tt crate

This commit is contained in:
Lukas Wirth 2024-06-24 14:47:12 +02:00
parent db056b4a69
commit dc39e87b79
10 changed files with 336 additions and 323 deletions

View file

@ -12,20 +12,17 @@ mod expander;
mod parser;
mod syntax_bridge;
mod to_parser_input;
mod tt_iter;
#[cfg(test)]
mod benchmark;
use span::{Edition, Span, SyntaxContextId};
use stdx::impl_from;
use tt::iter::TtIter;
use std::fmt;
use crate::{
parser::{MetaTemplate, MetaVarKind, Op},
tt_iter::TtIter,
};
use crate::parser::{MetaTemplate, MetaVarKind, Op};
// FIXME: we probably should re-think `token_tree_to_syntax_node` interfaces
pub use ::parser::TopEntryPoint;
@ -247,6 +244,10 @@ impl DeclarativeMacro {
self.err.as_deref()
}
pub fn num_rules(&self) -> usize {
self.rules.len()
}
pub fn expand(
&self,
tt: &tt::Subtree<Span>,
@ -361,3 +362,60 @@ impl<T: Default, E> From<Result<T, E>> for ValueResult<T, E> {
result.map_or_else(Self::only_err, Self::ok)
}
}
fn expect_fragment<S: Copy + fmt::Debug>(
tt_iter: &mut TtIter<'_, S>,
entry_point: ::parser::PrefixEntryPoint,
edition: ::parser::Edition,
) -> ExpandResult<Option<tt::TokenTree<S>>> {
use ::parser;
let buffer = tt::buffer::TokenBuffer::from_tokens(tt_iter.as_slice());
let parser_input = to_parser_input::to_parser_input(&buffer);
let tree_traversal = entry_point.parse(&parser_input, edition);
let mut cursor = buffer.begin();
let mut error = false;
for step in tree_traversal.iter() {
match step {
parser::Step::Token { kind, mut n_input_tokens } => {
if kind == ::parser::SyntaxKind::LIFETIME_IDENT {
n_input_tokens = 2;
}
for _ in 0..n_input_tokens {
cursor = cursor.bump_subtree();
}
}
parser::Step::FloatSplit { .. } => {
// FIXME: We need to split the tree properly here, but mutating the token trees
// in the buffer is somewhat tricky to pull off.
cursor = cursor.bump_subtree();
}
parser::Step::Enter { .. } | parser::Step::Exit => (),
parser::Step::Error { .. } => error = true,
}
}
let err = if error || !cursor.is_root() {
Some(ExpandError::binding_error(format!("expected {entry_point:?}")))
} else {
None
};
let mut curr = buffer.begin();
let mut res = vec![];
while curr != cursor {
let Some(token) = curr.token_tree() else { break };
res.push(token.cloned());
curr = curr.bump();
}
*tt_iter = TtIter::new_iter(tt_iter.as_slice()[res.len()..].iter());
let res = match &*res {
[] | [_] => res.pop(),
[first, ..] => Some(tt::TokenTree::Subtree(tt::Subtree {
delimiter: Delimiter::invisible_spanned(first.first_span()),
token_trees: res.into_boxed_slice(),
})),
};
ExpandResult { value: res, err }
}