func (a *stmtCompiler) compileIncDecStmt(s *ast.IncDecStmt) { // Create temporary block for extractEffect bc := a.enterChild() defer bc.exit() l := a.compileExpr(bc.block, false, s.X) if l == nil { return } if l.evalAddr == nil { l.diag("cannot assign to %s", l.desc) return } if !(l.t.isInteger() || l.t.isFloat()) { l.diagOpType(s.Tok, l.t) return } var op token.Token var desc string switch s.Tok { case token.INC: op = token.ADD desc = "increment statement" case token.DEC: op = token.SUB desc = "decrement statement" default: log.Panicf("Unexpected IncDec token %v", s.Tok) } effect, l := l.extractEffect(bc.block, desc) one := l.newExpr(IdealIntType, "constant") one.pos = s.Pos() one.eval = func() *big.Int { return big.NewInt(1) } binop := l.compileBinaryExpr(op, l, one) if binop == nil { return } assign := a.compileAssign(s.Pos(), bc.block, l.t, []*expr{binop}, "", "") if assign == nil { log.Panicf("compileAssign type check failed") } lf := l.evalAddr a.push(func(v *Thread) { effect(v) assign(lf(v), v) }) }
func (w *World) compileIncDecStmt(n *ast.IncDecStmt) Expr { l := w.compileLvalue(n.X) switch n.Tok { case token.INC: rhs_plus1 := &addone{incdec{typeConv(n.Pos(), l, float64_t)}} return &assignStmt{lhs: l, rhs: typeConv(n.Pos(), rhs_plus1, l.Type())} case token.DEC: rhs_minus1 := &subone{incdec{typeConv(n.Pos(), l, float64_t)}} return &assignStmt{lhs: l, rhs: typeConv(n.Pos(), rhs_minus1, l.Type())} default: panic(err(n.Pos(), "not allowed:", n.Tok)) } }