blob: fec22b14dbd76c8652663689a3dcaf77142cb8a7 [file] [log] [blame]
Akron0d9117c2025-05-27 15:20:21 +02001package ast
2
3import (
4 "reflect"
5)
6
7// NodesEqual compares two AST nodes for equality
8func NodesEqual(a, b Node) bool {
9 if a == nil || b == nil {
10 return a == b
11 }
12
13 if a.Type() != b.Type() {
14 return false
15 }
16
17 switch n1 := a.(type) {
18 case *Term:
19 if n2, ok := b.(*Term); ok {
20 return n1.Foundry == n2.Foundry &&
21 n1.Key == n2.Key &&
22 n1.Layer == n2.Layer &&
23 n1.Match == n2.Match &&
24 n1.Value == n2.Value
25 }
26 case *TermGroup:
27 if n2, ok := b.(*TermGroup); ok {
28 if n1.Relation != n2.Relation || len(n1.Operands) != len(n2.Operands) {
29 return false
30 }
31 for i := range n1.Operands {
32 if !NodesEqual(n1.Operands[i], n2.Operands[i]) {
33 return false
34 }
35 }
36 return true
37 }
38 case *Token:
39 if n2, ok := b.(*Token); ok {
40 return NodesEqual(n1.Wrap, n2.Wrap)
41 }
42 case *CatchallNode:
43 if n2, ok := b.(*CatchallNode); ok {
44 return n1.NodeType == n2.NodeType &&
45 reflect.DeepEqual(n1.RawContent, n2.RawContent) &&
46 NodesEqual(n1.Wrap, n2.Wrap)
47 }
48 }
49 return false
50}
51
52// IsTermNode checks if a node is a Term node
53func IsTermNode(node Node) bool {
54 _, ok := node.(*Term)
55 return ok
56}