Esempio n. 1
0
// unaryExpr generates code unary operators (+a, -a, ~a, !a, etc).
func (c *compiler) unaryExpr(e *ast.UnaryExpr, lv *arch.LV) *node {
	pos := e.Span().Start
	n := c.exprInternal(e.X, lv)

	var x opcode
	switch op := e.Op.Type; op {
	case scan.Inc, scan.Dec:
		switch {
		case op == scan.Inc && e.Affix == ast.Prefix:
			x = opPreInc
		case op == scan.Inc && e.Affix == ast.Postfix:
			x = opPostInc
		case op == scan.Dec && e.Affix == ast.Prefix:
			x = opPreDec
		case op == scan.Dec && e.Affix == ast.Postfix:
			x = opPostDec
		}
		n = newNode(x, lv, nil, n, nil)
		lv.Addressable = false

	case scan.Plus:
		n = c.rvalue(n, lv)
		lv.Addressable = false

	case scan.Minus, scan.Negate, scan.Not:
		switch op {
		case scan.Minus:
			x = opNeg
		case scan.Negate:
			x = opNot
		case scan.Not:
			x = opLogNot
		}
		n = c.rvalue(n, lv)
		n = newNode(x, lv, nil, n, nil)
		lv.Addressable = false

	case scan.And:
		if lv.Addressable && lv.Ident {
			n = newNode(opAddr, lv, nil, n, nil)
		}
		lv.Addressable = false

	default:
		c.errorf(pos, "invalid unary expression %v", op)
	}
	return n
}
Esempio n. 2
0
// incOrDec type checks an expression for ++/-- operators.
func (c *checker) incOrDec(x *operand, e *ast.UnaryExpr, op scan.Type) {
	Y := &ast.BasicLit{scan.Token{scan.Number, e.Span().Start, "1"}}
	c.binary(x, e.X, Y, op)
}