Added 'openArray[char]' overloads to 'std/parseutils' (#20527)

* Added 'openarray[char]' overloads to 'std/parseutils'

* Removed redundant `start` and `last` params from slice using procs

* Fixed type for parseIdent overload

* fixed one by off with 'substr'

* removed missed start parameters for procedures

* Added 'openarray[char]' overloads to 'std/parseutils'

* Removed redundant `start` and `last` params from slice using procs

* Fixed type for parseIdent overload

* fixed one by off with 'substr'

* removed missed start parameters for procedures

* Fixed VM op to work with new 'opcSlice'

* Corrected captureBetween's logic to work with openarray

* js sys's parsefloat logic now uses openarray

Co-authored-by: Clay Sweetser <Varriount@users.noreply.github.com>
This commit is contained in:
Jason Beetham 2022-10-24 12:50:54 -06:00 • committed by GitHub
commit ea0e45e62f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 550 additions and 162 deletions

View file

@ -78,8 +78,8 @@ const
when defined(nimHasInvariant):
{.push staticBoundChecks: off.}
proc nimParseBiggestFloat(s: string, number: var BiggestFloat,
start = 0): int {.compilerproc.} =
proc nimParseBiggestFloat(s: openArray[char], number: var BiggestFloat,
): int {.compilerproc.} =
# This routine attempt to parse float that can parsed quickly.
# i.e. whose integer part can fit inside a 53bits integer.
# their real exponent must also be <= 22. If the float doesn't follow
@ -88,7 +88,7 @@ proc nimParseBiggestFloat(s: string, number: var BiggestFloat,
# This avoid the problems of decimal character portability.
# see: http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/
var
i = start
i = 0
sign = 1.0
kdigits, fdigits = 0
exponent = 0
@ -111,7 +111,7 @@ proc nimParseBiggestFloat(s: string, number: var BiggestFloat,
if s[i+2] == 'N' or s[i+2] == 'n':
if i+3 >= s.len or s[i+3] notin IdentChars:
number = NaN
return i+3 - start
return i+3
return 0
# Inf?
@ -120,7 +120,7 @@ proc nimParseBiggestFloat(s: string, number: var BiggestFloat,
if s[i+2] == 'F' or s[i+2] == 'f':
if i+3 >= s.len or s[i+3] notin IdentChars:
number = Inf*sign
return i+3 - start
return i+3
return 0
if i < s.len and s[i] in {'0'..'9'}:
@ -154,8 +154,8 @@ proc nimParseBiggestFloat(s: string, number: var BiggestFloat,
# if has no digits: return error
if kdigits + fdigits <= 0 and
(i == start or # no char consumed (empty string).
(i == start + 1 and hasSign)): # or only '+' or '-
(i == 0 or # no char consumed (empty string).
(i == 1 and hasSign)): # or only '+' or '-
return 0
if i+1 < s.len and s[i] in {'e', 'E'}:
@ -182,7 +182,7 @@ proc nimParseBiggestFloat(s: string, number: var BiggestFloat,
number = 0.0*sign
else:
number = Inf*sign
return i - start
return i
# if integer is representable in 53 bits: fast path
# max fast path integer is 1<<53 - 1 or 8999999999999999 (16 digits)
@ -194,14 +194,14 @@ proc nimParseBiggestFloat(s: string, number: var BiggestFloat,
number = sign * integer.float / powtens[absExponent]
else:
number = sign * integer.float * powtens[absExponent]
return i - start
return i
# if exponent is greater try to fit extra exponent above 22 by multiplying
# integer part is there is space left.
let slop = 15 - kdigits - fdigits
if absExponent <= 22 + slop and not expNegative:
number = sign * integer.float * powtens[slop] * powtens[absExponent-slop]
return i - start
return i
# if failed: slow path with strtod.
var t: array[500, char] # flaviu says: 325 is the longest reasonable literal
@ -209,8 +209,8 @@ proc nimParseBiggestFloat(s: string, number: var BiggestFloat,
let maxlen = t.high - "e+000".len # reserve enough space for exponent
let endPos = i
result = endPos - start
i = start
result = endPos
i = 0
# re-parse without error checking, any error should be handled by the code above.
if i < endPos and s[i] == '.': i.inc
while i < endPos and s[i] in {'0'..'9','+','-'}: