about summary refs log tree commit diff
path: root/pkg/lang/parser/bin_order.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/lang/parser/bin_order.go')
-rw-r--r--pkg/lang/parser/bin_order.go34
1 files changed, 34 insertions, 0 deletions
diff --git a/pkg/lang/parser/bin_order.go b/pkg/lang/parser/bin_order.go
new file mode 100644
index 0000000..666d1fc
--- /dev/null
+++ b/pkg/lang/parser/bin_order.go
@@ -0,0 +1,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,
+	}
+}