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 }
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 } } }