1#![allow(dead_code)]
3
4use colors::*;
5use mpc_c_types::*;
6use std::slice;
7
8#[derive(Clone, Eq, PartialEq)]
10pub struct Ast
11{
12	pub raw_ast: *mut mpc_ast_t,
15	pub tag: String,
19	pub contents: String,
21	pub children: Vec<Ast>,
23	pub row: usize,
26	pub column: usize,
29	pub position: usize,
31}
32
33#[derive(Clone, Eq, PartialEq)]
36pub struct Child<'a>
37{
38	pub parent: &'a Ast,
40	pub ast: &'a Ast,
42	pub index: usize,
44}
45
46
47impl Ast
48{
49	pub fn new(ast_ptr: *mut mpc_ast_t) -> Ast
51	{
52		unsafe
53		{
54			let mut children: Vec<Ast> = Vec::new();
55
56			for node in
57				slice::from_raw_parts((*ast_ptr).children, (*ast_ptr).children_num as usize)
58			{
59				children.push(Ast::new(*node));
60			}
61
62			Ast
63			{
64				raw_ast: ast_ptr,
65				tag: dfs!(ast_ptr, tag),
66				contents: dfs!(ast_ptr, contents),
67				children: children,
68				row: dfu!(ast_ptr, state.row),
69				column: dfu!(ast_ptr, state.col),
70				position: dfu!(ast_ptr, state.pos),
71			}
72		}
73	}
74
75	pub fn by_index(&self, index: usize) -> Option<Child>
77	{
78		if index < self.children.len()
79		{
80			Some(Child
81			{
82				parent: self,
83				ast: &self.children[index],
84				index: index,
85			})
86		}
87		else { None }
88	}
89
90	pub fn by_tag(&self, tag: &str) -> Option<Child>
92	{
93		let children = self.children.clone().into_iter();
94		let index: i32 =
95			if let Some(_) =
96				children.clone().filter(|x| x.tag == tag).next()
97					{ children.count() as i32 }
98			else { -1 };
99
100		if index > -1
101		{
102			Some(Child
103			{
104				parent: self,
105				ast: &self.children[index as usize],
106				index: index as usize
107			})
108		}
109		else { None }
110	}
111
112	pub fn by_contents(&self, contents: &str) -> Option<Child>
114	{
115		let children = self.children.clone().into_iter();
116		let index: i32 =
117			if let Some(_) =
118				children.clone().filter(|x| x.contents == contents).next()
119					{ children.count() as i32 }
120			else { -1 };
121
122		if index > -1
123		{
124			Some(Child
125			{
126				parent: self,
127				ast: &self.children[index as usize],
128				index: index as usize
129			})
130		}
131		else { None }
132	}
133
134	pub fn print(&self)
136	{
137		self.print_level(0);
138	}
139
140	pub fn print_level(&self, level: usize)
142	{
143		for _ in 0..level {trace!("  ");}
144		if self.children.is_empty()
145		{
146			trace!(
147				RED self.tag
148				RESET ':'
149				GREEN self.row
150				RESET ':'
151				YELLOW self.column " "
152				RESET '\''
153				self.contents "'\n"
154			);
155		}
156		else
157		{
158			trace!(
159				MAGENTA self.tag
160				RESET "\n"
161			);
162			for child in &self.children
163			{
164				child.print_level(level+1);
165			}
166		}
167	}
168}