summary refs log tree commit diff stats
path: root/lib/pure/parseutils.nim
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pure/parseutils.nim')
-rw-r--r--lib/pure/parseutils.nim158
1 files changed, 83 insertions, 75 deletions
diff --git a/lib/pure/parseutils.nim b/lib/pure/parseutils.nim
index 484ba5184..06ee07aa8 100644
--- a/lib/pure/parseutils.nim
+++ b/lib/pure/parseutils.nim
@@ -231,88 +231,96 @@ proc parseInt*(s: string, number: var int, start = 0): int {.
   else:
     number = int(res)
 
-proc tenToThePowerOf(b: int): BiggestFloat =
-  var b = b
-  var a = 10.0
-  result = 1.0
-  while true:
-    if (b and 1) == 1:
-      result *= a
-    b = b shr 1
-    if b == 0: break
-    a *= a
+when defined(nimParseBiggestFloatMagic):
+  proc parseBiggestFloat*(s: string, number: var BiggestFloat, start = 0): int {.
+    magic: "ParseBiggestFloat", importc: "nimParseBiggestFloat", noSideEffect.}
+    ## parses a float starting at `start` and stores the value into `number`.
+    ## Result is the number of processed chars or 0 if a parsing error
+    ## occurred.
+else:
+  proc tenToThePowerOf(b: int): BiggestFloat =
+    var b = b
+    var a = 10.0
+    result = 1.0
+    while true:
+      if (b and 1) == 1:
+        result *= a
+      b = b shr 1
+      if b == 0: break
+      a *= a
 
-proc parseBiggestFloat*(s: string, number: var BiggestFloat, start = 0): int {.
-  rtl, extern: "npuParseBiggestFloat", noSideEffect.} =
-  ## parses a float starting at `start` and stores the value into `number`.
-  ## Result is the number of processed chars or 0 if there occured a parsing
-  ## error.
-  var
-    esign = 1.0
-    sign = 1.0
-    i = start
-    exponent: int
-    flags: int
-  number = 0.0
-  if s[i] == '+': inc(i)
-  elif s[i] == '-':
-    sign = -1.0
-    inc(i)
-  if s[i] == 'N' or s[i] == 'n':
-    if s[i+1] == 'A' or s[i+1] == 'a':
-      if s[i+2] == 'N' or s[i+2] == 'n':
-        if s[i+3] notin IdentChars:
-          number = NaN
-          return i+3 - start
-    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 = Inf*sign
-          return i+3 - start
-    return 0
-  while s[i] in {'0'..'9'}:
-    # Read integer part
-    flags = flags or 1
-    number = number * 10.0 + toFloat(ord(s[i]) - ord('0'))
-    inc(i)
-    while s[i] == '_': inc(i)
-  # Decimal?
-  if s[i] == '.':
-    var hd = 1.0
-    inc(i)
-    while s[i] in {'0'..'9'}:
-      # Read fractional part
-      flags = flags or 2
-      number = number * 10.0 + toFloat(ord(s[i]) - ord('0'))
-      hd = hd * 10.0
-      inc(i)
-      while s[i] == '_': inc(i)
-    number = number / hd # this complicated way preserves precision
-  # Again, read integer and fractional part
-  if flags == 0: return 0
-  # Exponent?
-  if s[i] in {'e', 'E'}:
-    inc(i)
-    if s[i] == '+':
-      inc(i)
+  proc parseBiggestFloat*(s: string, number: var BiggestFloat, start = 0): int {.
+    rtl, extern: "npuParseBiggestFloat", noSideEffect.} =
+    ## parses a float starting at `start` and stores the value into `number`.
+    ## Result is the number of processed chars or 0 if there occured a parsing
+    ## error.
+    var
+      esign = 1.0
+      sign = 1.0
+      i = start
+      exponent: int
+      flags: int
+    number = 0.0
+    if s[i] == '+': inc(i)
     elif s[i] == '-':
-      esign = -1.0
+      sign = -1.0
       inc(i)
-    if s[i] notin {'0'..'9'}:
+    if s[i] == 'N' or s[i] == 'n':
+      if s[i+1] == 'A' or s[i+1] == 'a':
+        if s[i+2] == 'N' or s[i+2] == 'n':
+          if s[i+3] notin IdentChars:
+            number = NaN
+            return i+3 - start
+      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 = Inf*sign
+            return i+3 - start
       return 0
     while s[i] in {'0'..'9'}:
-      exponent = exponent * 10 + ord(s[i]) - ord('0')
+      # Read integer part
+      flags = flags or 1
+      number = number * 10.0 + toFloat(ord(s[i]) - ord('0'))
       inc(i)
       while s[i] == '_': inc(i)
-  # Calculate Exponent
-  let hd = tenToThePowerOf(exponent)
-  if esign > 0.0: number = number * hd
-  else:           number = number / hd
-  # evaluate sign
-  number = number * sign
-  result = i - start
+    # Decimal?
+    if s[i] == '.':
+      var hd = 1.0
+      inc(i)
+      while s[i] in {'0'..'9'}:
+        # Read fractional part
+        flags = flags or 2
+        number = number * 10.0 + toFloat(ord(s[i]) - ord('0'))
+        hd = hd * 10.0
+        inc(i)
+        while s[i] == '_': inc(i)
+      number = number / hd # this complicated way preserves precision
+    # Again, read integer and fractional part
+    if flags == 0: return 0
+    # Exponent?
+    if s[i] in {'e', 'E'}:
+      inc(i)
+      if s[i] == '+':
+        inc(i)
+      elif s[i] == '-':
+        esign = -1.0
+        inc(i)
+      if s[i] notin {'0'..'9'}:
+        return 0
+      while s[i] in {'0'..'9'}:
+        exponent = exponent * 10 + ord(s[i]) - ord('0')
+        inc(i)
+        while s[i] == '_': inc(i)
+    # Calculate Exponent
+    let hd = tenToThePowerOf(exponent)
+    if esign > 0.0: number = number * hd
+    else:           number = number / hd
+    # evaluate sign
+    number = number * sign
+    result = i - start
+
 
 proc parseFloat*(s: string, number: var float, start = 0): int {.
   rtl, extern: "npuParseFloat", noSideEffect.} =