Skip to content

Commit

Permalink
fix: fix unary and binary node print
Browse files Browse the repository at this point in the history
consider the precedence of operators and their associative law when printing unary and binary nodes
  • Loading branch information
zhuliquan committed Jun 26, 2024
1 parent ef455a9 commit 3375714
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 2 deletions.
25 changes: 23 additions & 2 deletions ast/print.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,13 @@ func (n *UnaryNode) String() string {
op = fmt.Sprintf("%s ", n.Operator)
}
wrap := false
switch n.Node.(type) {
case *BinaryNode, *ConditionalNode:
switch b := n.Node.(type) {
case *BinaryNode:
if operator.Binary[b.Operator].Precedence <
operator.Unary[n.Operator].Precedence {
wrap = true
}
case *ConditionalNode:
wrap = true
}
if wrap {
Expand All @@ -68,10 +73,21 @@ func (n *BinaryNode) String() string {
var lhs, rhs string
var lwrap, rwrap bool

if l, ok := n.Left.(*UnaryNode); ok {
if operator.Unary[l.Operator].Precedence <
operator.Binary[n.Operator].Precedence {
lwrap = true
}
}
if lb, ok := n.Left.(*BinaryNode); ok {
if operator.Less(lb.Operator, n.Operator) {
lwrap = true
}
if operator.Binary[lb.Operator].Precedence ==
operator.Binary[n.Operator].Precedence &&
operator.Binary[n.Operator].Associativity == operator.Right {
lwrap = true
}
if lb.Operator == "??" {
lwrap = true
}
Expand All @@ -83,6 +99,11 @@ func (n *BinaryNode) String() string {
if operator.Less(rb.Operator, n.Operator) {
rwrap = true
}
if operator.Binary[rb.Operator].Precedence ==
operator.Binary[n.Operator].Precedence &&
operator.Binary[n.Operator].Associativity == operator.Left {
rwrap = true
}
if operator.IsBoolean(rb.Operator) && n.Operator != rb.Operator {
rwrap = true
}
Expand Down
5 changes: 5 additions & 0 deletions ast/print_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ func TestPrint(t *testing.T) {
{`{("a" + "b"): 42}`, `{("a" + "b"): 42}`},
{`(One == 1 ? true : false) && Two == 2`, `(One == 1 ? true : false) && Two == 2`},
{`not (a == 1 ? b > 1 : b < 2)`, `not (a == 1 ? b > 1 : b < 2)`},
{`(-(1+1)) ** 2`, `(-(1 + 1)) ** 2`},
{`2 ** (-(1+1))`, `2 ** -(1 + 1)`},
{`(2 ** 2) ** 3`, `(2 ** 2) ** 3`},
{`(3 + 5) / (5 % 3)`, `(3 + 5) / (5 % 3)`},
{`(-(1+1)) == 2`, `-(1 + 1) == 2`},
}

for _, tt := range tests {
Expand Down

0 comments on commit 3375714

Please sign in to comment.