simple_shunting/
rpnprint.rs1use crate::parser::RPNExpr;
2use lexers::MathToken;
3use std::fmt;
4
5#[derive(Debug, Clone)]
6enum AST<'a> {
7 Leaf(&'a MathToken),
8 Node(&'a MathToken, Vec<AST<'a>>),
9}
10
11impl RPNExpr {
12 fn build_ast(&self) -> AST {
13 let mut ops = Vec::new();
14 for token in &self.0 {
15 match token {
16 MathToken::Number(_) | MathToken::Variable(_) =>
17 ops.push(AST::Leaf(token)),
18 MathToken::Function(_, arity) => {
19 let children = ops.split_off(ops.len() - arity);
20 ops.push(AST::Node(token, children));
21 },
22 MathToken::BOp(_) => {
23 let children = ops.split_off(ops.len() - 2);
24 ops.push(AST::Node(token, children));
25 },
26 MathToken::UOp(_) => {
27 let children = ops.split_off(ops.len() - 1);
28 ops.push(AST::Node(token, children));
29 },
30 _ => unreachable!(),
31 }
32 }
33 ops.pop().unwrap()
34 }
35}
36
37impl fmt::Display for RPNExpr {
38 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
39 fn print_helper(root: &AST, indent: &str, out: &mut String) {
40 match root {
41 AST::Leaf(tok) => *out += &format!("\u{2500}{:?}\n", tok),
42 AST::Node(tok, children) => {
43 *out += &format!("\u{252c}{:?}\n", tok);
45 if let Some((last_node, rest)) = children.split_last() {
47 for mid_node in rest {
48 *out += &format!("{}\u{251c}", indent);
49 print_helper(mid_node, &format!("{}\u{2502}", indent), out);
50 }
51 *out += &format!("{}\u{2570}", indent);
52 print_helper(last_node, &format!("{} ", indent), out);
53 }
54 }
55 }
56 }
57 let mut output = String::new();
58 print_helper(&self.build_ast(), "", &mut output);
59 write!(f, "{}", output)
60 }
61}