1
0
mirror of https://github.com/robertkrimen/otto synced 2025-10-12 20:27:30 +08:00

Make parseInt behavior correspond to the 15.1.2.3 algorithm

This commit is contained in:
Robert Krimen 2013-04-29 17:29:08 +02:00
parent a6d6f26c01
commit 16030f4b6f
3 changed files with 39 additions and 11 deletions

View File

@ -123,13 +123,31 @@ func builtinGlobal_parseInt(call FunctionCall) Value {
return toValue(value)
}
var parseFloat_matchBadSpecial = regexp.MustCompile(`[\+\-]?(?:[Ii]nf$|infinity)`)
var parseFloat_matchValid = regexp.MustCompile(`[0-9eE\+\-\.]|Infinity`)
func builtinGlobal_parseFloat(call FunctionCall) Value {
// Caveat emptor: This implementation does NOT match the specification
string_ := strings.TrimSpace(toString(call.Argument(0)))
value, err := strconv.ParseFloat(string_, 64)
if err != nil {
input := strings.TrimSpace(toString(call.Argument(0)))
if parseFloat_matchBadSpecial.MatchString(input) {
return NaNValue()
}
value, err := strconv.ParseFloat(input, 64)
if err != nil {
for end := len(input); end > 0; end -= 1 {
input := input[0:end]
if !parseFloat_matchValid.MatchString(input) {
return NaNValue()
}
value, err = strconv.ParseFloat(input, 64)
if err == nil {
break
}
}
if err != nil {
return NaNValue()
}
}
return toValue(value)
}

View File

@ -703,7 +703,7 @@ func newContext() *_runtime {
"Infinity", positiveInfinityValue(),
"eval", -1, builtinGlobal_eval,
"parseInt", -2, builtinGlobal_parseInt,
"parseFloat", builtinGlobal_parseFloat,
"parseFloat", -1, builtinGlobal_parseFloat,
"isNaN", builtinGlobal_isNaN,
"isFinite", builtinGlobal_isFinite,
"decodeURI", builtinGlobal_decodeURI_decodeURIComponent,

View File

@ -118,7 +118,9 @@ func Test_parseInt(t *testing.T) {
test(`parseInt(" 11 ")`, "11")
test(`parseInt(" 11\n")`, "11")
test(`parseInt(" 11\n", 16)`, "17")
test(`parseInt("Xyzzy")`, "NaN")
test(`parseInt(" 0x11\n", 16)`, "17")
test(`parseInt("0x0aXyzzy", 16)`, "10")
test(`parseInt("0x1", 0)`, "1")
@ -126,6 +128,7 @@ func Test_parseInt(t *testing.T) {
// TODO
test(`parseInt("0x10000000000000000000", 16)`, "75557863725914323419136")
}
test(`parseInt.length === 2`, "true")
test(`parseInt.prototype === undefined`, "true")
}
@ -141,14 +144,21 @@ func Test_parseFloat(t *testing.T) {
test(`parseFloat(" 11 ")`, "11")
test(`parseFloat(" 11\n")`, "11")
test(`parseFloat(" 11\n", 16)`, "11")
test(`parseFloat("Xyzzy")`, "NaN")
test(`parseFloat("0x0a")`, "NaN")
test(`parseFloat("11.1")`, "11.1")
if false {
test(`parseFloat(" 0x11\n", 16)`, "17")
// TODO parseFloat should return 10 in this scenario
test(`parseFloat("0x0aXyzzy")`, "10")
}
test(`parseFloat("Xyzzy")`, "NaN")
test(`parseFloat(" 0x11\n", 16)`, "0")
test(`parseFloat("0x0a")`, "0")
test(`parseFloat("0x0aXyzzy")`, "0")
test(`parseFloat("Infinity")`, "Infinity")
test(`parseFloat("infinity")`, "NaN")
test(`parseFloat("0x")`, "0")
test(`parseFloat("11x")`, "11")
test(`parseFloat("Infinity1")`, "Infinity")
test(`parseFloat.length === 1`, "true")
test(`parseFloat.prototype === undefined`, "true")
}
func Test_encodeURI(t *testing.T) {