mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-22 00:41:28 +00:00
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:
@@ -725,15 +725,20 @@ const
|
||||
IdentChars = {'a'..'z', 'A'..'Z', '0'..'9', '_'}
|
||||
|
||||
|
||||
proc parseFloatNative(a: string): float =
|
||||
let a2 = a.cstring
|
||||
proc parseFloatNative(a: openarray[char]): float =
|
||||
var str = ""
|
||||
for x in a:
|
||||
str.add x
|
||||
|
||||
let cstr = cstring str
|
||||
|
||||
asm """
|
||||
`result` = Number(`a2`);
|
||||
`result` = Number(`cstr`);
|
||||
"""
|
||||
|
||||
proc nimParseBiggestFloat(s: string, number: var BiggestFloat, start: int): int {.compilerproc.} =
|
||||
proc nimParseBiggestFloat(s: openarray[char], number: var BiggestFloat): int {.compilerproc.} =
|
||||
var sign: bool
|
||||
var i = start
|
||||
var i = 0
|
||||
if s[i] == '+': inc(i)
|
||||
elif s[i] == '-':
|
||||
sign = true
|
||||
@@ -743,14 +748,14 @@ proc nimParseBiggestFloat(s: string, number: var BiggestFloat, start: int): int
|
||||
if s[i+2] == 'N' or s[i+2] == 'n':
|
||||
if s[i+3] notin IdentChars:
|
||||
number = NaN
|
||||
return i+3 - start
|
||||
return i+3
|
||||
return 0
|
||||
if s[i] == 'I' or s[i] == 'i':
|
||||
if s[i+1] == 'N' or s[i+1] == 'n':
|
||||
if s[i+2] == 'F' or s[i+2] == 'f':
|
||||
if s[i+3] notin IdentChars:
|
||||
number = if sign: -Inf else: Inf
|
||||
return i+3 - start
|
||||
return i+3
|
||||
return 0
|
||||
|
||||
var buf: string
|
||||
@@ -782,7 +787,7 @@ proc nimParseBiggestFloat(s: string, number: var BiggestFloat, start: int): int
|
||||
addInc()
|
||||
eatUnderscores()
|
||||
number = parseFloatNative(buf)
|
||||
result = i - start
|
||||
result = i
|
||||
|
||||
# Workaround for IE, IE up to version 11 lacks 'Math.trunc'. We produce
|
||||
# 'Math.trunc' for Nim's ``div`` and ``mod`` operators:
|
||||
|
||||
@@ -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','+','-'}:
|
||||
|
||||
Reference in New Issue
Block a user