strconv: change atof64 to return an error, if the parsed value is not a valid number (#13424)
parent
1c19573382
commit
7f29418c63
|
@ -511,12 +511,12 @@ pub fn (s string) i16() i16 {
|
|||
|
||||
// f32 returns the value of the string as f32 `'1.0'.f32() == f32(1)`.
|
||||
pub fn (s string) f32() f32 {
|
||||
return f32(strconv.atof64(s))
|
||||
return f32(strconv.atof64(s) or { 0 })
|
||||
}
|
||||
|
||||
// f64 returns the value of the string as f64 `'1.0'.f64() == f64(1)`.
|
||||
pub fn (s string) f64() f64 {
|
||||
return strconv.atof64(s)
|
||||
return strconv.atof64(s) or { 0 }
|
||||
}
|
||||
|
||||
// u8 returns the value of the string as u8 `'1'.u8() == u8(1)`.
|
||||
|
|
|
@ -104,6 +104,7 @@ pub const (
|
|||
parser_mzero = 2 // number is negative, module smaller
|
||||
parser_pinf = 3 // number is higher than +HUGE_VAL
|
||||
parser_minf = 4 // number is lower than -HUGE_VAL
|
||||
parser_invalid_number = 5 // invalid number, used for '#@%^' for example
|
||||
//
|
||||
// char constants
|
||||
// Note: Modify these if working with non-ASCII encoding
|
||||
|
@ -232,6 +233,9 @@ fn parser(s string) (int, PrepNumber) {
|
|||
result = strconv.parser_pzero
|
||||
}
|
||||
}
|
||||
if i == 0 && s.len > 0 {
|
||||
return strconv.parser_invalid_number, pn
|
||||
}
|
||||
return result, pn
|
||||
}
|
||||
|
||||
|
@ -403,9 +407,9 @@ fn converter(mut pn PrepNumber) u64 {
|
|||
// Public functions
|
||||
|
||||
// atof64 return a f64 from a string doing a parsing operation
|
||||
pub fn atof64(s string) f64 {
|
||||
pub fn atof64(s string) ?f64 {
|
||||
if s.len == 0 {
|
||||
return 0
|
||||
return error('expected a number found an empty string')
|
||||
}
|
||||
mut pn := PrepNumber{}
|
||||
mut res_parsing := 0
|
||||
|
@ -428,7 +432,9 @@ pub fn atof64(s string) f64 {
|
|||
strconv.parser_minf {
|
||||
res.u = strconv.double_minus_infinity
|
||||
}
|
||||
else {}
|
||||
else {
|
||||
return error('not a number')
|
||||
}
|
||||
}
|
||||
return unsafe { res.f }
|
||||
}
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
module strconv
|
||||
|
||||
// atof64 return a f64 from a string doing a parsing operation
|
||||
pub fn atof64(s string) f64 {
|
||||
pub fn atof64(s string) ?f64 {
|
||||
// TODO: handle parsing invalid numbers as close as possible to the pure V version
|
||||
// that may be slower, but more portable, and will guarantee that higher level code
|
||||
// works the same in the JS version, as well as in the C and Native versions.
|
||||
res := 0.0
|
||||
#res.val = Number(s.str)
|
||||
|
||||
|
|
|
@ -36,7 +36,8 @@ fn test_atof() {
|
|||
// check conversion case 1 string <=> string
|
||||
for c, x in src_num {
|
||||
// slow atof
|
||||
assert strconv.atof64(src_num_str[c]).strlong() == x.strlong()
|
||||
val := strconv.atof64(src_num_str[c]) or { panic(err) }
|
||||
assert val.strlong() == x.strlong()
|
||||
|
||||
// quick atof
|
||||
mut s1 := (strconv.atof_quick(src_num_str[c]).str())
|
||||
|
@ -56,7 +57,8 @@ fn test_atof() {
|
|||
// we don't test atof_quick beacuse we already know the rounding error
|
||||
for c, x in src_num_str {
|
||||
b := src_num[c].strlong()
|
||||
a1 := strconv.atof64(x).strlong()
|
||||
value := strconv.atof64(x) or { panic(err) }
|
||||
a1 := value.strlong()
|
||||
assert a1 == b
|
||||
}
|
||||
|
||||
|
@ -73,3 +75,18 @@ fn test_atof() {
|
|||
assert *ptr == u64(0x8000000000000000)
|
||||
println('DONE!')
|
||||
}
|
||||
|
||||
fn test_atof_errors() {
|
||||
if x := strconv.atof64('') {
|
||||
eprintln('> x: $x')
|
||||
assert false // strconv.atof64 should have failed
|
||||
} else {
|
||||
assert err.str() == 'expected a number found an empty string'
|
||||
}
|
||||
if x := strconv.atof64('####') {
|
||||
eprintln('> x: $x')
|
||||
assert false // strconv.atof64 should have failed
|
||||
} else {
|
||||
assert err.str() == 'not a number'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -191,7 +191,7 @@ pub fn (mut e Eval) expr(expr ast.Expr, expecting ast.Type) Object {
|
|||
}) // TODO: numbers larger than 2^63 (for u64)
|
||||
}
|
||||
ast.FloatLiteral {
|
||||
return f64(strconv.atof64(expr.val))
|
||||
return f64(strconv.atof64(expr.val) or { e.error(err.str()) })
|
||||
}
|
||||
ast.BoolLiteral {
|
||||
return expr.val
|
||||
|
|
Loading…
Reference in New Issue