github.com/arnodel/golua@v0.0.0-20230215163904-e0b5347eaaa1/ast/binopexp.go (about) 1 package ast 2 3 import ( 4 "github.com/arnodel/golua/ops" 5 "github.com/arnodel/golua/token" 6 ) 7 8 // A BinOp is a expression node that represents any binary operator. The right 9 // hand side can be a list of operations of the same type (OpType). All 10 // operations of the same type have the same precedence and can be merged into a 11 // list. 12 type BinOp struct { 13 Location 14 Left ExpNode 15 OpType ops.Op 16 Right []Operation 17 } 18 19 var _ ExpNode = BinOp{} 20 21 // An Operation is a pair (operator, operand) which can be applied to an 22 // expression node (e.g. "+ 2" or "/ 5"). 23 type Operation struct { 24 Op ops.Op 25 Operand ExpNode 26 } 27 28 // NewBinOp creates a new BinOp from the given arguments. If the left node is 29 // already a BinOp node with the same operator type, a new node based on that 30 // will be created. 31 func NewBinOp(left ExpNode, op ops.Op, opTok *token.Token, right ExpNode) *BinOp { 32 loc := MergeLocations(left, right) 33 leftOp, ok := left.(*BinOp) 34 opType := op.Type() 35 if ok && leftOp.OpType == opType { 36 return &BinOp{ 37 Location: loc, 38 Left: leftOp.Left, 39 OpType: opType, 40 Right: append(leftOp.Right, Operation{op, right}), 41 } 42 } 43 return &BinOp{ 44 Location: LocFromToken(opTok), 45 Left: left, 46 OpType: opType, 47 Right: []Operation{{op, right}}, 48 } 49 } 50 51 // ProcessExp uses the given ExpProcessor to process the receiver. 52 func (b BinOp) ProcessExp(p ExpProcessor) { 53 p.ProcessBinOpExp(b) 54 } 55 56 // HWrite prints a tree representation of the node. 57 func (b BinOp) HWrite(w HWriter) { 58 w.Writef("binop: %d", b.OpType) 59 w.Indent() 60 w.Next() 61 b.Left.HWrite(w) 62 for _, r := range b.Right { 63 w.Next() 64 w.Writef("op: %s", r.Op) 65 w.Next() 66 w.Writef("right: ") 67 r.Operand.HWrite(w) 68 } 69 w.Dedent() 70 }