// binaryExpr generates code for binary operators. func (c *compiler) binaryExpr(e *ast.BinaryExpr, lv *arch.LV) *node { op := e.Op.Type if op == scan.Land || op == scan.Lor { return c.logical(op, e, lv) } var lv2 arch.LV n := c.exprInternal(e.X, lv) m := c.rvalue(c.exprInternal(e.Y, &lv2), &lv2) bop := binOp(op) aop := arithOp(op) switch { // regular binary operators (+, -, *, /, etc) case bop != 0: tv, found := c.typAndValue(e) if !found { return nil } n = c.rvalue(n, lv) lv.Btype = tv.Type return newNode(bop, lv, &lv2, n, m) // binary assignment operator such as (+=, -=, *=, /=, etc) case aop != 0: lvs := *lv src := c.rvalue(n, &lvs) m = newNode(aop, lv, &lv2, src, m) n = newNode(opAssign, lv, &lv2, n, m) lv.Addressable = false // assignment operator (=) case op == scan.Assign: n = newNode(opAssign, lv, &lv2, n, m) lv.Addressable = false // comma operator (,) case op == scan.Comma: n = c.rvalue(n, lv) n = newNode(opComma, &lv2, nil, n, m) default: c.errorf(e.Span().Start, "unknown binary op: %s\n", e.Op.Text) } return n }