Exemple #1
0
// 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
}