1use rscel::{
2 Addition, AstNode, BindContext, CelContext, CelResult, CelValue, ConditionalAnd, ConditionalOr,
3 Expr, ExprList, Ident, Member, MemberPrime, Multiplication, NegList, NotList, ObjInit,
4 ObjInits, Primary, Relation, SourceRange, Unary,
5};
6
7struct RangeNode {
8 pub range: SourceRange,
9
10 pub children: Vec<Box<RangeNode>>,
11}
12
13impl RangeNode {
14 fn empty(range: SourceRange) -> Self {
15 RangeNode {
16 range,
17 children: Vec::new(),
18 }
19 }
20
21 fn with_children(range: SourceRange, children: impl Iterator<Item = Box<RangeNode>>) -> Self {
22 RangeNode {
23 range,
24 children: children.collect(),
25 }
26 }
27
28 fn range(&self) -> SourceRange {
29 self.range
30 }
31
32 fn into_children(self) -> Vec<Box<RangeNode>> {
33 self.children
34 }
35}
36
37fn main() {
38 let args: Vec<_> = std::env::args().collect();
39
40 if args.len() < 2 {
41 eprintln!("Usage: {} <prog> [bindings]", args[0]);
42 return;
43 }
44
45 let bindings: serde_json::Value = if args.len() == 3 {
46 serde_json::from_str(&args[2]).expect("Failed to parse bindings")
47 } else {
48 serde_json::from_str::<serde_json::Value>("{}").unwrap()
49 };
50
51 let prog = rscel::Program::from_source(&args[1]).expect("Failed to compile");
52 let ast = prog.details().ast().unwrap();
53
54 let dumper = AstDumper::new();
55 let tree = dumper.dump_expr_node(ast);
56
57 let mut queue = Vec::new();
58 queue.push((tree, 0));
59
60 while !queue.is_empty() {
61 let (curr_node, depth) = queue.pop().expect("wut");
62
63 let range = curr_node.range();
65
66 let start = range.start().col();
67 let end = range.end().col();
68
69 let src = &args[1][start..end];
70
71 print!("{}{} => ", " ".to_owned().repeat(depth), src);
72 match eval(src, &bindings) {
73 Ok(val) => println!("{}", val),
74 Err(err) => println!("err: {}", err),
75 }
76
77 for node in curr_node.into_children().into_iter().rev() {
78 if node.range() != range {
79 queue.push((node, depth + 1));
80 }
81 }
82 }
83}
84
85fn eval(source: &str, bindings: &serde_json::Value) -> CelResult<CelValue> {
86 let mut ctx = CelContext::new();
87
88 ctx.add_program_str("main", source)?;
89
90 let mut bind = BindContext::new();
91 bind.bind_params_from_json_obj(bindings.clone())?;
92
93 Ok(ctx.exec("main", &bind)?)
94}
95
96struct AstDumper;
97
98impl AstDumper {
99 fn new() -> Self {
100 AstDumper {}
101 }
102
103 fn dump_expr_node(&self, node: &AstNode<Expr>) -> Box<RangeNode> {
104 match node.node() {
105 Expr::Unary(nxt) => self.dump_or_node(nxt),
106 Expr::Ternary {
107 condition,
108 true_clause,
109 false_clause,
110 } => Box::new(RangeNode::with_children(
111 node.range(),
112 [
113 self.dump_or_node(condition),
114 self.dump_or_node(true_clause),
115 self.dump_expr_node(false_clause),
116 ]
117 .into_iter(),
118 )),
119 Expr::Match { .. } => todo!(),
120 }
121 }
122
123 fn dump_or_node(&self, node: &AstNode<ConditionalOr>) -> Box<RangeNode> {
124 match node.node() {
125 ConditionalOr::Unary(nxt) => self.dump_and_node(nxt),
126 ConditionalOr::Binary { lhs, rhs } => Box::new(RangeNode::with_children(
127 node.range(),
128 [self.dump_or_node(lhs), self.dump_and_node(rhs)].into_iter(),
129 )),
130 }
131 }
132
133 fn dump_and_node(&self, node: &AstNode<ConditionalAnd>) -> Box<RangeNode> {
134 match node.node() {
135 ConditionalAnd::Unary(nxt) => self.dump_relation(nxt),
136 ConditionalAnd::Binary { lhs, rhs } => Box::new(RangeNode::with_children(
137 node.range(),
138 [self.dump_and_node(lhs), self.dump_relation(rhs)].into_iter(),
139 )),
140 }
141 }
142
143 fn dump_relation(&self, node: &AstNode<Relation>) -> Box<RangeNode> {
144 match node.node() {
145 Relation::Unary(nxt) => self.dump_addition(nxt),
146 Relation::Binary { lhs, op: _op, rhs } => Box::new(RangeNode::with_children(
147 node.range(),
148 [self.dump_relation(lhs), self.dump_addition(rhs)].into_iter(),
149 )),
150 }
151 }
152
153 fn dump_addition(&self, node: &AstNode<Addition>) -> Box<RangeNode> {
154 match node.node() {
155 Addition::Unary(nxt) => self.dump_multiplication(nxt),
156 Addition::Binary { lhs, op: _op, rhs } => Box::new(RangeNode::with_children(
157 node.range(),
158 [self.dump_addition(lhs), self.dump_multiplication(rhs)].into_iter(),
159 )),
160 }
161 }
162
163 fn dump_multiplication(&self, node: &AstNode<Multiplication>) -> Box<RangeNode> {
164 match node.node() {
165 Multiplication::Unary(nxt) => self.dump_uniary(nxt),
166 Multiplication::Binary { lhs, op: _op, rhs } => Box::new(RangeNode::with_children(
167 node.range(),
168 [self.dump_multiplication(lhs), self.dump_uniary(rhs)].into_iter(),
169 )),
170 }
171 }
172
173 fn dump_uniary(&self, node: &AstNode<Unary>) -> Box<RangeNode> {
174 match node.node() {
175 Unary::Member(nxt) => self.dump_member(nxt),
176 Unary::NegMember { negs, member } => {
177 self.dump_neg(negs);
178 let mem = self.dump_member(member);
179 Box::new(RangeNode::with_children(node.range(), [mem].into_iter()))
180 }
181 Unary::NotMember { nots, member } => {
182 self.dump_not(nots);
183 let mem = self.dump_member(member);
184 Box::new(RangeNode::with_children(node.range(), [mem].into_iter()))
185 }
186 }
187 }
188
189 fn dump_neg(&self, node: &AstNode<NegList>) {
190 match node.node() {
191 NegList::List { tail } => self.dump_neg(tail),
192 NegList::EmptyList => {}
193 }
194 }
195
196 fn dump_not(&self, node: &AstNode<NotList>) {
197 match node.node() {
198 NotList::List { tail } => self.dump_not(tail),
199 NotList::EmptyList => {}
200 }
201 }
202
203 fn dump_member(&self, node: &AstNode<Member>) -> Box<RangeNode> {
204 let mut children = vec![self.dump_primary(&node.node().primary)];
205 for member in node.node().member.iter() {
206 children.push(self.dump_member_prime(member));
207 }
208
209 Box::new(RangeNode::with_children(node.range(), children.into_iter()))
210 }
211
212 fn dump_primary(&self, node: &AstNode<Primary>) -> Box<RangeNode> {
213 match node.node() {
214 Primary::Type => Box::new(RangeNode::empty(node.range())),
215 Primary::Ident(_) => Box::new(RangeNode::empty(node.range())),
216 Primary::Parens(expr) => Box::new(RangeNode::with_children(
217 node.range(),
218 [self.dump_expr_node(expr)].into_iter(),
219 )),
220 Primary::ListConstruction(exprs) => self.dump_expr_list(exprs),
221 Primary::ObjectInit(objinits) => self.dump_obj_inits(objinits),
222 Primary::Literal(_) => Box::new(RangeNode::empty(node.range())),
223 }
224 }
225
226 fn dump_member_prime(&self, node: &AstNode<MemberPrime>) -> Box<RangeNode> {
227 match node.node() {
228 MemberPrime::MemberAccess { ident } => self.dump_ident(&ident),
229 MemberPrime::Call { call } => self.dump_expr_list(call),
230 MemberPrime::ArrayAccess { access } => self.dump_expr_node(access),
231 MemberPrime::Empty => Box::new(RangeNode::empty(node.range())),
232 }
233 }
234
235 fn dump_ident(&self, node: &AstNode<Ident>) -> Box<RangeNode> {
236 Box::new(RangeNode::empty(node.range()))
237 }
238
239 fn dump_expr_list(&self, node: &AstNode<ExprList>) -> Box<RangeNode> {
240 Box::new(RangeNode::with_children(
241 node.range(),
242 node.node()
243 .exprs
244 .clone()
245 .into_iter()
246 .map(|x| self.dump_expr_node(&x)),
247 ))
248 }
249
250 fn dump_obj_inits(&self, node: &AstNode<ObjInits>) -> Box<RangeNode> {
251 Box::new(RangeNode::with_children(
252 node.range(),
253 node.node()
254 .inits
255 .clone()
256 .into_iter()
257 .map(|x| self.dump_obj_init(&x)),
258 ))
259 }
260
261 fn dump_obj_init(&self, node: &AstNode<ObjInit>) -> Box<RangeNode> {
262 self.dump_expr_node(&node.node().key);
263 self.dump_expr_node(&node.node().value);
264 Box::new(RangeNode::empty(node.range()))
265 }
266}