1use rscel::{
2 Addition, AstNode, ConditionalAnd, ConditionalOr, Expr, ExprList, Ident, Member, MemberPrime,
3 Multiplication, NegList, NotList, ObjInit, ObjInits, Primary, Relation, Unary,
4};
5
6fn main() {
7 let args: Vec<_> = std::env::args().collect();
8
9 if args.len() < 2 {
10 eprintln!("Usage: {} <prog>", args[0]);
11 return;
12 }
13
14 let prog = rscel::Program::from_source(&args[1]).expect("Failed to compile");
15 let ast = prog.details().ast().unwrap();
16
17 AstDumper::with_source(&args[1]).dump_expr_node(ast, 0);
18}
19
20struct AstDumper<'a> {
21 source: &'a str,
22}
23
24impl<'a> AstDumper<'a> {
25 fn with_source(s: &'a str) -> Self {
26 AstDumper { source: s }
27 }
28
29 fn dump_expr_node(&self, node: &AstNode<Expr>, depth: usize) {
30 self.format_output(node, depth);
31 match node.node() {
32 Expr::Unary(nxt) => self.dump_or_node(nxt, depth + 1),
33 Expr::Ternary {
34 condition,
35 true_clause,
36 false_clause,
37 } => {
38 self.dump_or_node(condition, depth + 1);
39 self.dump_or_node(true_clause, depth + 1);
40 self.dump_expr_node(false_clause, depth + 1);
41 }
42 Expr::Match { .. } => todo!(),
43 }
44 }
45
46 fn dump_or_node(&self, node: &AstNode<ConditionalOr>, depth: usize) {
47 self.format_output(node, depth);
48 match node.node() {
49 ConditionalOr::Unary(nxt) => self.dump_and_node(nxt, depth + 1),
50 ConditionalOr::Binary { lhs, rhs } => {
51 self.dump_or_node(lhs, depth + 1);
52 self.dump_and_node(rhs, depth + 1)
53 }
54 }
55 }
56
57 fn dump_and_node(&self, node: &AstNode<ConditionalAnd>, depth: usize) {
58 self.format_output(node, depth);
59 match node.node() {
60 ConditionalAnd::Unary(nxt) => self.dump_relation(nxt, depth + 1),
61 ConditionalAnd::Binary { lhs, rhs } => {
62 self.dump_and_node(lhs, depth + 1);
63 self.dump_relation(rhs, depth + 1);
64 }
65 }
66 }
67
68 fn dump_relation(&self, node: &AstNode<Relation>, depth: usize) {
69 self.format_output(node, depth);
70 match node.node() {
71 Relation::Unary(nxt) => self.dump_addition(nxt, depth + 1),
72 Relation::Binary { lhs, op: _op, rhs } => {
73 self.dump_relation(lhs, depth + 1);
74 self.dump_addition(rhs, depth + 1);
75 }
76 }
77 }
78
79 fn dump_addition(&self, node: &AstNode<Addition>, depth: usize) {
80 self.format_output(node, depth);
81 match node.node() {
82 Addition::Unary(nxt) => self.dump_multiplication(nxt, depth + 1),
83 Addition::Binary { lhs, op: _op, rhs } => {
84 self.dump_addition(lhs, depth + 1);
85 self.dump_multiplication(rhs, depth + 1);
86 }
87 }
88 }
89
90 fn dump_multiplication(&self, node: &AstNode<Multiplication>, depth: usize) {
91 self.format_output(node, depth);
92 match node.node() {
93 Multiplication::Unary(nxt) => self.dump_uniary(nxt, depth + 1),
94 Multiplication::Binary { lhs, op: _op, rhs } => {
95 self.dump_multiplication(lhs, depth + 1);
96 self.dump_uniary(rhs, depth + 1);
97 }
98 }
99 }
100
101 fn dump_uniary(&self, node: &AstNode<Unary>, depth: usize) {
102 self.format_output(node, depth);
103 match node.node() {
104 Unary::Member(nxt) => self.dump_member(nxt, depth + 1),
105 Unary::NegMember { negs, member } => {
106 self.dump_neg(negs, depth + 1);
107 self.dump_member(member, depth + 1);
108 }
109 Unary::NotMember { nots, member } => {
110 self.dump_not(nots, depth + 1);
111 self.dump_member(member, depth + 1);
112 }
113 }
114 }
115
116 fn dump_neg(&self, node: &AstNode<NegList>, depth: usize) {
117 self.format_output(node, depth);
118 match node.node() {
119 NegList::List { tail } => self.dump_neg(tail, depth + 1),
120 NegList::EmptyList => {}
121 }
122 }
123
124 fn dump_not(&self, node: &AstNode<NotList>, depth: usize) {
125 self.format_output(node, depth);
126 match node.node() {
127 NotList::List { tail } => self.dump_not(tail, depth + 1),
128 NotList::EmptyList => {}
129 }
130 }
131
132 fn dump_member(&self, node: &AstNode<Member>, depth: usize) {
133 self.format_output(node, depth);
134 self.dump_primary(&node.node().primary, depth + 1);
135 for member in node.node().member.iter() {
136 self.dump_member_prime(member, depth + 1);
137 }
138 }
139
140 fn dump_primary(&self, node: &AstNode<Primary>, depth: usize) {
141 self.format_output(node, depth);
142 match node.node() {
143 Primary::Type => {}
144 Primary::Ident(_) => {}
145 Primary::Parens(expr) => self.dump_expr_node(expr, depth + 1),
146 Primary::ListConstruction(exprs) => self.dump_expr_list(exprs, depth + 1),
147 Primary::ObjectInit(objinits) => self.dump_obj_inits(objinits, depth + 1),
148 Primary::Literal(_) => {}
149 }
150 }
151
152 fn dump_member_prime(&self, node: &AstNode<MemberPrime>, depth: usize) {
153 self.format_output(node, depth);
154 match node.node() {
155 MemberPrime::MemberAccess { ident } => {
156 self.dump_ident(&ident, depth + 1);
157 }
158 MemberPrime::Call { call } => self.dump_expr_list(call, depth + 1),
159 MemberPrime::ArrayAccess { access } => self.dump_expr_node(access, depth + 1),
160 MemberPrime::Empty => {}
161 }
162 }
163
164 fn dump_ident(&self, node: &AstNode<Ident>, depth: usize) {
165 self.format_output(node, depth);
166 }
167
168 fn dump_expr_list(&self, node: &AstNode<ExprList>, depth: usize) {
169 self.format_output(node, depth);
170 for expr in node.node().exprs.iter() {
171 self.dump_expr_node(expr, depth + 1);
172 }
173 }
174
175 fn dump_obj_inits(&self, node: &AstNode<ObjInits>, depth: usize) {
176 self.format_output(node, depth);
177 for init in node.node().inits.iter() {
178 self.dump_obj_init(init, depth + 1);
179 }
180 }
181
182 fn dump_obj_init(&self, node: &AstNode<ObjInit>, depth: usize) {
183 self.format_output(node, depth);
184 self.dump_expr_node(&node.node().key, depth + 1);
185 self.dump_expr_node(&node.node().value, depth + 1);
186 }
187
188 fn format_output<T>(&self, ast: &AstNode<T>, depth: usize) {
189 let spacing: String = std::iter::repeat(' ').take(depth).collect();
190
191 println!(
192 "{} {} -- '{}'::{},{}",
193 spacing,
194 std::any::type_name::<T>().split("::").last().unwrap(),
195 &self.source.to_string()[ast.start().col()..ast.end().col()],
196 ast.start().col(),
197 ast.end().col()
198 );
199 }
200}