jotdown/src/tree.rs

284 lines
7.5 KiB
Rust
Raw Normal View History

2022-11-12 12:45:17 -05:00
use crate::Span;
2022-11-28 14:12:49 -05:00
#[derive(Debug, Clone, PartialEq, Eq)]
2022-12-10 04:26:06 -05:00
pub enum EventKind<C, A> {
2022-11-28 14:12:49 -05:00
Enter(C),
2022-11-28 18:33:43 -05:00
Exit(C),
2022-12-10 04:26:06 -05:00
Atom(A),
2022-11-28 14:12:49 -05:00
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Event<C, A> {
pub kind: EventKind<C, A>,
pub span: Span,
}
2022-12-10 04:26:06 -05:00
#[derive(Clone)]
pub struct Tree<C, A> {
nodes: Vec<Node<C, A>>,
2022-11-28 14:19:22 -05:00
branch: Vec<NodeIndex>,
head: Option<NodeIndex>,
2022-11-12 12:45:17 -05:00
}
2022-12-10 04:26:06 -05:00
impl<C: Copy, A: Copy> Tree<C, A> {
fn new(nodes: Vec<Node<C, A>>) -> Self {
2022-12-08 11:42:54 -05:00
let head = nodes[NodeIndex::root().index()].next;
2022-11-28 14:19:22 -05:00
Self {
nodes,
branch: Vec::new(),
2022-12-08 11:42:54 -05:00
head,
2022-11-28 14:19:22 -05:00
}
2022-11-12 12:45:17 -05:00
}
2022-12-08 11:42:54 -05:00
2022-12-10 04:26:06 -05:00
pub fn atoms(&self) -> impl Iterator<Item = (A, Span)> + '_ {
2022-12-08 11:42:54 -05:00
let mut head = self.head;
std::iter::from_fn(move || {
head.take().map(|h| {
let n = &self.nodes[h.index()];
let kind = match &n.kind {
NodeKind::Root => unreachable!(),
2022-12-10 04:26:06 -05:00
NodeKind::Container(..) => panic!(),
NodeKind::Atom(a) => *a,
2022-12-08 11:42:54 -05:00
};
head = n.next;
2022-12-10 04:26:06 -05:00
(kind, n.span)
2022-12-08 11:42:54 -05:00
})
})
}
2022-11-12 12:45:17 -05:00
}
2022-12-10 04:26:06 -05:00
impl<C: Copy, A: Copy> Iterator for Tree<C, A> {
type Item = Event<C, A>;
2022-11-12 12:45:17 -05:00
fn next(&mut self) -> Option<Self::Item> {
if let Some(head) = self.head {
let n = &self.nodes[head.index()];
2022-11-28 14:12:49 -05:00
let kind = match &n.kind {
2022-12-08 11:42:54 -05:00
NodeKind::Root => unreachable!(),
2022-11-12 12:45:17 -05:00
NodeKind::Container(c, child) => {
self.branch.push(head);
self.head = *child;
2022-11-28 14:12:49 -05:00
EventKind::Enter(*c)
2022-11-12 12:45:17 -05:00
}
2022-12-10 04:26:06 -05:00
NodeKind::Atom(e) => {
2022-11-12 12:45:17 -05:00
self.head = n.next;
2022-12-10 04:26:06 -05:00
EventKind::Atom(*e)
2022-11-12 12:45:17 -05:00
}
2022-11-28 14:12:49 -05:00
};
Some(Event { kind, span: n.span })
2022-11-12 12:45:17 -05:00
} else if let Some(block_ni) = self.branch.pop() {
2022-11-28 18:33:43 -05:00
let Node { next, kind, span } = &self.nodes[block_ni.index()];
let cont = if let NodeKind::Container(c, _) = kind {
c
} else {
panic!();
};
2022-11-12 12:45:17 -05:00
self.head = *next;
2022-11-28 14:12:49 -05:00
Some(Event {
2022-11-28 18:33:43 -05:00
kind: EventKind::Exit(*cont),
2022-11-28 14:12:49 -05:00
span: *span,
})
2022-11-12 12:45:17 -05:00
} else {
None
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct NodeIndex(std::num::NonZeroUsize);
impl NodeIndex {
fn new(i: usize) -> Self {
assert_ne!(i, usize::MAX);
Self((i + 1).try_into().unwrap())
}
fn root() -> Self {
Self::new(0)
}
fn index(self) -> usize {
usize::from(self.0) - 1
}
}
#[derive(Debug, Clone)]
2022-12-10 04:26:06 -05:00
enum NodeKind<C, A> {
2022-11-12 12:45:17 -05:00
Root,
Container(C, Option<NodeIndex>),
2022-12-10 04:26:06 -05:00
Atom(A),
2022-11-12 12:45:17 -05:00
}
#[derive(Debug, Clone)]
2022-12-10 04:26:06 -05:00
struct Node<C, A> {
2022-11-12 12:45:17 -05:00
span: Span,
2022-12-10 04:26:06 -05:00
kind: NodeKind<C, A>,
2022-11-12 12:45:17 -05:00
next: Option<NodeIndex>,
}
2022-12-10 04:26:06 -05:00
#[derive(Clone)]
pub struct Builder<C, A> {
nodes: Vec<Node<C, A>>,
2022-11-12 12:45:17 -05:00
branch: Vec<NodeIndex>,
head: Option<NodeIndex>,
}
2022-12-10 04:26:06 -05:00
impl<C: Copy, A: Copy> Builder<C, A> {
2022-11-12 12:45:17 -05:00
pub(super) fn new() -> Self {
Builder {
nodes: vec![Node {
span: Span::default(),
kind: NodeKind::Root,
next: None,
}],
branch: vec![],
head: Some(NodeIndex::root()),
}
}
2022-12-10 04:26:06 -05:00
pub(super) fn atom(&mut self, a: A, span: Span) {
2022-11-12 12:45:17 -05:00
self.add_node(Node {
span,
2022-12-10 04:26:06 -05:00
kind: NodeKind::Atom(a),
2022-11-12 12:45:17 -05:00
next: None,
});
}
pub(super) fn enter(&mut self, c: C, span: Span) {
self.add_node(Node {
span,
kind: NodeKind::Container(c, None),
next: None,
});
}
pub(super) fn exit(&mut self) {
if self.head.is_some() {
self.head = None;
} else {
let last = self.branch.pop();
assert_ne!(last, None);
}
}
2022-12-10 04:26:06 -05:00
pub(super) fn finish(self) -> Tree<C, A> {
2022-11-12 12:45:17 -05:00
Tree::new(self.nodes)
}
2022-12-10 04:26:06 -05:00
fn add_node(&mut self, node: Node<C, A>) {
2022-11-12 12:45:17 -05:00
let ni = NodeIndex::new(self.nodes.len());
self.nodes.push(node);
if let Some(head_ni) = &mut self.head {
let mut head = &mut self.nodes[head_ni.index()];
match &mut head.kind {
2022-12-10 04:26:06 -05:00
NodeKind::Root | NodeKind::Atom(_) => {
2022-11-12 12:45:17 -05:00
// update next pointer of previous node
assert_eq!(head.next, None);
head.next = Some(ni);
}
NodeKind::Container(_, child) => {
self.branch.push(*head_ni);
// update child pointer of current container
assert_eq!(*child, None);
*child = Some(ni);
}
}
} else if let Some(block) = self.branch.pop() {
let mut block = &mut self.nodes[block.index()];
assert!(matches!(block.kind, NodeKind::Container(..)));
block.next = Some(ni);
} else {
panic!()
}
self.head = Some(ni);
}
}
2022-12-10 04:26:06 -05:00
impl<C: Copy + std::fmt::Debug, A: Copy + std::fmt::Debug> std::fmt::Debug for Builder<C, A> {
2022-11-12 12:45:17 -05:00
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.clone().finish().fmt(f)
}
}
2022-12-10 04:26:06 -05:00
impl<C: Copy + std::fmt::Debug, A: Copy + std::fmt::Debug> std::fmt::Debug for Tree<C, A> {
2022-11-12 12:45:17 -05:00
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
const INDENT: &str = " ";
let mut level = 0;
2022-11-28 14:19:22 -05:00
for e in self.clone() {
2022-11-12 12:45:17 -05:00
let indent = INDENT.repeat(level);
2022-11-28 14:12:49 -05:00
match e.kind {
2022-12-10 04:26:06 -05:00
EventKind::Enter(c) => {
write!(f, "{}{:?}", indent, c)?;
2022-11-12 12:45:17 -05:00
level += 1;
}
2022-12-10 04:26:06 -05:00
EventKind::Exit(..) => {
2022-11-28 14:12:49 -05:00
level -= 1;
continue;
}
2022-12-10 04:26:06 -05:00
EventKind::Atom(a) => write!(f, "{}{:?}", indent, a)?,
2022-11-12 12:45:17 -05:00
}
2022-11-28 14:12:49 -05:00
writeln!(f, " ({}:{})", e.span.start(), e.span.end())?;
2022-11-12 12:45:17 -05:00
}
Ok(())
}
}
#[cfg(test)]
mod test {
use crate::Span;
#[test]
fn fmt_linear() {
let mut tree: super::Builder<u8, u8> = super::Builder::new();
2022-12-10 04:26:06 -05:00
tree.atom(1, Span::new(0, 1));
tree.atom(2, Span::new(1, 2));
tree.atom(3, Span::new(3, 4));
2022-11-12 12:45:17 -05:00
assert_eq!(
2022-12-10 04:26:06 -05:00
format!("{:?}", tree),
2022-11-12 12:45:17 -05:00
concat!(
"1 (0:1)\n",
"2 (1:2)\n",
"3 (3:4)\n", //
)
);
}
#[test]
fn fmt_container() {
let mut tree: super::Builder<u8, u16> = super::Builder::new();
tree.enter(1, Span::new(0, 1));
2022-12-10 04:26:06 -05:00
tree.atom(11, Span::new(0, 1));
tree.atom(12, Span::new(0, 1));
2022-11-12 12:45:17 -05:00
tree.exit();
tree.enter(2, Span::new(1, 5));
tree.enter(21, Span::new(2, 5));
tree.enter(211, Span::new(3, 4));
2022-12-10 04:26:06 -05:00
tree.atom(2111, Span::new(3, 4));
2022-11-12 12:45:17 -05:00
tree.exit();
tree.exit();
tree.enter(22, Span::new(4, 5));
2022-12-10 04:26:06 -05:00
tree.atom(221, Span::new(4, 5));
2022-11-12 12:45:17 -05:00
tree.exit();
tree.exit();
tree.enter(3, Span::new(5, 6));
2022-12-10 04:26:06 -05:00
tree.atom(31, Span::new(5, 6));
2022-11-12 12:45:17 -05:00
tree.exit();
assert_eq!(
2022-12-10 04:26:06 -05:00
format!("{:?}", tree),
2022-11-12 12:45:17 -05:00
concat!(
"1 (0:1)\n",
" 11 (0:1)\n",
" 12 (0:1)\n",
"2 (1:5)\n",
" 21 (2:5)\n",
" 211 (3:4)\n",
" 2111 (3:4)\n",
" 22 (4:5)\n",
" 221 (4:5)\n",
"3 (5:6)\n",
" 31 (5:6)\n",
)
);
}
}