Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions pkg/strconv/pkg.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 32 additions & 0 deletions pkg/strconv/strconv.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ package strconv
import (
"math/big"
"strconv"
"cuelang.org/go/cue/literal"
"cuelang.org/go/internal"
)

// ParseBool returns the boolean value represented by the string.
Expand Down Expand Up @@ -65,6 +67,36 @@ func ParseFloat(s string, bitSize int) (float64, error) {
return strconv.ParseFloat(s, bitSize)
}

// ParseNum interprets s using the full CUE number literal syntax and returns
// the resulting value as an arbitrary-precision decimal. It accepts decimal
// and non-decimal bases, underscores as separators, fractional syntax, and
// the decimal or binary multiplier suffixes defined by CUE (for example "1Ki"
// and "10M").
//
// If s is not syntactically well-formed, ParseNum returns a *strconv.NumError
// with Err containing detailed syntax information. Semantic errors, such as a
// multiplier that cannot be represented, are reported in the same way.
func ParseNum(s string) (*internal.Decimal, error) {
var info literal.NumInfo
if err := literal.ParseNum(s, &info); err != nil {
return nil, &strconv.NumError{
Func: "ParseNum",
Num: s,
Err: err,
}
}

var dec internal.Decimal
if err := info.Decimal(&dec); err != nil {
return nil, &strconv.NumError{
Func: "ParseNum",
Num: s,
Err: err,
}
}
return &dec, nil
}

// IntSize is the size in bits of an int or uint value.
const IntSize = 64

Expand Down
18 changes: 18 additions & 0 deletions pkg/strconv/testdata/gen.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ t44: strconv.ParseUint("100", 16, 8) // hex overflow uint8
t45: strconv.ParseUint("invalid", 10, 8) // syntax error
t46: strconv.ParseUint("123", 10, -1) // negative bitSize error
t47: strconv.ParseUint("-1", 10, 8) // negative value error
// Test ParseNum
t48: strconv.ParseNum("123.456")
t49: strconv.ParseNum("0xFF")
t50: strconv.ParseNum("1Ki")
t51: strconv.ParseNum("-.5")
t52: strconv.ParseNum("1_")
t53: strconv.ParseNum("0xG")
-- out/strconv-v3 --
Errors:
t2: int 300 overflows byte in argument 1 in call to strconv.FormatFloat:
Expand Down Expand Up @@ -98,6 +105,10 @@ t46: error in call to strconv.ParseUint: strconv.ParseUint: parsing "123": value
./in.cue:51:6
t47: error in call to strconv.ParseUint: strconv.ParseUint: parsing "-1": value out of range:
./in.cue:52:6
t52: error in call to strconv.ParseNum: strconv.ParseNum: parsing "1_": illegal '_' in number:
./in.cue:58:6
t53: error in call to strconv.ParseNum: strconv.ParseNum: parsing "0xG": illegal hexadecimal number "0xG":
./in.cue:59:6

Result:
t1: "40"
Expand Down Expand Up @@ -150,6 +161,13 @@ t44: _|_ // t44: error in call to strconv.ParseUint: strconv.ParseUint: parsing
t45: _|_ // t45: error in call to strconv.ParseUint: strconv.ParseUint: parsing "invalid": invalid syntax
t46: _|_ // t46: error in call to strconv.ParseUint: strconv.ParseUint: parsing "123": value out of range
t47: _|_ // t47: error in call to strconv.ParseUint: strconv.ParseUint: parsing "-1": value out of range
// Test ParseNum
t48: 123.456
t49: 255
t50: 1024
t51: -0.5
t52: _|_ // t52: error in call to strconv.ParseNum: strconv.ParseNum: parsing "1_": illegal '_' in number
t53: _|_ // t53: error in call to strconv.ParseNum: strconv.ParseNum: parsing "0xG": illegal hexadecimal number "0xG"
-- diff/-out/strconv-v3<==>+out/strconv --
diff old new
--- old
Expand Down