From e5aa440109f0464eb218aca93bb761b71d974c35 Mon Sep 17 00:00:00 2001 From: Morgan Bazalgette Date: Wed, 11 Oct 2023 00:16:12 +0100 Subject: [PATCH] fix(gnolang): allow floats in inc/dec statements --- gnovm/pkg/gnolang/op_inc_dec.go | 47 +++++++++++++++++++++++-- gnovm/tests/files/{inc.gno => inc0.gno} | 0 gnovm/tests/files/inc1.gno | 15 ++++++++ 3 files changed, 60 insertions(+), 2 deletions(-) rename gnovm/tests/files/{inc.gno => inc0.gno} (100%) create mode 100644 gnovm/tests/files/inc1.gno diff --git a/gnovm/pkg/gnolang/op_inc_dec.go b/gnovm/pkg/gnolang/op_inc_dec.go index 80987707035..70886497d5e 100644 --- a/gnovm/pkg/gnolang/op_inc_dec.go +++ b/gnovm/pkg/gnolang/op_inc_dec.go @@ -1,5 +1,12 @@ package gnolang +import ( + "fmt" + "math/big" + + "github.com/cockroachdb/apd" +) + func (m *Machine) doOpInc() { s := m.PopStmt().(*IncDecStmt) @@ -42,8 +49,26 @@ func (m *Machine) doOpInc() { lv.SetUint32(lv.GetUint32() + 1) case Uint64Type: lv.SetUint64(lv.GetUint64() + 1) + case Float32Type: + lv.SetFloat32(lv.GetFloat32() + 1) + case Float64Type: + lv.SetFloat64(lv.GetFloat64() + 1) + case BigintType, UntypedBigintType: + lb := lv.GetBigInt() + lb = big.NewInt(0).Add(lb, big.NewInt(1)) + lv.V = BigintValue{V: lb} + case BigdecType, UntypedBigdecType: + lb := lv.GetBigDec() + sum := apd.New(0, 0) + cond, err := apd.BaseContext.WithPrecision(0).Add(sum, lb, apd.New(1, 0)) + if err != nil { + panic(fmt.Sprintf("bigdec addition error: %v", err)) + } else if cond.Inexact() { + panic(fmt.Sprintf("bigdec addition inexact: %v + 1", lb)) + } + lv.V = BigdecValue{V: sum} default: - panic("unexpected type in in operation") + panic(fmt.Sprintf("unexpected type %s in inc/dec operation", lv.T)) } // Mark dirty in realm. @@ -94,8 +119,26 @@ func (m *Machine) doOpDec() { lv.SetUint32(lv.GetUint32() - 1) case Uint64Type: lv.SetUint64(lv.GetUint64() - 1) + case Float32Type: + lv.SetFloat32(lv.GetFloat32() - 1) + case Float64Type: + lv.SetFloat64(lv.GetFloat64() - 1) + case BigintType, UntypedBigintType: + lb := lv.GetBigInt() + lb = big.NewInt(0).Sub(lb, big.NewInt(1)) + lv.V = BigintValue{V: lb} + case BigdecType, UntypedBigdecType: + lb := lv.GetBigDec() + sum := apd.New(0, 0) + cond, err := apd.BaseContext.WithPrecision(0).Sub(sum, lb, apd.New(1, 0)) + if err != nil { + panic(fmt.Sprintf("bigdec addition error: %v", err)) + } else if cond.Inexact() { + panic(fmt.Sprintf("bigdec addition inexact: %v + 1", lb)) + } + lv.V = BigdecValue{V: sum} default: - panic("unexpected type in in operation") + panic(fmt.Sprintf("unexpected type %s in inc/dec operation", lv.T)) } // Mark dirty in realm. diff --git a/gnovm/tests/files/inc.gno b/gnovm/tests/files/inc0.gno similarity index 100% rename from gnovm/tests/files/inc.gno rename to gnovm/tests/files/inc0.gno diff --git a/gnovm/tests/files/inc1.gno b/gnovm/tests/files/inc1.gno new file mode 100644 index 00000000000..f997b3b9a00 --- /dev/null +++ b/gnovm/tests/files/inc1.gno @@ -0,0 +1,15 @@ +package main + +func main() { + var i float64 = 899 + i++ + println(i) + + j := float32(901) + j-- + println(j) +} + +// Output: +// 900 +// 900