mamba/parse/ast/
node.rs

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    /// Apply mapping to node, before recursively applying mapping to result
148    #[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    /// True if node is an expression with certainty.
671    ///
672    /// If False, then it might still be an expression if for instance it is a function call.
673    /// In such a case, the type checker must determine if it is an expression.
674    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}