update tree

This commit is contained in:
Noah Hellman 2023-02-04 10:19:47 +01:00
parent 768699d138
commit 95bf52a31e
2 changed files with 100 additions and 50 deletions

View file

@ -459,9 +459,9 @@ impl<'s> TreeParser<'s> {
self.alignments.extend( self.alignments.extend(
self.tree self.tree
.children(row_node) .children(row_node)
.filter(|(kind, _)| matches!(kind, tree::Element::Inline)) .filter(|n| matches!(n.elem, tree::Element::Inline))
.map(|(_, sp)| { .map(|n| {
let cell = sp.of(self.src); let cell = n.span.of(self.src);
let l = cell.as_bytes()[0] == b':'; let l = cell.as_bytes()[0] == b':';
let r = cell.as_bytes()[cell.len() - 1] == b':'; let r = cell.as_bytes()[cell.len() - 1] == b':';
match (l, r) { match (l, r) {
@ -476,8 +476,8 @@ impl<'s> TreeParser<'s> {
if let Some(head_row) = last_row_node { if let Some(head_row) = last_row_node {
self.tree self.tree
.children(head_row) .children(head_row)
.filter(|(e, _sp)| { .filter(|n| {
matches!(e, tree::Element::Container(Node::Leaf(TableCell(..)))) matches!(n.elem, tree::Element::Container(Node::Leaf(TableCell(..))))
}) })
.zip( .zip(
self.alignments self.alignments
@ -485,8 +485,10 @@ impl<'s> TreeParser<'s> {
.copied() .copied()
.chain(std::iter::repeat(Alignment::Unspecified)), .chain(std::iter::repeat(Alignment::Unspecified)),
) )
.for_each(|((e, _), new_align)| { .for_each(|(n, new_align)| {
if let tree::Element::Container(Node::Leaf(TableCell(alignment))) = e { if let tree::Element::Container(Node::Leaf(TableCell(alignment))) =
n.elem
{
*alignment = new_align; *alignment = new_align;
} }
}); });

View file

@ -8,6 +8,14 @@ pub enum EventKind<C, A> {
Atom(A), Atom(A),
} }
#[derive(Debug)]
pub struct Node<'a, C, A> {
pub index: NodeIndex,
pub elem: Element<'a, C, A>,
pub span: Span,
}
#[derive(Debug)]
pub enum Element<'a, C, A> { pub enum Element<'a, C, A> {
Container(&'a mut C), Container(&'a mut C),
Atom(&'a mut A), Atom(&'a mut A),
@ -22,7 +30,7 @@ pub struct Event<C, A> {
#[derive(Clone)] #[derive(Clone)]
pub struct Tree<C: 'static, A: 'static> { pub struct Tree<C: 'static, A: 'static> {
nodes: std::rc::Rc<[Node<C, A>]>, nodes: std::rc::Rc<[InternalNode<C, A>]>,
branch: Vec<NodeIndex>, branch: Vec<NodeIndex>,
head: Option<NodeIndex>, head: Option<NodeIndex>,
} }
@ -103,11 +111,8 @@ impl<C: Clone, A: Clone> Iterator for Tree<C, A> {
}; };
Some(Event { kind, span: n.span }) Some(Event { kind, span: n.span })
} else if let Some(block_ni) = self.branch.pop() { } else if let Some(block_ni) = self.branch.pop() {
let Node { next, kind, span } = &self.nodes[block_ni.index()]; let InternalNode { next, kind, span } = &self.nodes[block_ni.index()];
let kind = match kind { let kind = EventKind::Exit(kind.container().unwrap().clone());
NodeKind::Container(c, _) => EventKind::Exit(c.clone()),
_ => panic!(),
};
self.head = *next; self.head = *next;
Some(Event { kind, span: *span }) Some(Event { kind, span: *span })
} else { } else {
@ -143,7 +148,7 @@ enum NodeKind<C, A> {
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
struct Node<C, A> { struct InternalNode<C, A> {
span: Span, span: Span,
kind: NodeKind<C, A>, kind: NodeKind<C, A>,
next: Option<NodeIndex>, next: Option<NodeIndex>,
@ -151,12 +156,38 @@ struct Node<C, A> {
#[derive(Clone)] #[derive(Clone)]
pub struct Builder<C, A> { pub struct Builder<C, A> {
nodes: Vec<Node<C, A>>, nodes: Vec<InternalNode<C, A>>,
branch: Vec<NodeIndex>, branch: Vec<NodeIndex>,
head: Option<NodeIndex>, head: Option<NodeIndex>,
depth: usize, depth: usize,
} }
impl<C, A> NodeKind<C, A> {
fn child(&self) -> Option<NodeIndex> {
if let NodeKind::Container(_, child) = self {
*child
} else {
None
}
}
fn child_mut(&mut self) -> &mut Option<NodeIndex> {
if let NodeKind::Container(_, child) = self {
child
} else {
panic!()
}
}
fn container(&self) -> Option<&C> {
if let NodeKind::Container(c, _) = self {
Some(c)
} else {
None
}
}
}
impl<'a, C, A> From<&'a mut NodeKind<C, A>> for Element<'a, C, A> { impl<'a, C, A> From<&'a mut NodeKind<C, A>> for Element<'a, C, A> {
fn from(kind: &'a mut NodeKind<C, A>) -> Self { fn from(kind: &'a mut NodeKind<C, A>) -> Self {
match kind { match kind {
@ -168,10 +199,10 @@ impl<'a, C, A> From<&'a mut NodeKind<C, A>> for Element<'a, C, A> {
} }
} }
impl<C: std::fmt::Debug, A: std::fmt::Debug> Builder<C, A> { impl<C, A> Builder<C, A> {
pub(super) fn new() -> Self { pub(super) fn new() -> Self {
Builder { Builder {
nodes: vec![Node { nodes: vec![InternalNode {
span: Span::default(), span: Span::default(),
kind: NodeKind::Root, kind: NodeKind::Root,
next: None, next: None,
@ -183,7 +214,7 @@ impl<C: std::fmt::Debug, A: std::fmt::Debug> Builder<C, A> {
} }
pub(super) fn atom(&mut self, a: A, span: Span) { pub(super) fn atom(&mut self, a: A, span: Span) {
self.add_node(Node { self.add_node(InternalNode {
span, span,
kind: NodeKind::Atom(a), kind: NodeKind::Atom(a),
next: None, next: None,
@ -191,7 +222,7 @@ impl<C: std::fmt::Debug, A: std::fmt::Debug> Builder<C, A> {
} }
pub(super) fn inline(&mut self, span: Span) { pub(super) fn inline(&mut self, span: Span) {
self.add_node(Node { self.add_node(InternalNode {
span, span,
kind: NodeKind::Inline, kind: NodeKind::Inline,
next: None, next: None,
@ -200,7 +231,7 @@ impl<C: std::fmt::Debug, A: std::fmt::Debug> Builder<C, A> {
pub(super) fn enter(&mut self, c: C, span: Span) -> NodeIndex { pub(super) fn enter(&mut self, c: C, span: Span) -> NodeIndex {
self.depth += 1; self.depth += 1;
self.add_node(Node { self.add_node(InternalNode {
span, span,
kind: NodeKind::Container(c, None), kind: NodeKind::Container(c, None),
next: None, next: None,
@ -224,14 +255,31 @@ impl<C: std::fmt::Debug, A: std::fmt::Debug> Builder<C, A> {
self.exit(); self.exit();
let exited = self.branch.pop().unwrap(); let exited = self.branch.pop().unwrap();
self.nodes.drain(exited.index()..); self.nodes.drain(exited.index()..);
let (ni, has_parent) = self.relink(exited, None); let (prev, has_parent) = self.replace(exited, None);
if has_parent { if has_parent {
self.head = Some(ni); self.head = Some(prev);
} else { } else {
self.branch.push(ni); self.branch.push(prev);
} }
} }
/// Swap the node and its children with either its parent or the node before.
pub fn swap_prev(&mut self, node: NodeIndex) {
let next = self.nodes[node.index()].next;
if let Some(n) = next {
self.replace(n, None);
}
let (prev, _) = self.replace(node, next);
self.replace(prev, Some(node));
self.nodes[node.index()].next = Some(prev);
}
/// Remove the specified node and its children.
pub fn remove(&mut self, node: NodeIndex) {
let next = self.nodes[node.index()].next;
self.replace(node, next);
}
pub(super) fn depth(&self) -> usize { pub(super) fn depth(&self) -> usize {
self.depth self.depth
} }
@ -245,21 +293,24 @@ impl<C: std::fmt::Debug, A: std::fmt::Debug> Builder<C, A> {
} }
} }
/// Retrieve all children nodes for the specified node. Order is in the order they were added. /// Retrieve all children nodes for the specified node, in the order that they were added.
pub(super) fn children( pub(super) fn children(&mut self, node: NodeIndex) -> impl Iterator<Item = Node<C, A>> {
&mut self, // XXX assumes no modifications
node: NodeIndex, let n = &self.nodes[node.index()];
) -> impl Iterator<Item = (Element<C, A>, Span)> { let range = if let Some(start) = n.kind.child() {
assert!(matches!( start.index()..n.next.map_or(self.nodes.len(), NodeIndex::index)
self.nodes[node.index()].kind, } else {
NodeKind::Container(..) 0..0
)); };
let end = self.nodes[node.index()] range
.next .clone()
.map_or(self.nodes.len(), NodeIndex::index); .map(NodeIndex::new)
self.nodes[node.index()..end] .zip(self.nodes[range].iter_mut())
.iter_mut() .map(|(index, n)| Node {
.map(|n| (Element::from(&mut n.kind), n.span)) index,
elem: Element::from(&mut n.kind),
span: n.span,
})
} }
pub(super) fn finish(self) -> Tree<C, A> { pub(super) fn finish(self) -> Tree<C, A> {
@ -272,7 +323,7 @@ impl<C: std::fmt::Debug, A: std::fmt::Debug> Builder<C, A> {
} }
} }
fn add_node(&mut self, node: Node<C, A>) -> NodeIndex { fn add_node(&mut self, node: InternalNode<C, A>) -> NodeIndex {
let ni = NodeIndex::new(self.nodes.len()); let ni = NodeIndex::new(self.nodes.len());
self.nodes.push(node); self.nodes.push(node);
if let Some(head_ni) = &mut self.head { if let Some(head_ni) = &mut self.head {
@ -301,23 +352,20 @@ impl<C: std::fmt::Debug, A: std::fmt::Debug> Builder<C, A> {
ni ni
} }
/// Remove the link from the node that points to the specified node. Return the pointer node /// Remove the link from the node that points to the specified node. Optionally replace the
/// and whether it is a container or not. /// node with another node. Return the pointer node and whether it is a container or not.
fn relink(&mut self, prev: NodeIndex, next: Option<NodeIndex>) -> (NodeIndex, bool) { fn replace(&mut self, node: NodeIndex, next: Option<NodeIndex>) -> (NodeIndex, bool) {
for (i, n) in self.nodes.iter_mut().enumerate().rev() { for (i, n) in self.nodes.iter_mut().enumerate().rev() {
let ni = NodeIndex::new(i); let ni = NodeIndex::new(i);
if n.next == Some(prev) { if n.next == Some(node) {
n.next = next; n.next = next;
return (ni, false); return (ni, false);
} else if let NodeKind::Container(kind, child) = &mut n.kind { } else if n.kind.child() == Some(node) {
if *child == Some(prev) { *n.kind.child_mut() = next;
dbg!(kind, next); return (ni, true);
*child = next;
return (ni, true);
}
} }
} }
panic!() panic!("node is never linked to")
} }
} }