Beispiel #1
0
func (p *parser) postfixExpr() ast.Node {
	line := p.line()
	left := p.callExpr()

	if ast.IsPostfixOp(p.tok) {
		op := p.tok
		p.next()
		return &ast.PostfixExpr{Op: op, Left: left, NodeInfo: ast.NodeInfo{line}}
	}

	return left
}
Beispiel #2
0
func (c *compiler) VisitUnaryExpr(node *ast.UnaryExpr, data interface{}) {
	var reg int
	expr, exprok := data.(*exprdata)
	if exprok {
		reg = expr.rega
	} else {
		reg = c.genRegister()
	}
	value, ok := c.constFold(node)
	if ok {
		if exprok && expr.propagate {
			expr.regb = OpConstOffset + c.addConst(value)
			return
		}
		c.emitABx(OpLoadconst, reg, c.addConst(value), node.NodeInfo.Line)
	} else if ast.IsPostfixOp(node.Op) {
		op := OpAdd
		if node.Op == ast.TokenMinusminus {
			op = OpSub
		}
		exprdata := exprdata{true, reg, reg}
		node.Right.Accept(c, &exprdata)
		one := OpConstOffset + c.addConst(Number(1))
		c.emitABC(op, exprdata.regb, exprdata.regb, one, node.NodeInfo.Line)

		// don't bother moving if we're not in an expression
		if exprok {
			c.emitAB(OpMove, reg, exprdata.regb, node.NodeInfo.Line)
		}
	} else {
		var op Opcode
		switch node.Op {
		case ast.TokenMinus:
			op = OpUnm
		case ast.TokenNot, ast.TokenBang:
			op = OpNot
		case ast.TokenTilde:
			op = OpCmpl
		}
		exprdata := exprdata{true, reg, reg}
		node.Right.Accept(c, &exprdata)
		c.emitABx(op, reg, exprdata.regb, node.NodeInfo.Line)
		if exprok && expr.propagate {
			expr.regb = reg
		}
	}
}