Skip to content

Commit

Permalink
feat(sdk/vm): support float as arguments to maketx call (#1434)
Browse files Browse the repository at this point in the history
<!-- please provide a detailed description of the changes made in this
pull request. -->
Addresses #1427

This allows passing in float types to contract functions
<details><summary>Contributors' checklist...</summary>

- [x] Added new tests, or not needed, or not feasible
- [ ] Provided an example (e.g. screenshot) to aid review or the PR is
self-explanatory
- [ ] Updated the official documentation or not needed
- [ ] No breaking changes were made, or a `BREAKING CHANGE: xxx` message
was included in the description
- [x] Added references to related issues and PRs
- [ ] Provided any useful hints for running manual tests
- [ ] Added new benchmarks to [generated
graphs](https://gnoland.github.io/benchmarks), if any. More info
[here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md).
</details>

---------

Co-authored-by: Hariom Verma <hariom18599@gmail.com>
  • Loading branch information
deelawn and harry-hov authored Feb 1, 2024
1 parent d6f0cde commit 988ca91
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 30 deletions.
24 changes: 24 additions & 0 deletions gno.land/cmd/gnoland/testdata/float-arg.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# test for float args

## start a new node
gnoland start

gnokey maketx addpkg -pkgdir $WORK -pkgpath gno.land/r/demo/float_realm -gas-fee 1000000ugnot -gas-wanted 2000000 -broadcast -chainid=tendermint_test test1

gnokey maketx call -pkgpath gno.land/r/demo/float_realm --func AddF32 -args 10.5 --args 20 --gas-fee 1000000ugnot --gas-wanted 2000000 --broadcast -chainid=tendermint_test test1
stdout '(30.5 float32)'

gnokey maketx call -pkgpath gno.land/r/demo/float_realm --func AddF64 -args 3.1 --args 2.2 --gas-fee 1000000ugnot --gas-wanted 2000000 --broadcast -chainid=tendermint_test test1
stdout '(5.3[0-9]* float64)'

-- float_realm.gno --
package float_realm

func AddF32(x, y float32) float32 {
return x + y
}

func AddF64(x, y float64) float64 {
return x + y
}

70 changes: 40 additions & 30 deletions gno.land/pkg/sdk/vm/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,16 @@ import (
"fmt"
"strconv"

"github.com/cockroachdb/apd/v3"
gno "github.com/gnolang/gno/gnovm/pkg/gnolang"
)

func assertCharNotPlus(b byte) {
if b == '+' {
panic("numbers cannot start with +")
}
}

// These convert string representations of public-facing arguments to GNO types.
// The limited set of input types available should map 1:1 to types supported
// in FunctionSignature{}.
Expand All @@ -34,9 +41,7 @@ func convertArgToGno(arg string, argT gno.Type) (tv gno.TypedValue) {
tv.SetString(gno.StringValue(arg))
return
case gno.IntType:
if arg[0] == '+' {
panic("numbers cannot start with +")
}
assertCharNotPlus(arg[0])
i64, err := strconv.ParseInt(arg, 10, 64)
if err != nil {
panic(fmt.Sprintf(
Expand All @@ -46,9 +51,7 @@ func convertArgToGno(arg string, argT gno.Type) (tv gno.TypedValue) {
tv.SetInt(int(i64))
return
case gno.Int8Type:
if arg[0] == '+' {
panic("numbers cannot start with +")
}
assertCharNotPlus(arg[0])
i8, err := strconv.ParseInt(arg, 10, 8)
if err != nil {
panic(fmt.Sprintf(
Expand All @@ -58,9 +61,7 @@ func convertArgToGno(arg string, argT gno.Type) (tv gno.TypedValue) {
tv.SetInt8(int8(i8))
return
case gno.Int16Type:
if arg[0] == '+' {
panic("numbers cannot start with +")
}
assertCharNotPlus(arg[0])
i16, err := strconv.ParseInt(arg, 10, 16)
if err != nil {
panic(fmt.Sprintf(
Expand All @@ -70,9 +71,7 @@ func convertArgToGno(arg string, argT gno.Type) (tv gno.TypedValue) {
tv.SetInt16(int16(i16))
return
case gno.Int32Type:
if arg[0] == '+' {
panic("numbers cannot start with +")
}
assertCharNotPlus(arg[0])
i32, err := strconv.ParseInt(arg, 10, 32)
if err != nil {
panic(fmt.Sprintf(
Expand All @@ -82,9 +81,7 @@ func convertArgToGno(arg string, argT gno.Type) (tv gno.TypedValue) {
tv.SetInt32(int32(i32))
return
case gno.Int64Type:
if arg[0] == '+' {
panic("numbers cannot start with +")
}
assertCharNotPlus(arg[0])
i64, err := strconv.ParseInt(arg, 10, 64)
if err != nil {
panic(fmt.Sprintf(
Expand All @@ -94,9 +91,7 @@ func convertArgToGno(arg string, argT gno.Type) (tv gno.TypedValue) {
tv.SetInt64(i64)
return
case gno.UintType:
if arg[0] == '+' {
panic("numbers cannot start with +")
}
assertCharNotPlus(arg[0])
u64, err := strconv.ParseUint(arg, 10, 64)
if err != nil {
panic(fmt.Sprintf(
Expand All @@ -106,9 +101,7 @@ func convertArgToGno(arg string, argT gno.Type) (tv gno.TypedValue) {
tv.SetUint(uint(u64))
return
case gno.Uint8Type:
if arg[0] == '+' {
panic("numbers cannot start with +")
}
assertCharNotPlus(arg[0])
u8, err := strconv.ParseUint(arg, 10, 8)
if err != nil {
panic(fmt.Sprintf(
Expand All @@ -118,9 +111,7 @@ func convertArgToGno(arg string, argT gno.Type) (tv gno.TypedValue) {
tv.SetUint8(uint8(u8))
return
case gno.Uint16Type:
if arg[0] == '+' {
panic("numbers cannot start with +")
}
assertCharNotPlus(arg[0])
u16, err := strconv.ParseUint(arg, 10, 16)
if err != nil {
panic(fmt.Sprintf(
Expand All @@ -130,9 +121,7 @@ func convertArgToGno(arg string, argT gno.Type) (tv gno.TypedValue) {
tv.SetUint16(uint16(u16))
return
case gno.Uint32Type:
if arg[0] == '+' {
panic("numbers cannot start with +")
}
assertCharNotPlus(arg[0])
u32, err := strconv.ParseUint(arg, 10, 32)
if err != nil {
panic(fmt.Sprintf(
Expand All @@ -142,9 +131,7 @@ func convertArgToGno(arg string, argT gno.Type) (tv gno.TypedValue) {
tv.SetUint32(uint32(u32))
return
case gno.Uint64Type:
if arg[0] == '+' {
panic("numbers cannot start with +")
}
assertCharNotPlus(arg[0])
u64, err := strconv.ParseUint(arg, 10, 64)
if err != nil {
panic(fmt.Sprintf(
Expand All @@ -153,6 +140,14 @@ func convertArgToGno(arg string, argT gno.Type) (tv gno.TypedValue) {
}
tv.SetUint64(u64)
return
case gno.Float32Type:
value := convertFloat(arg, 32)
tv.SetFloat32(float32(value))
return
case gno.Float64Type:
value := convertFloat(arg, 64)
tv.SetFloat64(value)
return
default:
panic(fmt.Sprintf("unexpected primitive type %s", bt.String()))
}
Expand Down Expand Up @@ -195,3 +190,18 @@ func convertArgToGno(arg string, argT gno.Type) (tv gno.TypedValue) {
panic(fmt.Sprintf("unexpected type in contract arg: %v", argT))
}
}

func convertFloat(value string, precision int) float64 {
assertCharNotPlus(value[0])
dec, _, err := apd.NewFromString(value)
if err != nil {
panic(fmt.Sprintf("error parsing float%d %s: %v", precision, value, err))
}

f64, err := strconv.ParseFloat(dec.String(), precision)
if err != nil {
panic(fmt.Sprintf("error value exceeds float%d precision %s: %v", precision, value, err))
}

return f64
}

0 comments on commit 988ca91

Please sign in to comment.