1use std::mem;
2use std::rc::Rc;
3
4#[derive(Debug)]
5pub struct ParseTree<K> {
6 pub kind: K,
7 pub span: Span,
8 pub child: Option<Rc<ParseTree<K>>>,
9 pub sibling: Option<Rc<ParseTree<K>>>,
10}
11
12#[derive(Debug)]
13pub struct Span {
14 pub lo: usize,
15 pub hi: usize,
16}
17
18pub const DUMMY_SPAN: Span = Span { lo: 0, hi: 0 };
19
20impl<K> ParseTree<K> {
23 #[cfg(test)]
24 fn build(value: K, span: Span, children: Vec<ParseTree<K>>) -> ParseTree<K> {
25 ParseTree::new(value, span, ParseTree::sibling_chain(children))
26 }
27
28 pub fn new(kind: K, span: Span, child: Option<ParseTree<K>>) -> ParseTree<K> {
29 let child = child.map(Rc::new);
30 ParseTree { kind: kind, span: span, child: child, sibling: None }
31 }
32
33 pub fn sibling_chain(mut children: Vec<ParseTree<K>>) -> Option<ParseTree<K>> {
34 let mut p = match children.pop() {
35 Some(p) => p,
36 None => { return None; }
37 };
38 while let Some(mut q) = children.pop() {
39 q.sibling = Some(Rc::new(p));
40 p = q;
41 }
42 Some(p)
43 }
44
45 pub fn add_child_front(&mut self, mut child: ParseTree<K>) {
46 assert!(child.sibling.is_none());
47 let old_child = mem::replace(&mut self.child, None);
48 child.sibling = old_child;
49 self.child = Some(Rc::new(child));
50 }
51
52 pub fn children(&self) -> ChildIterator<K> {
53 ChildIterator { next: to_ref(&self.child) }
54 }
55}
56
57fn to_ref<K>(tree: &Option<Rc<ParseTree<K>>>) -> Option<&ParseTree<K>> {
58 tree.as_ref().map(|t| &**t)
59}
60
61pub struct ChildIterator<'tree, K: 'tree> {
64 next: Option<&'tree ParseTree<K>>
65}
66
67impl<'tree, K> Iterator for ChildIterator<'tree, K> {
68 type Item = &'tree ParseTree<K>;
69
70 fn next(&mut self) -> Option<&'tree ParseTree<K>> {
71 match self.next {
72 Some(ptr) => {
73 self.next = to_ref(&ptr.sibling);
74 Some(ptr)
75 }
76 None => None,
77 }
78 }
79}
80
81impl Span {
84 pub fn new(lo: usize, hi: usize) -> Span {
85 Span { lo: lo, hi: hi }
86 }
87}
88
89#[cfg(test)]
90mod test {
91 use super::*;
92
93 macro_rules! test_tree {
94 ({ $value:expr; $($children:tt)* }) => {
95 ParseTree::build($value,
96 DUMMY_SPAN,
97 vec![$(test_tree!($children)),*])
98 }
99 }
100
101 #[test]
102 fn iterate() {
103 let tree = test_tree!({22; {44; {66;}} {88;}});
104 let kids: Vec<_> = tree.children().map(|x| x.kind).collect();
105 assert_eq!(kids, vec![44, 88]);
106 }
107}