1use std::fmt::{Display, Error, Formatter};
2
3use crate::common::delimit::comma_delm;
4use crate::parse::ast::{AST, Node};
5use crate::parse::lex::token::Token;
6
7fn equal_optional(this: &Option<Box<AST>>, that: &Option<Box<AST>>) -> bool {
8 if let (Some(this), Some(that)) = (this, that) {
9 this.same_value(that)
10 } else {
11 true
12 }
13}
14
15fn equal_vec(this: &[AST], other: &[AST]) -> bool {
16 if this.len() != other.len() {
17 false
18 } else {
19 for (left, right) in this.iter().zip(other) {
20 if !left.same_value(right) {
21 return false;
22 }
23 }
24 true
25 }
26}
27
28impl Display for Node {
29 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
30 let name = match &self {
31 Node::Import { .. } => String::from("import"),
32 Node::Class { .. } => String::from("class"),
33 Node::Generic { id, isa } => if let Some(isa) = isa {
34 format!("{}: {}", id.node, isa.node)
35 } else {
36 format!("{}", id.node)
37 },
38 Node::Parent { .. } => String::from("parent"),
39 Node::Reassign { .. } => String::from("reassign"),
40 Node::VariableDef { .. } => String::from("variable definition"),
41 Node::FunDef { .. } => String::from("function definition"),
42 Node::AnonFun { .. } => String::from("anonymous function"),
43 Node::Raise { .. } => String::from("raise"),
44 Node::Handle { .. } => String::from("handle"),
45 Node::With { .. } => String::from("with"),
46 Node::FunctionCall { name, args } => {
47 format!("{}({})", name.node, comma_delm(args.iter().map(|a| a.node.clone())))
48 }
49 Node::PropertyCall { instance, property } => {
50 format!("{}.{}", instance.node, property.node)
51 }
52 Node::Id { lit } => lit.clone(),
53 Node::ExpressionType { .. } => String::from("expression type"),
54 Node::TypeDef { .. } => String::from("type definition"),
55 Node::TypeAlias { .. } => String::from("type alias"),
56 Node::TypeTup { .. } => String::from("type tuple"),
57 Node::TypeUnion { .. } => String::from("type union"),
58 Node::Type { id, generics } => if generics.is_empty() {
59 format!("{}", id.node)
60 } else {
61 format!("{}[{}]", id.node, comma_delm(generics.iter().map(|e| e.node.clone())))
62 },
63 Node::TypeFun { .. } => String::from("type function"),
64 Node::Condition { .. } => String::from("condition"),
65 Node::FunArg { .. } => String::from("function argument"),
66 Node::Dict { elements } => {
67 format!("{{{}}}", comma_delm(elements.iter().map(|(from, to)| {
68 format!("{} => {}", from.node, to.node)
69 })))
70 }
71 Node::DictBuilder { .. } => String::from("dictionary builder"),
72 Node::Set { elements } => {
73 format!("{{{}}}", comma_delm(elements.iter().map(|e| e.node.clone())))
74 }
75 Node::SetBuilder { item, conditions } => {
76 format!("{{ {} | {} }}", item.node, comma_delm(conditions.iter().map(|e| e.node.clone())))
77 }
78 Node::List { elements } => {
79 format!("[{}]", comma_delm(elements.iter().map(|e| e.node.clone())))
80 }
81 Node::ListBuilder { item, conditions } => {
82 format!("[ {} | {} ]", item.node, comma_delm(conditions.iter().map(|e| e.node.clone())))
83 }
84 Node::Tuple { elements } => {
85 format!("({})", comma_delm(elements.iter().map(|e| e.node.clone())))
86 }
87 Node::Index { item, range } => format!("{}[{}]", item.node, range.node),
88 Node::Range { .. } => String::from("range"),
89 Node::Slice { .. } => String::from("slice"),
90 Node::Block { .. } => String::from("Code block"),
91 Node::Real { lit } => lit.clone(),
92 Node::Int { lit } => lit.clone(),
93 Node::ENum { num, exp } => format!("{num}E{exp}"),
94 Node::Str { lit, .. } => format!("\"{lit}\""),
95 Node::DocStr { .. } => String::from("doc string"),
96 Node::Bool { .. } => String::from("boolean"),
97 Node::Add { left, right } => format!("{} + {}", left.node, right.node),
98 Node::AddU { .. } => String::from("addition unary"),
99 Node::Sub { left, right } => format!("{} - {}", left.node, right.node),
100 Node::SubU { .. } => String::from("subtract unary"),
101 Node::Mul { left, right } => format!("{} * {}", left.node, right.node),
102 Node::Div { left, right } => format!("{} / {}", left.node, right.node),
103 Node::FDiv { left, right } => format!("{} // {}", left.node, right.node),
104 Node::Mod { left, right } => format!("{} mod {}", left.node, right.node),
105 Node::Pow { left, right } => format!("{} ^ {}", left.node, right.node),
106 Node::Sqrt { expr } => format!("sqrt {}", expr.node),
107 Node::BAnd { left, right } => format!("{} _and_ {}", left.node, right.node),
108 Node::BOr { left, right } => format!("{} _or_ {}", left.node, right.node),
109 Node::BXOr { left, right } => format!("{} _xor_ {}", left.node, right.node),
110 Node::BOneCmpl { expr } => format!("_not {}", expr.node),
111 Node::BLShift { left, right } => format!("{} << {}", left.node, right.node),
112 Node::BRShift { left, right } => format!("{} >> {}", left.node, right.node),
113 Node::Le { left, right } => format!("{} < {}", left.node, right.node),
114 Node::Ge { left, right } => format!("{} > {}", left.node, right.node),
115 Node::Leq { left, right } => format!("{} <= {}", left.node, right.node),
116 Node::Geq { left, right } => format!("{} >= {}", left.node, right.node),
117 Node::Is { left, right } => format!("{} is {}", left.node, right.node),
118 Node::IsN { left, right } => format!("{} isnt {}", left.node, right.node),
119 Node::Eq { left, right } => format!("{} = {}", left.node, right.node),
120 Node::Neq { left, right } => format!("{} != {}", left.node, right.node),
121 Node::IsA { left, right } => format!("{} isa {}", left.node, right.node),
122 Node::IsNA { left, right } => format!("{} isna {}", left.node, right.node),
123 Node::Not { expr } => format!("not {}", expr.node),
124 Node::And { left, right } => format!("{} and {}", left.node, right.node),
125 Node::Or { left, right } => format!("{} or {}", left.node, right.node),
126 Node::IfElse { el, .. } => String::from(if el.is_some() { "if" } else { "if else" }),
127 Node::Match { .. } => String::from("match"),
128 Node::Case { .. } => String::from("case"),
129 Node::For { .. } => String::from("for loop"),
130 Node::In { left, right } => format!("{} {} {}", left.node, Token::In, right.node),
131 Node::While { .. } => String::from("while loop"),
132 Node::Break => format!("{}", Token::Break),
133 Node::Continue => format!("{}", Token::Continue),
134 Node::Return { .. } | Node::ReturnEmpty => String::from("return"),
135 Node::Underscore => format!("{}", Token::Underscore),
136 Node::Undefined => format!("{}", Token::Undefined),
137 Node::Pass => format!("{}", Token::Pass),
138 Node::Question { .. } => String::from("ternary operator"),
139 Node::QuestionOp { .. } => String::from("unsafe operator")
140 };
141
142 write!(f, "{name}")
143 }
144}
145
146impl Node {
147 #[must_use]
149 pub fn map(&self, mapping: &dyn Fn(&Node) -> Node) -> Node {
150 match mapping(self) {
151 Node::Import { from, import, alias } => Node::Import {
152 from: from.map(|a| a.map(mapping)).map(Box::from),
153 import: import.iter().map(|i| i.map(mapping)).collect(),
154 alias: alias.iter().map(|a| a.map(mapping)).collect(),
155 },
156 Node::Class { ty, args, parents, body } => Node::Class {
157 ty: Box::from(ty.map(mapping)),
158 args: args.iter().map(|a| a.map(mapping)).collect(),
159 parents: parents.iter().map(|p| p.map(mapping)).collect(),
160 body: body.map(|b| Box::from(b.map(mapping))),
161 },
162 Node::Generic { id, isa } => Node::Generic {
163 id: Box::from(id.map(mapping)),
164 isa: isa.map(|isa| Box::from(isa.map(mapping))),
165 },
166 Node::Parent { ty, args } => Node::Parent {
167 ty: Box::from(ty.map(mapping)),
168 args: args.iter().map(|a| a.map(mapping)).collect(),
169 },
170 Node::Reassign { left, right, op } => Node::Reassign {
171 left: Box::from(left.map(mapping)),
172 right: Box::from(right.map(mapping)),
173 op,
174 },
175 Node::VariableDef { mutable, var, ty, expr: expression, forward } => {
176 Node::VariableDef {
177 mutable,
178 var: Box::from(var.map(mapping)),
179 ty: ty.map(|t| Box::from(t.map(mapping))),
180 expr: expression.map(|e| Box::from(e.map(mapping))),
181 forward: forward.iter().map(|f| f.map(mapping)).collect(),
182 }
183 }
184 Node::FunDef { pure, id, args: fun_args, ret: ret_ty, raises, body } => Node::FunDef {
185 pure,
186 id: Box::from(id.map(mapping)),
187 args: fun_args.iter().map(|a| a.map(mapping)).collect(),
188 ret: ret_ty.map(|r| Box::from(r.map(mapping))),
189 raises: raises.iter().map(|r| r.map(mapping)).collect(),
190 body: body.map(|b| Box::from(b.map(mapping))),
191 },
192 Node::AnonFun { args, body } => Node::AnonFun {
193 args: args.iter().map(|a| a.map(mapping)).collect(),
194 body: Box::from(body.map(mapping)),
195 },
196 Node::Raise { error } => Node::Raise { error: Box::from(error.map(mapping)) },
197 Node::Handle { expr_or_stmt, cases } => Node::Handle {
198 expr_or_stmt: Box::from(expr_or_stmt.map(mapping)),
199 cases: cases.iter().map(|c| c.map(mapping)).collect(),
200 },
201 Node::With { resource, alias, expr } => Node::With {
202 resource: Box::from(resource.map(mapping)),
203 alias: alias.map(|(resource, alias, expr)| {
204 (
205 Box::from(resource.map(mapping)),
206 alias,
207 expr.map(|expr| Box::from(expr.map(mapping))),
208 )
209 }),
210 expr: Box::from(expr.map(mapping)),
211 },
212 Node::FunctionCall { name, args } => Node::FunctionCall {
213 name: Box::from(name.map(mapping)),
214 args: args.iter().map(|a| a.map(mapping)).collect(),
215 },
216 Node::PropertyCall { instance, property } => Node::PropertyCall {
217 instance: Box::from(instance.map(mapping)),
218 property: Box::from(property.map(mapping)),
219 },
220 Node::ExpressionType { expr, mutable, ty } => Node::ExpressionType {
221 expr: Box::from(expr.map(mapping)),
222 mutable,
223 ty: ty.map(|ty| Box::from(ty.map(mapping))),
224 },
225 Node::TypeDef { ty, isa, body } => Node::TypeDef {
226 ty: Box::from(ty.map(mapping)),
227 isa: isa.map(|isa| Box::from(isa.map(mapping))),
228 body: body.map(|body| Box::from(body.map(mapping))),
229 },
230 Node::TypeAlias { ty, isa, conditions } => Node::TypeAlias {
231 ty: Box::from(ty.map(mapping)),
232 isa: Box::from(isa.map(mapping)),
233 conditions: conditions.iter().map(|c| c.map(mapping)).collect(),
234 },
235 Node::TypeTup { types } => {
236 Node::TypeTup { types: types.iter().map(|ty| ty.map(mapping)).collect() }
237 }
238 Node::TypeUnion { types } => {
239 Node::TypeUnion { types: types.iter().map(|ty| ty.map(mapping)).collect() }
240 }
241 Node::Type { id, generics } => Node::Type {
242 id: Box::from(id.map(mapping)),
243 generics: generics.iter().map(|gen| gen.map(mapping)).collect(),
244 },
245 Node::TypeFun { args, ret_ty } => Node::TypeFun {
246 args: args.iter().map(|arg| arg.map(mapping)).collect(),
247 ret_ty: Box::from(ret_ty.map(mapping)),
248 },
249 Node::Condition { cond, el } => Node::Condition {
250 cond: Box::from(cond.map(mapping)),
251 el: el.map(|el| Box::from(el.map(mapping))),
252 },
253 Node::FunArg { vararg, mutable, var, ty, default } => Node::FunArg {
254 vararg,
255 mutable,
256 var: Box::from(var.map(mapping)),
257 ty: ty.map(|ty| Box::from(ty.map(mapping))),
258 default: default.map(|d| Box::from(d.map(mapping))),
259 },
260 Node::Set { elements } => {
261 Node::Set { elements: elements.iter().map(|e| e.map(mapping)).collect() }
262 }
263 Node::SetBuilder { item, conditions } => Node::SetBuilder {
264 item: Box::from(item.map(mapping)),
265 conditions: conditions.iter().map(|cond| cond.map(mapping)).collect(),
266 },
267 Node::List { elements } => {
268 Node::List { elements: elements.iter().map(|e| e.map(mapping)).collect() }
269 }
270 Node::ListBuilder { item, conditions } => Node::ListBuilder {
271 item: Box::from(item.map(mapping)),
272 conditions: conditions.iter().map(|cond| cond.map(mapping)).collect(),
273 },
274 Node::Tuple { elements } => {
275 Node::Tuple { elements: elements.iter().map(|e| e.map(mapping)).collect() }
276 }
277 Node::Range { from, to, inclusive, step } => Node::Range {
278 from: Box::from(from.map(mapping)),
279 to: Box::from(to.map(mapping)),
280 inclusive,
281 step: step.map(|ast| Box::from(ast.map(mapping))),
282 },
283 Node::Block { statements } => Node::Block {
284 statements: statements.iter().map(|stmt| stmt.map(mapping)).collect(),
285 },
286 Node::Add { left, right } => Node::Add {
287 left: Box::from(left.map(mapping)),
288 right: Box::from(right.map(mapping)),
289 },
290 Node::AddU { expr } => Node::AddU { expr: Box::from(expr.map(mapping)) },
291 Node::Sub { left, right } => Node::Sub {
292 left: Box::from(left.map(mapping)),
293 right: Box::from(right.map(mapping)),
294 },
295 Node::SubU { expr } => Node::SubU { expr: Box::from(expr.map(mapping)) },
296 Node::Mul { left, right } => Node::Mul {
297 left: Box::from(left.map(mapping)),
298 right: Box::from(right.map(mapping)),
299 },
300 Node::Div { left, right } => Node::Div {
301 left: Box::from(left.map(mapping)),
302 right: Box::from(right.map(mapping)),
303 },
304 Node::FDiv { left, right } => Node::FDiv {
305 left: Box::from(left.map(mapping)),
306 right: Box::from(right.map(mapping)),
307 },
308 Node::Mod { left, right } => Node::Mod {
309 left: Box::from(left.map(mapping)),
310 right: Box::from(right.map(mapping)),
311 },
312 Node::Pow { left, right } => Node::Pow {
313 left: Box::from(left.map(mapping)),
314 right: Box::from(right.map(mapping)),
315 },
316 Node::Sqrt { expr } => Node::Sqrt { expr: Box::from(expr.map(mapping)) },
317 Node::BAnd { left, right } => Node::BAnd {
318 left: Box::from(left.map(mapping)),
319 right: Box::from(right.map(mapping)),
320 },
321 Node::BOr { left, right } => Node::BOr {
322 left: Box::from(left.map(mapping)),
323 right: Box::from(right.map(mapping)),
324 },
325 Node::BXOr { left, right } => Node::BXOr {
326 left: Box::from(left.map(mapping)),
327 right: Box::from(right.map(mapping)),
328 },
329 Node::BOneCmpl { expr } => Node::BOneCmpl { expr: Box::from(expr.map(mapping)) },
330 Node::BLShift { left, right } => Node::BLShift {
331 left: Box::from(left.map(mapping)),
332 right: Box::from(right.map(mapping)),
333 },
334 Node::BRShift { left, right } => Node::BRShift {
335 left: Box::from(left.map(mapping)),
336 right: Box::from(right.map(mapping)),
337 },
338 Node::Le { left, right } => Node::Le {
339 left: Box::from(left.map(mapping)),
340 right: Box::from(right.map(mapping)),
341 },
342 Node::Ge { left, right } => Node::Ge {
343 left: Box::from(left.map(mapping)),
344 right: Box::from(right.map(mapping)),
345 },
346 Node::Leq { left, right } => Node::Leq {
347 left: Box::from(left.map(mapping)),
348 right: Box::from(right.map(mapping)),
349 },
350 Node::Geq { left, right } => Node::Geq {
351 left: Box::from(left.map(mapping)),
352 right: Box::from(right.map(mapping)),
353 },
354 Node::Is { left, right } => Node::Is {
355 left: Box::from(left.map(mapping)),
356 right: Box::from(right.map(mapping)),
357 },
358 Node::IsN { left, right } => Node::IsN {
359 left: Box::from(left.map(mapping)),
360 right: Box::from(right.map(mapping)),
361 },
362 Node::Eq { left, right } => Node::Eq {
363 left: Box::from(left.map(mapping)),
364 right: Box::from(right.map(mapping)),
365 },
366 Node::Neq { left, right } => Node::Neq {
367 left: Box::from(left.map(mapping)),
368 right: Box::from(right.map(mapping)),
369 },
370 Node::IsA { left, right } => Node::IsA {
371 left: Box::from(left.map(mapping)),
372 right: Box::from(right.map(mapping)),
373 },
374 Node::IsNA { left, right } => Node::IsNA {
375 left: Box::from(left.map(mapping)),
376 right: Box::from(right.map(mapping)),
377 },
378 Node::Not { expr } => Node::Not { expr: Box::from(expr.map(mapping)) },
379 Node::And { left, right } => Node::And {
380 left: Box::from(left.map(mapping)),
381 right: Box::from(right.map(mapping)),
382 },
383 Node::Or { left, right } => Node::Or {
384 left: Box::from(left.map(mapping)),
385 right: Box::from(right.map(mapping)),
386 },
387 Node::IfElse { cond, then, el } => Node::IfElse {
388 cond: Box::from(cond.map(mapping)),
389 then: Box::from(then.map(mapping)),
390 el: el.map(|el| Box::from(el.map(mapping))),
391 },
392 Node::Match { cond, cases } => Node::Match {
393 cond: Box::from(cond.map(mapping)),
394 cases: cases.iter().map(|c| c.map(mapping)).collect(),
395 },
396 Node::Case { cond, body } => Node::Case {
397 cond: Box::from(cond.map(mapping)),
398 body: Box::from(body.map(mapping)),
399 },
400 Node::For { expr, col, body } => Node::For {
401 expr: Box::from(expr.map(mapping)),
402 col: Box::from(col.map(mapping)),
403 body: Box::from(body.map(mapping)),
404 },
405 Node::In { left, right } => Node::In {
406 left: Box::from(left.map(mapping)),
407 right: Box::from(right.map(mapping)),
408 },
409 Node::While { cond, body } => Node::While {
410 cond: Box::from(cond.map(mapping)),
411 body: Box::from(body.map(mapping)),
412 },
413 Node::Return { expr } => Node::Return { expr: Box::from(expr.map(mapping)) },
414 Node::Question { left, right } => Node::Question {
415 left: Box::from(left.map(mapping)),
416 right: Box::from(right.map(mapping)),
417 },
418 Node::QuestionOp { expr } => Node::QuestionOp { expr: Box::from(expr.map(mapping)) },
419
420 other => mapping(&other),
421 }
422 }
423
424 pub fn same_value(&self, other: &Node) -> bool {
425 match (&self, &other) {
426 (
427 Node::Import { from: lf, import: li, alias: la },
428 Node::Import { from: rf, import: ri, alias: ra },
429 ) => lf == rf && equal_vec(li, ri) && equal_vec(la, ra),
430 (
431 Node::Class { ty: lt, args: la, parents: lp, body: lb },
432 Node::Class { ty: rt, args: ra, parents: rp, body: rb },
433 ) => {
434 lt.same_value(rt)
435 && equal_vec(la, ra)
436 && equal_vec(lp, rp)
437 && equal_optional(lb, rb)
438 }
439 (Node::Generic { id: li, isa: lisa }, Node::Generic { id: ri, isa: risa }) => {
440 li.same_value(ri) && equal_optional(lisa, risa)
441 }
442 (Node::Parent { ty: l_ty, args: la }, Node::Parent { ty: r_ty, args: ra }) => {
443 l_ty.same_value(r_ty) && equal_vec(la, ra)
444 }
445 (
446 Node::Reassign { left: ll, right: lr, op: lop },
447 Node::Reassign { left: rl, right: rr, op: rop },
448 ) => ll.same_value(rl) && lr.same_value(rr) && lop == rop,
449 (
450 Node::VariableDef { mutable: lm, var: lv, ty: lt, expr: le, forward: lf },
451 Node::VariableDef { mutable: rm, var: rv, ty: rt, expr: re, forward: rf },
452 ) => {
453 lm == rm
454 && lv.same_value(rv)
455 && equal_optional(lt, rt)
456 && equal_optional(le, re)
457 && equal_vec(lf, rf)
458 }
459 (
460 Node::FunDef { pure: lpu, id: li, args: la, ret: lret, raises: lraise, body: lb },
461 Node::FunDef { pure: rpu, id: ri, args: ra, ret: rret, raises: rraise, body: rb },
462 ) => {
463 lpu == rpu
464 && li.same_value(ri)
465 && equal_vec(la, ra)
466 && equal_optional(lret, rret)
467 && equal_vec(lraise, rraise)
468 && equal_optional(lb, rb)
469 }
470 (Node::AnonFun { args: la, body: lb }, Node::AnonFun { args: ra, body: rb }) => {
471 equal_vec(la, ra) && lb.same_value(rb)
472 }
473 (Node::Raise { error: le }, Node::Raise { error: re }) => le.same_value(re),
474 (
475 Node::Handle { expr_or_stmt: les, cases: lc },
476 Node::Handle { expr_or_stmt: res, cases: rc },
477 ) => les.same_value(res) && equal_vec(lc, rc),
478 (
479 Node::With { resource: lr, alias: Some((la, lmut, lty)), expr: le },
480 Node::With { resource: rr, alias: Some((ra, rmut, rty)), expr: re },
481 ) => {
482 lr.same_value(rr)
483 && la.same_value(ra)
484 && lmut == rmut
485 && equal_optional(lty, rty)
486 && le.same_value(re)
487 }
488 (
489 Node::With { resource: lr, alias: None, expr: le },
490 Node::With { resource: rr, alias: None, expr: re },
491 ) => lr.same_value(rr) && le.same_value(re),
492 (
493 Node::FunctionCall { name: ln, args: la },
494 Node::FunctionCall { name: rn, args: ra },
495 ) => ln.same_value(rn) && equal_vec(la, ra),
496 (
497 Node::PropertyCall { instance: li, property: lp },
498 Node::PropertyCall { instance: ri, property: rp },
499 ) => li.same_value(ri) && lp.same_value(rp),
500 (Node::Id { lit: l }, Node::Id { lit: r }) => l == r,
501 (
502 Node::ExpressionType { expr: le, mutable: lm, ty: lt },
503 Node::ExpressionType { expr: re, mutable: rm, ty: rt },
504 ) => le.same_value(re) && lm == rm && equal_optional(lt, rt),
505 (
506 Node::TypeDef { ty: lt, isa: li, body: lb },
507 Node::TypeDef { ty: rt, isa: ri, body: rb },
508 ) => lt.same_value(rt) && equal_optional(li, ri) && equal_optional(lb, rb),
509 (
510 Node::TypeAlias { ty: lt, isa: li, conditions: lc },
511 Node::TypeAlias { ty: rt, isa: ri, conditions: rc },
512 ) => lt.same_value(rt) && li.same_value(ri) && equal_vec(lc, rc),
513 (Node::TypeTup { types: l }, Node::TypeTup { types: r }) => equal_vec(l, r),
514 (Node::TypeUnion { types: l }, Node::TypeUnion { types: r }) => equal_vec(l, r),
515 (Node::Type { id: li, generics: lg }, Node::Type { id: ri, generics: rg }) => {
516 li.same_value(ri) && equal_vec(lg, rg)
517 }
518 (Node::TypeFun { args: la, ret_ty: lr }, Node::TypeFun { args: ra, ret_ty: rr }) => {
519 equal_vec(la, ra) && lr.same_value(rr)
520 }
521 (Node::Condition { cond: lc, el: le }, Node::Condition { cond: rc, el: re }) => {
522 lc.same_value(rc) && equal_optional(le, re)
523 }
524 (
525 Node::FunArg { vararg: lv, mutable: lm, var: lvar, ty: lt, default: ld },
526 Node::FunArg { vararg: rv, mutable: rm, var: rvar, ty: rt, default: rd },
527 ) => {
528 lv == rv
529 && lm == rm
530 && lvar.same_value(rvar)
531 && equal_optional(lt, rt)
532 && equal_optional(ld, rd)
533 }
534 (
535 Node::SetBuilder { item: li, conditions: lc },
536 Node::SetBuilder { item: ri, conditions: rc },
537 ) => li.same_value(ri) && equal_vec(lc, rc),
538 (
539 Node::ListBuilder { item: li, conditions: lc },
540 Node::ListBuilder { item: ri, conditions: rc },
541 ) => li.same_value(ri) && equal_vec(lc, rc),
542 (Node::Set { elements: l }, Node::Set { elements: r }) => equal_vec(l, r),
543 (Node::List { elements: l }, Node::List { elements: r }) => equal_vec(l, r),
544 (Node::Tuple { elements: l }, Node::Tuple { elements: r }) => equal_vec(l, r),
545 (
546 Node::Range { from: lf, to: lt, inclusive: li, step: ls },
547 Node::Range { from: rf, to: rt, inclusive: ri, step: rs },
548 ) => lf.same_value(rf) && lt.same_value(rt) && li == ri && equal_optional(ls, rs),
549 (Node::Block { statements: l }, Node::Block { statements: r }) => equal_vec(l, r),
550 (Node::Real { lit: l }, Node::Real { lit: r }) => l == r,
551 (Node::Int { lit: l }, Node::Int { lit: r }) => l == r,
552 (Node::ENum { num: ln, exp: le }, Node::ENum { num: rn, exp: re }) => {
553 ln == rn && le == re
554 }
555 (Node::Str { lit: l, expressions: le }, Node::Str { lit: r, expressions: re }) => {
556 l == r && equal_vec(le, re)
557 }
558 (Node::DocStr { .. }, Node::DocStr { .. }) => true,
559 (Node::Bool { lit: l }, Node::Bool { lit: r }) => l == r,
560 (Node::AddU { expr: l }, Node::AddU { expr: r }) => l.same_value(r),
561 (Node::SubU { expr: l }, Node::SubU { expr: r }) => l.same_value(r),
562 (Node::Add { left: ll, right: lr }, Node::Add { left: rl, right: rr }) => {
563 ll.same_value(rl) && lr.same_value(rr)
564 }
565 (Node::Sub { left: ll, right: lr }, Node::Sub { left: rl, right: rr }) => {
566 ll.same_value(rl) && lr.same_value(rr)
567 }
568 (Node::Mul { left: ll, right: lr }, Node::Mul { left: rl, right: rr }) => {
569 ll.same_value(rl) && lr.same_value(rr)
570 }
571 (Node::Div { left: ll, right: lr }, Node::Div { left: rl, right: rr }) => {
572 ll.same_value(rl) && lr.same_value(rr)
573 }
574 (Node::BOr { left: ll, right: lr }, Node::BOr { left: rl, right: rr }) => {
575 ll.same_value(rl) && lr.same_value(rr)
576 }
577 (Node::Mod { left: ll, right: lr }, Node::Mod { left: rl, right: rr }) => {
578 ll.same_value(rl) && lr.same_value(rr)
579 }
580 (Node::Pow { left: ll, right: lr }, Node::Pow { left: rl, right: rr }) => {
581 ll.same_value(rl) && lr.same_value(rr)
582 }
583 (Node::Sqrt { expr: l }, Node::Sqrt { expr: r }) => l.same_value(r),
584 (Node::FDiv { left: ll, right: lr }, Node::FDiv { left: rl, right: rr }) => {
585 ll.same_value(rl) && lr.same_value(rr)
586 }
587 (Node::BAnd { left: ll, right: lr }, Node::BAnd { left: rl, right: rr }) => {
588 ll.same_value(rl) && lr.same_value(rr)
589 }
590 (Node::BXOr { left: ll, right: lr }, Node::BXOr { left: rl, right: rr }) => {
591 ll.same_value(rl) && lr.same_value(rr)
592 }
593 (Node::BOneCmpl { expr: l }, Node::BOneCmpl { expr: r }) => l.same_value(r),
594 (Node::BLShift { left: ll, right: lr }, Node::BLShift { left: rl, right: rr }) => {
595 ll.same_value(rl) && lr.same_value(rr)
596 }
597 (Node::BRShift { left: ll, right: lr }, Node::BRShift { left: rl, right: rr }) => {
598 ll.same_value(rl) && lr.same_value(rr)
599 }
600 (Node::Leq { left: ll, right: lr }, Node::Leq { left: rl, right: rr }) => {
601 ll.same_value(rl) && lr.same_value(rr)
602 }
603 (Node::Geq { left: ll, right: lr }, Node::Geq { left: rl, right: rr }) => {
604 ll.same_value(rl) && lr.same_value(rr)
605 }
606 (Node::IsN { left: ll, right: lr }, Node::IsN { left: rl, right: rr }) => {
607 ll.same_value(rl) && lr.same_value(rr)
608 }
609 (Node::Neq { left: ll, right: lr }, Node::Neq { left: rl, right: rr }) => {
610 ll.same_value(rl) && lr.same_value(rr)
611 }
612 (Node::IsA { left: ll, right: lr }, Node::IsA { left: rl, right: rr }) => {
613 ll.same_value(rl) && lr.same_value(rr)
614 }
615 (Node::Le { left: ll, right: lr }, Node::Le { left: rl, right: rr }) => {
616 ll.same_value(rl) && lr.same_value(rr)
617 }
618 (Node::Ge { left: ll, right: lr }, Node::Ge { left: rl, right: rr }) => {
619 ll.same_value(rl) && lr.same_value(rr)
620 }
621 (Node::Is { left: ll, right: lr }, Node::Is { left: rl, right: rr }) => {
622 ll.same_value(rl) && lr.same_value(rr)
623 }
624 (Node::Eq { left: ll, right: lr }, Node::Eq { left: rl, right: rr }) => {
625 ll.same_value(rl) && lr.same_value(rr)
626 }
627 (Node::IsNA { left: ll, right: lr }, Node::IsNA { left: rl, right: rr }) => {
628 ll.same_value(rl) && lr.same_value(rr)
629 }
630 (Node::Not { expr: l }, Node::Not { expr: r }) => l.same_value(r),
631 (Node::And { left: ll, right: lr }, Node::And { left: rl, right: rr }) => {
632 ll.same_value(rl) && lr.same_value(rr)
633 }
634 (Node::Or { left: ll, right: lr }, Node::Or { left: rl, right: rr }) => {
635 ll.same_value(rl) && lr.same_value(rr)
636 }
637 (
638 Node::IfElse { cond: lc, then: lt, el: le },
639 Node::IfElse { cond: rc, then: rt, el: re },
640 ) => lc.same_value(rc) && lt.same_value(rt) && equal_optional(le, re),
641 (Node::Match { cond: lco, cases: lc }, Node::Match { cond: rco, cases: rc }) => {
642 lco.same_value(rco) && equal_vec(lc, rc)
643 }
644 (Node::Case { cond: lc, body: lb }, Node::Case { cond: rc, body: rb }) => {
645 lc.same_value(rc) && lb.same_value(rb)
646 }
647 (
648 Node::For { expr: le, col: lc, body: lb },
649 Node::For { expr: re, col: rc, body: rb },
650 ) => le.same_value(re) && lc.same_value(rc) && lb.same_value(rb),
651 (Node::In { left: ll, right: lr }, Node::In { left: rl, right: rr }) => {
652 ll.same_value(rl) && lr.same_value(rr)
653 }
654 (Node::While { cond: lc, body: lb }, Node::While { cond: rc, body: rb }) => {
655 lc.same_value(rc) && lb.same_value(rb)
656 }
657 (Node::Return { expr: left }, Node::Return { expr: right }) => left.same_value(right),
658 (Node::Question { left: ll, right: lr }, Node::Question { left: rl, right: rr }) => {
659 ll.same_value(rl) && lr.same_value(rr)
660 }
661 (Node::QuestionOp { expr: left }, Node::QuestionOp { expr: right }) => {
662 left.same_value(right)
663 }
664
665 (left, right) if **left == **right => true,
666 _ => false,
667 }
668 }
669
670 pub fn is_expression(&self) -> bool {
675 match &self {
676 Node::AnonFun { .. }
677 | Node::PropertyCall { .. }
678 | Node::Id { .. }
679 | Node::Set { .. }
680 | Node::SetBuilder { .. }
681 | Node::List { .. }
682 | Node::ListBuilder { .. }
683 | Node::Tuple { .. }
684 | Node::Range { .. }
685 | Node::Slice { .. }
686 | Node::Index { .. }
687 | Node::Real { .. }
688 | Node::Int { .. }
689 | Node::ENum { .. }
690 | Node::Str { .. }
691 | Node::Bool { .. }
692 | Node::Match { .. }
693 | Node::Underscore
694 | Node::Undefined
695 | Node::Question { .. }
696 | Node::QuestionOp { .. } => true,
697
698 Node::IfElse { el, .. } => el.is_some(),
699
700 Node::Block { statements } => {
701 if let Some(stmt) = statements.last() {
702 stmt.node.is_expression()
703 } else {
704 false
705 }
706 }
707
708 _ => self.is_operator(),
709 }
710 }
711
712 fn is_operator(&self) -> bool {
713 matches!(
714 &self,
715 Node::Add { .. }
716 | Node::AddU { .. }
717 | Node::Sub { .. }
718 | Node::SubU { .. }
719 | Node::Mul { .. }
720 | Node::Div { .. }
721 | Node::FDiv { .. }
722 | Node::Mod { .. }
723 | Node::Pow { .. }
724 | Node::Sqrt { .. }
725 | Node::BAnd { .. }
726 | Node::BOr { .. }
727 | Node::BXOr { .. }
728 | Node::BOneCmpl { .. }
729 | Node::BLShift { .. }
730 | Node::BRShift { .. }
731 | Node::Le { .. }
732 | Node::Ge { .. }
733 | Node::Leq { .. }
734 | Node::Geq { .. }
735 | Node::Is { .. }
736 | Node::IsN { .. }
737 | Node::Eq { .. }
738 | Node::Neq { .. }
739 | Node::IsA { .. }
740 | Node::IsNA { .. }
741 | Node::Not { .. }
742 | Node::And { .. }
743 | Node::Or { .. }
744 | Node::In { .. }
745 )
746 }
747}
748
749#[cfg(test)]
750mod test {
751 use crate::common::position::{CaretPos, Position};
752 use crate::parse::ast::{AST, Node};
753 use crate::parse::ast::node_op::NodeOp;
754
755 macro_rules! map_ne {
756 ($node:expr, $new_node: expr, $old: expr, $new: expr) => {{
757 let ast = AST::new(Position::invisible(), $node);
758 let ast2 = ast.map(&|node| {
759 if let Node::Id { lit } = node {
760 if *lit == String::from($old) {
761 Node::Id { lit: String::from($new) }
762 } else {
763 node.clone()
764 }
765 } else {
766 node.clone()
767 }
768 });
769
770 assert!(!ast.same_value(&ast2));
771 assert_eq!(ast2.node, $new_node)
772 }};
773 }
774
775 macro_rules! map_eq {
776 ($node:expr, $new_node: expr, $old: expr, $new: expr) => {{
777 let ast = AST::new(Position::invisible(), $node);
778 let ast2 = ast.map(&|node| {
779 if let Node::Id { lit } = node {
780 if *lit == String::from($old) {
781 Node::Id { lit: String::from($new) }
782 } else {
783 node.clone()
784 }
785 } else {
786 node.clone()
787 }
788 });
789
790 assert!(ast.same_value(&ast2));
791 assert_eq!(ast2.node, $new_node)
792 }};
793 }
794
795 #[test]
796 fn unmappable_ast_map() {
797 let old = "noise";
798 let new = "noise_again";
799
800 map_eq!(Node::Break, Node::Break, old, new);
801 map_eq!(Node::Continue, Node::Continue, old, new);
802 map_eq!(Node::ReturnEmpty, Node::ReturnEmpty, old, new);
803 map_eq!(Node::Underscore, Node::Underscore, old, new);
804 map_eq!(Node::Undefined, Node::Undefined, old, new);
805 map_eq!(Node::Pass, Node::Pass, old, new);
806 }
807
808 #[test]
809 fn for_ast_map() {
810 let pos = Position::new(CaretPos::new(3, 403), CaretPos::new(324, 673));
811 let node = Node::For {
812 expr: Box::new(AST::new(pos, Node::Id { lit: String::from("a") })),
813 col: Box::new(AST::new(pos, Node::Id { lit: String::from("b") })),
814 body: Box::new(AST::new(pos, Node::Id { lit: String::from("c") })),
815 };
816
817 let new_node = Node::For {
818 expr: Box::new(AST::new(pos, Node::Id { lit: String::from("2012") })),
819 col: Box::new(AST::new(pos, Node::Id { lit: String::from("b") })),
820 body: Box::new(AST::new(pos, Node::Id { lit: String::from("c") })),
821 };
822
823 let old = "a";
824 let new = "2012";
825 map_ne!(node, new_node, old, new);
826 }
827
828 macro_rules! two_ast_ne {
829 ($left:expr, $right: expr) => {{
830 let pos = Position::new(CaretPos::new(3, 403), CaretPos::new(324, 673));
831 let pos2 = Position::new(CaretPos::new(32, 4032), CaretPos::new(3242, 6732));
832 let (ast, ast2) = (AST::new(pos, $left), AST::new(pos2, $right));
833 assert!(!ast.same_value(&ast2))
834 }};
835 }
836
837 macro_rules! two_ast {
838 ($left:expr) => {{
839 let pos = Position::new(CaretPos::new(3, 403), CaretPos::new(324, 673));
840 let pos2 = Position::new(CaretPos::new(32, 4032), CaretPos::new(3242, 6732));
841
842 let right = $left.clone();
843 let (ast, ast2) = (AST::new(pos, $left), AST::new(pos2, right));
844 assert!(ast.same_value(&ast2))
845 }};
846 ($left:expr, $right: expr) => {{
847 let pos = Position::new(CaretPos::new(3, 403), CaretPos::new(324, 673));
848 let pos2 = Position::new(CaretPos::new(32, 4032), CaretPos::new(3242, 6732));
849 let (ast, ast2) = (AST::new(pos, $left), AST::new(pos2, $right));
850 assert!(ast.same_value(&ast2))
851 }};
852 }
853
854 #[test]
855 fn simple_ast() {
856 let pos = Position::new(CaretPos::new(3, 403), CaretPos::new(324, 673));
857 let node = Node::Id { lit: String::from("fd") };
858
859 let ast = AST::new(pos, node.clone());
860
861 assert_eq!(ast.pos, pos);
862 assert_eq!(ast.node, node);
863 }
864
865 #[test]
866 fn id_equal_structure() {
867 two_ast!(Node::Id { lit: String::from("fd") }, Node::Id { lit: String::from("fd") });
868 }
869
870 #[test]
871 fn tuple_equal_structure() {
872 let node = Node::Tuple {
873 elements: vec![
874 AST::new(Position::invisible(), Node::Id { lit: String::from("aa") }),
875 AST::new(Position::invisible(), Node::Id { lit: String::from("ba") }),
876 ],
877 };
878
879 two_ast!(node);
880 }
881
882 #[test]
883 fn tuple_not_equal_structure() {
884 let pos = Position::invisible();
885 let node1 = Node::Tuple {
886 elements: vec![
887 AST::new(pos, Node::Id { lit: String::from("aa") }),
888 AST::new(pos, Node::Id { lit: String::from("ba") }),
889 AST::new(pos, Node::Id { lit: String::from("ca") }),
890 ],
891 };
892 let node2 = Node::Tuple {
893 elements: vec![
894 AST::new(pos, Node::Id { lit: String::from("aa") }),
895 AST::new(pos, Node::Id { lit: String::from("ba") }),
896 AST::new(pos, Node::Id { lit: String::from("ca") }),
897 AST::new(pos, Node::Id { lit: String::from("ca") }),
898 ],
899 };
900
901 two_ast_ne!(node1, node2);
902 }
903
904 #[test]
905 fn break_equal_structure() {
906 two_ast!(Node::Break, Node::Break);
907 }
908
909 #[test]
910 fn break_continue_not_equal_structure() {
911 two_ast_ne!(Node::Break, Node::Continue);
912 }
913
914 #[test]
915 fn import_equal_value() {
916 two_ast!(Node::Import {
917 from: Some(Box::from(AST::new(Position::invisible(), Node::Break))),
918 import: vec![AST::new(Position::invisible(), Node::Continue)],
919 alias: vec![AST::new(Position::invisible(), Node::Pass)],
920 });
921 }
922
923 #[test]
924 fn class_equal_value() {
925 let node = Node::Class {
926 ty: Box::new(AST::new(Position::invisible(), Node::Continue)),
927 args: vec![AST::new(Position::invisible(), Node::ReturnEmpty)],
928 parents: vec![AST::new(Position::invisible(), Node::Pass)],
929 body: Some(Box::from(AST::new(Position::invisible(), Node::new_self()))),
930 };
931
932 two_ast!(node);
933 }
934
935 #[test]
936 fn generic_equal_value() {
937 let node = Node::Generic {
938 id: Box::new(AST::new(Position::invisible(), Node::ReturnEmpty)),
939 isa: Some(Box::from(AST::new(Position::invisible(), Node::Continue))),
940 };
941
942 two_ast!(node);
943 }
944
945 #[test]
946 fn parent_equal_value() {
947 let node = Node::Parent {
948 ty: Box::new(AST::new(Position::invisible(), Node::new_self())),
949 args: vec![AST::new(Position::invisible(), Node::Pass)],
950 };
951
952 two_ast!(node);
953 }
954
955 #[test]
956 fn reassign_equal_value() {
957 let node = Node::Reassign {
958 left: Box::new(AST::new(Position::invisible(), Node::Pass)),
959 right: Box::new(AST::new(Position::invisible(), Node::ReturnEmpty)),
960 op: NodeOp::Sub,
961 };
962
963 two_ast!(node);
964 }
965
966 #[test]
967 fn def_equal_value() {
968 let first = Box::from(AST::new(Position::invisible(), Node::Continue));
969 let second = Box::from(AST::new(Position::invisible(), Node::Break));
970 let third = Box::from(AST::new(Position::invisible(), Node::Pass));
971
972 two_ast!(Node::VariableDef {
973 mutable: false,
974 var: first.clone(),
975 ty: Some(second.clone()),
976 expr: Some(third.clone()),
977 forward: vec![*first.clone()]
978 });
979 two_ast!(Node::FunDef {
980 pure: false,
981 id: first.clone(),
982 args: vec![*second.clone()],
983 ret: Some(third.clone()),
984 raises: vec![*first.clone(), *second.clone()],
985 body: Some(Box::from(AST::new(
986 Position::invisible(),
987 Node::Raise { error: third.clone() }
988 )))
989 });
990 }
991
992 #[test]
993 fn anon_fun_same_value() {
994 let first = Box::from(AST::new(Position::invisible(), Node::Continue));
995 let second = Box::from(AST::new(Position::invisible(), Node::Break));
996
997 two_ast!(Node::AnonFun { args: vec![*first.clone()], body: second.clone() });
998 }
999
1000 #[test]
1001 fn anon_raise_same_value() {
1002 let second = Box::from(AST::new(Position::invisible(), Node::Break));
1003 two_ast!(Node::Raise { error: second.clone() });
1004 }
1005
1006 #[test]
1007 fn handle_same_value() {
1008 let first = Box::from(AST::new(Position::invisible(), Node::Continue));
1009 let second = Box::from(AST::new(Position::invisible(), Node::Break));
1010 let third = Box::from(AST::new(Position::invisible(), Node::Pass));
1011
1012 two_ast!(Node::Handle { cases: vec![*first.clone()], expr_or_stmt: second.clone() });
1013 two_ast!(Node::With {
1014 resource: first.clone(),
1015 alias: Some((second.clone(), false, Some(third.clone()))),
1016 expr: Box::from(AST::new(Position::invisible(), Node::Pass))
1017 });
1018 }
1019
1020 #[test]
1021 fn call_same_value() {
1022 let first = Box::from(AST::new(Position::invisible(), Node::Continue));
1023 let second = Box::from(AST::new(Position::invisible(), Node::Break));
1024
1025 two_ast!(Node::FunctionCall { name: first.clone(), args: vec![*second.clone()] });
1026 two_ast!(Node::PropertyCall { instance: first.clone(), property: second.clone() });
1027 }
1028
1029 #[test]
1030 fn id_equal_value() {
1031 two_ast!(Node::Id { lit: String::from("id") });
1032 }
1033
1034 #[test]
1035 fn id_differnt_str_not_equal_value() {
1036 two_ast_ne!(Node::Id { lit: String::from("id") }, Node::Id { lit: String::from("id2") });
1037 }
1038
1039 #[test]
1040 fn expression_type_equal_value() {
1041 let expr = Box::from(AST::new(Position::invisible(), Node::Continue));
1042 let expr2 = Box::from(AST::new(Position::invisible(), Node::Pass));
1043 two_ast!(Node::ExpressionType {
1044 expr: expr.clone(),
1045 mutable: false,
1046 ty: Some(expr2.clone())
1047 });
1048 }
1049
1050 #[test]
1051 fn type_equal_value() {
1052 let first = Box::from(AST::new(Position::invisible(), Node::Continue));
1053 let second = Box::from(AST::new(Position::invisible(), Node::Break));
1054 let third = Box::from(AST::new(Position::invisible(), Node::Pass));
1055
1056 two_ast!(Node::TypeDef {
1057 ty: first.clone(),
1058 isa: Some(second.clone()),
1059 body: Some(third.clone())
1060 });
1061 two_ast!(Node::TypeAlias {
1062 ty: first.clone(),
1063 isa: second.clone(),
1064 conditions: vec![*third.clone()]
1065 });
1066 two_ast!(Node::TypeTup { types: vec![*third.clone(), *second.clone()] });
1067 two_ast!(Node::TypeUnion { types: vec![*third.clone(), *second.clone()] });
1068 two_ast!(Node::Type { id: first.clone(), generics: vec![*second.clone(), *third.clone()] });
1069 two_ast!(Node::TypeFun {
1070 args: vec![*first.clone(), *second.clone()],
1071 ret_ty: third.clone()
1072 });
1073
1074 two_ast!(Node::Condition { cond: first.clone(), el: Some(second.clone()) });
1075 }
1076
1077 #[test]
1078 fn literal_value() {
1079 two_ast!(Node::Real { lit: String::from("dgfdh") });
1080 two_ast!(Node::Int { lit: String::from("sdfdf") });
1081 two_ast!(Node::Bool { lit: true });
1082 two_ast!(Node::ENum { num: String::from("werw"), exp: String::from("reter") });
1083 two_ast!(Node::Str {
1084 lit: String::from("yuk"),
1085 expressions: vec![AST::new(Position::invisible(), Node::Continue)]
1086 });
1087 }
1088
1089 #[test]
1090 fn string_different_expression_not_same_value() {
1091 two_ast_ne!(
1092 Node::Str {
1093 lit: String::from("yuk"),
1094 expressions: vec![AST::new(Position::invisible(), Node::Continue)]
1095 },
1096 Node::Str {
1097 lit: String::from("yuk"),
1098 expressions: vec![AST::new(Position::invisible(), Node::Pass)]
1099 }
1100 );
1101 }
1102
1103 #[test]
1104 fn collection_same_value() {
1105 let item = Box::from(AST::new(Position::invisible(), Node::Id { lit: String::from("asdf") }));
1106
1107 two_ast!(Node::Set { elements: vec![*item.clone()] });
1108 two_ast!(Node::List { elements: vec![*item.clone()] });
1109 two_ast!(Node::Tuple { elements: vec![*item.clone()] });
1110
1111 two_ast!(Node::SetBuilder { item: item.clone(), conditions: vec![*item.clone()] });
1112 two_ast!(Node::ListBuilder { item: item.clone(), conditions: vec![*item.clone()] });
1113 }
1114
1115 #[test]
1116 fn block_same_value() {
1117 let first =
1118 Box::from(AST::new(Position::invisible(), Node::Id { lit: String::from("asdf") }));
1119 let second =
1120 Box::from(AST::new(Position::invisible(), Node::Id { lit: String::from("lkjh") }));
1121
1122 two_ast!(Node::Block { statements: vec![*first.clone(), *second.clone()] });
1123 }
1124
1125 #[test]
1126 fn docstr_different_str_same_value() {
1127 two_ast!(
1128 Node::DocStr { lit: String::from("asdf") },
1129 Node::DocStr { lit: String::from("lkjh") }
1130 );
1131 }
1132
1133 #[test]
1134 fn binary_op_same_value() {
1135 let left = Box::from(AST::new(Position::invisible(), Node::Id { lit: String::from("asdf") }));
1136 let right =
1137 Box::from(AST::new(Position::invisible(), Node::Id { lit: String::from("lkjh") }));
1138
1139 two_ast!(Node::Add { left: left.clone(), right: right.clone() });
1140 two_ast!(Node::Sub { left: left.clone(), right: right.clone() });
1141 two_ast!(Node::Mul { left: left.clone(), right: right.clone() });
1142 two_ast!(Node::Div { left: left.clone(), right: right.clone() });
1143 two_ast!(Node::FDiv { left: left.clone(), right: right.clone() });
1144 two_ast!(Node::Mod { left: left.clone(), right: right.clone() });
1145 two_ast!(Node::Pow { left: left.clone(), right: right.clone() });
1146 two_ast!(Node::BAnd { left: left.clone(), right: right.clone() });
1147 two_ast!(Node::BOr { left: left.clone(), right: right.clone() });
1148 two_ast!(Node::BXOr { left: left.clone(), right: right.clone() });
1149
1150 two_ast!(Node::BAnd { left: left.clone(), right: right.clone() });
1151 two_ast!(Node::BOr { left: left.clone(), right: right.clone() });
1152 two_ast!(Node::BXOr { left: left.clone(), right: right.clone() });
1153 two_ast!(Node::BLShift { left: left.clone(), right: right.clone() });
1154 two_ast!(Node::BRShift { left: left.clone(), right: right.clone() });
1155
1156 two_ast!(Node::Le { left: left.clone(), right: right.clone() });
1157 two_ast!(Node::Ge { left: left.clone(), right: right.clone() });
1158 two_ast!(Node::Leq { left: left.clone(), right: right.clone() });
1159 two_ast!(Node::Geq { left: left.clone(), right: right.clone() });
1160 two_ast!(Node::Is { left: left.clone(), right: right.clone() });
1161 two_ast!(Node::IsN { left: left.clone(), right: right.clone() });
1162 two_ast!(Node::Eq { left: left.clone(), right: right.clone() });
1163 two_ast!(Node::Neq { left: left.clone(), right: right.clone() });
1164 two_ast!(Node::IsA { left: left.clone(), right: right.clone() });
1165 two_ast!(Node::IsNA { left: left.clone(), right: right.clone() });
1166
1167 two_ast!(Node::And { left: left.clone(), right: right.clone() });
1168 two_ast!(Node::Or { left: left.clone(), right: right.clone() });
1169 }
1170
1171 #[test]
1172 fn unary_op_same_value() {
1173 let expr =
1174 Box::from(AST::new(Position::invisible(), Node::Id { lit: String::from("qwerty") }));
1175
1176 two_ast!(Node::AddU { expr: expr.clone() });
1177 two_ast!(Node::SubU { expr: expr.clone() });
1178 two_ast!(Node::Sqrt { expr: expr.clone() });
1179 two_ast!(Node::BOneCmpl { expr: expr.clone() });
1180 two_ast!(Node::Not { expr: expr.clone() });
1181 }
1182
1183 #[test]
1184 fn contrl_flow_same_value() {
1185 let cond =
1186 Box::from(AST::new(Position::invisible(), Node::Id { lit: String::from("qwerty") }));
1187 let body = Box::from(AST::new(Position::invisible(), Node::ReturnEmpty));
1188 let third = Box::from(AST::new(Position::invisible(), Node::Continue));
1189
1190 two_ast!(Node::IfElse { cond: cond.clone(), then: body.clone(), el: Some(third.clone()) });
1191 two_ast!(Node::Match { cond: cond.clone(), cases: vec![*body.clone(), *third.clone()] });
1192 two_ast!(Node::Case { cond: cond.clone(), body: body.clone() });
1193 two_ast!(Node::Range {
1194 from: cond.clone(),
1195 to: body.clone(),
1196 inclusive: true,
1197 step: Some(third.clone())
1198 });
1199 two_ast!(Node::For { expr: cond.clone(), col: body.clone(), body: third.clone() });
1200 two_ast!(Node::In { left: cond.clone(), right: body.clone() });
1201
1202 two_ast!(Node::While { cond: cond.clone(), body: body.clone() });
1203 }
1204
1205 #[test]
1206 fn cntrl_flow_op_equal_value() {
1207 two_ast!(Node::Break);
1208 two_ast!(Node::Continue);
1209 two_ast!(Node::ReturnEmpty);
1210 two_ast!(Node::Underscore);
1211 two_ast!(Node::Undefined);
1212 two_ast!(Node::Pass);
1213 }
1214
1215 #[test]
1216 fn return_equal_value() {
1217 two_ast!(Node::Return { expr: Box::from(AST::new(Position::invisible(), Node::Continue)) });
1218 }
1219
1220 #[test]
1221 fn question_equal_value() {
1222 two_ast!(Node::QuestionOp {
1223 expr: Box::from(AST::new(Position::invisible(), Node::Continue))
1224 });
1225 two_ast!(Node::Question {
1226 left: Box::from(AST::new(Position::invisible(), Node::Continue)),
1227 right: Box::from(AST::new(Position::invisible(), Node::Break))
1228 });
1229 }
1230
1231 #[test]
1232 fn block_end_with_expression_is_expression() {
1233 let node = Node::Block {
1234 statements: vec![
1235 AST::new(Position::invisible(), Node::Pass),
1236 AST::new(Position::invisible(), Node::Int { lit: String::from("3") }),
1237 ],
1238 };
1239 assert!(node.is_expression())
1240 }
1241
1242 #[test]
1243 fn block_end_with_statement_not_expression() {
1244 let node = Node::Block {
1245 statements: vec![
1246 AST::new(Position::invisible(), Node::Int { lit: String::from("3") }),
1247 AST::new(Position::invisible(), Node::Pass),
1248 ],
1249 };
1250 assert!(!node.is_expression())
1251 }
1252
1253 #[test]
1254 fn empty_block_not_expression() {
1255 assert!(!Node::Block { statements: vec![] }.is_expression())
1256 }
1257
1258 #[test]
1259 fn if_is_not_expression() {
1260 let node = Node::IfElse {
1261 cond: Box::new(AST::new(Position::invisible(), Node::Bool { lit: true })),
1262 then: Box::new(AST::new(Position::invisible(), Node::Pass)),
1263 el: None,
1264 };
1265 assert!(!node.is_expression())
1266 }
1267
1268 #[test]
1269 fn if_else_is_not_expression() {
1270 let node = Node::IfElse {
1271 cond: Box::new(AST::new(Position::invisible(), Node::Bool { lit: true })),
1272 then: Box::new(AST::new(Position::invisible(), Node::Pass)),
1273 el: Some(Box::new(AST::new(Position::invisible(), Node::Pass))),
1274 };
1275 assert!(node.is_expression())
1276 }
1277
1278 #[test]
1279 fn expression_is_expression() {
1280 let first = Box::from(AST::new(Position::invisible(), Node::Continue));
1281 let second = Box::from(AST::new(Position::invisible(), Node::Break));
1282 let third = Box::from(AST::new(Position::invisible(), Node::Pass));
1283
1284 assert!(Node::AnonFun { args: vec![*first.clone()], body: second.clone() }.is_expression());
1285 assert!(Node::PropertyCall { instance: first.clone(), property: second.clone() }
1286 .is_expression());
1287 assert!(Node::Id { lit: String::from("s") }.is_expression());
1288 assert!(Node::Set { elements: vec![*first.clone(), *second.clone()] }.is_expression());
1289 assert!(Node::SetBuilder { item: first.clone(), conditions: vec![*third.clone()] }
1290 .is_expression());
1291 assert!(Node::List { elements: vec![*first.clone(), *second.clone()] }.is_expression());
1292 assert!(Node::ListBuilder { item: first.clone(), conditions: vec![*third.clone()] }
1293 .is_expression());
1294 assert!(Node::Tuple { elements: vec![*first.clone(), *second.clone()] }.is_expression());
1295 assert!(Node::Range {
1296 from: first.clone(),
1297 to: second.clone(),
1298 inclusive: false,
1299 step: None,
1300 }
1301 .is_expression());
1302 assert!(Node::Real { lit: String::from("6.7") }.is_expression());
1303 assert!(Node::Int { lit: String::from("3") }.is_expression());
1304 assert!(Node::ENum { num: String::from("4"), exp: String::from("4") }.is_expression());
1305 assert!(Node::Str { lit: String::from("asdf"), expressions: vec![*third.clone()] }
1306 .is_expression());
1307 assert!(Node::Bool { lit: false }.is_expression());
1308 assert!(Node::Match { cond: first.clone(), cases: vec![*second.clone()] }.is_expression());
1309 assert!(Node::Underscore.is_expression());
1310 assert!(Node::Undefined.is_expression());
1311 assert!(Node::Question { left: first.clone(), right: third.clone() }.is_expression());
1312 assert!(Node::QuestionOp { expr: second.clone() }.is_expression());
1313 }
1314
1315 #[test]
1316 fn operator_is_expression() {
1317 let left = Box::from(AST::new(Position::invisible(), Node::Id { lit: String::from("left") }));
1318 let right =
1319 Box::from(AST::new(Position::invisible(), Node::Id { lit: String::from("right") }));
1320
1321 assert!(Node::Add { left: left.clone(), right: right.clone() }.is_expression());
1322 assert!(Node::AddU { expr: left.clone() }.is_expression());
1323 assert!(Node::Sub { left: left.clone(), right: right.clone() }.is_expression());
1324 assert!(Node::SubU { expr: right.clone() }.is_expression());
1325 assert!(Node::Mul { left: left.clone(), right: right.clone() }.is_expression());
1326 assert!(Node::Div { left: left.clone(), right: right.clone() }.is_expression());
1327 assert!(Node::FDiv { left: left.clone(), right: right.clone() }.is_expression());
1328 assert!(Node::Mod { left: left.clone(), right: right.clone() }.is_expression());
1329 assert!(Node::Pow { left: left.clone(), right: right.clone() }.is_expression());
1330 assert!(Node::Sqrt { expr: right.clone() }.is_expression());
1331 assert!(Node::BAnd { left: left.clone(), right: right.clone() }.is_expression());
1332 assert!(Node::BOr { left: left.clone(), right: right.clone() }.is_expression());
1333 assert!(Node::BXOr { left: left.clone(), right: right.clone() }.is_expression());
1334 assert!(Node::BOneCmpl { expr: right.clone() }.is_expression());
1335 assert!(Node::BLShift { left: left.clone(), right: right.clone() }.is_expression());
1336 assert!(Node::BRShift { left: left.clone(), right: right.clone() }.is_expression());
1337 assert!(Node::Le { left: left.clone(), right: right.clone() }.is_expression());
1338 assert!(Node::Ge { left: left.clone(), right: right.clone() }.is_expression());
1339 assert!(Node::Leq { left: left.clone(), right: right.clone() }.is_expression());
1340 assert!(Node::Geq { left: left.clone(), right: right.clone() }.is_expression());
1341 assert!(Node::Is { left: left.clone(), right: right.clone() }.is_expression());
1342 assert!(Node::IsN { left: left.clone(), right: right.clone() }.is_expression());
1343 assert!(Node::Eq { left: left.clone(), right: right.clone() }.is_expression());
1344 assert!(Node::Neq { left: left.clone(), right: right.clone() }.is_expression());
1345 assert!(Node::IsA { left: left.clone(), right: right.clone() }.is_expression());
1346 assert!(Node::IsNA { left: left.clone(), right: right.clone() }.is_expression());
1347 assert!(Node::Not { expr: right.clone() }.is_expression());
1348 assert!(Node::And { left: left.clone(), right: right.clone() }.is_expression());
1349 assert!(Node::Or { left: left.clone(), right: right.clone() }.is_expression());
1350 assert!(Node::In { left: left.clone(), right: right.clone() }.is_expression());
1351 }
1352
1353 #[test]
1354 fn is_operator() {
1355 let left = Box::from(AST::new(Position::invisible(), Node::Id { lit: String::from("asdf") }));
1356 let right =
1357 Box::from(AST::new(Position::invisible(), Node::Id { lit: String::from("lkjh") }));
1358
1359 assert!(Node::Add { left: left.clone(), right: right.clone() }.is_operator());
1360 assert!(Node::AddU { expr: left.clone() }.is_operator());
1361 assert!(Node::Sub { left: left.clone(), right: right.clone() }.is_operator());
1362 assert!(Node::SubU { expr: right.clone() }.is_operator());
1363 assert!(Node::Mul { left: left.clone(), right: right.clone() }.is_operator());
1364 assert!(Node::Div { left: left.clone(), right: right.clone() }.is_operator());
1365 assert!(Node::FDiv { left: left.clone(), right: right.clone() }.is_operator());
1366 assert!(Node::Mod { left: left.clone(), right: right.clone() }.is_operator());
1367 assert!(Node::Pow { left: left.clone(), right: right.clone() }.is_operator());
1368 assert!(Node::Sqrt { expr: right.clone() }.is_operator());
1369 assert!(Node::BAnd { left: left.clone(), right: right.clone() }.is_operator());
1370 assert!(Node::BOr { left: left.clone(), right: right.clone() }.is_operator());
1371 assert!(Node::BXOr { left: left.clone(), right: right.clone() }.is_operator());
1372 assert!(Node::BOneCmpl { expr: right.clone() }.is_operator());
1373 assert!(Node::BLShift { left: left.clone(), right: right.clone() }.is_operator());
1374 assert!(Node::BRShift { left: left.clone(), right: right.clone() }.is_operator());
1375 assert!(Node::Le { left: left.clone(), right: right.clone() }.is_operator());
1376 assert!(Node::Ge { left: left.clone(), right: right.clone() }.is_operator());
1377 assert!(Node::Leq { left: left.clone(), right: right.clone() }.is_operator());
1378 assert!(Node::Geq { left: left.clone(), right: right.clone() }.is_operator());
1379 assert!(Node::Is { left: left.clone(), right: right.clone() }.is_operator());
1380 assert!(Node::IsN { left: left.clone(), right: right.clone() }.is_operator());
1381 assert!(Node::Eq { left: left.clone(), right: right.clone() }.is_operator());
1382 assert!(Node::Neq { left: left.clone(), right: right.clone() }.is_operator());
1383 assert!(Node::IsA { left: left.clone(), right: right.clone() }.is_operator());
1384 assert!(Node::IsNA { left: left.clone(), right: right.clone() }.is_operator());
1385 assert!(Node::Not { expr: right.clone() }.is_operator());
1386 assert!(Node::And { left: left.clone(), right: right.clone() }.is_operator());
1387 assert!(Node::Or { left: left.clone(), right: right.clone() }.is_operator());
1388 assert!(Node::In { left: left.clone(), right: right.clone() }.is_operator());
1389 }
1390}