about summary refs log tree commit diff
path: root/pkg/lang/parser/bin_order.go
blob: 666d1fc909735cdb6be1090e3e8c22403e81d6d7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package parser

import (
	"jinx/pkg/lang/ast"
)

func (p *Parser) mergeIntoBinary(left ast.Expr, op ast.BinOp, right ast.Expr) ast.ExprBinary {
	if right.Kind == ast.ExprKindBinary {
		rightBin := right.Value.(ast.ExprBinary)

		needsSwitch := (op.Precedence() > rightBin.Op.Precedence()) ||
			(op.Precedence() == rightBin.Op.Precedence() && op.Associativity() == ast.AssociativityLeft)

		if needsSwitch {
			leftBin := p.mergeIntoBinary(left, op, rightBin.Left)

			left = ast.Expr{
				At:    left.At,
				Kind:  ast.ExprKindBinary,
				Value: leftBin,
			}

			right = rightBin.Right

			op = rightBin.Op
		}
	}

	return ast.ExprBinary{
		Left:  left,
		Op:    op,
		Right: right,
	}
}