Scanner.st
changeset 4596 9725321f7ec8
parent 4592 d14e38aec6de
child 4598 9733fe6a560f
--- a/Scanner.st	Sun Nov 17 15:34:11 2019 +0100
+++ b/Scanner.st	Tue Nov 26 00:50:09 2019 +0100
@@ -3175,7 +3175,8 @@
      support for single prec. floats with f/F is controlled by a parser flag"
 
     |pos1 nextChar value integerPart sign
-     expSign tokenRadix mantissaAndScaledPart d type exp scale|
+     expSign tokenRadix mantissaAndScaledPart d type exp scale 
+     kindChar kindClass chars|
 
     tokenRadix := 10.
     sign := 1.
@@ -3269,21 +3270,32 @@
     ].
 
     ('eEdDqQfF' includes:nextChar) ifTrue:[
-        (nextChar == $q or:[nextChar == $Q]) ifTrue:[
-            (nextChar == $Q) ifTrue:[
-                value := value asQuadFloat
+        kindClass := Float.
+        kindChar := nextChar.
+        nextChar := source nextPeek.
+        (kindChar == $q or:[kindChar == $Q]) ifTrue:[
+            (kindChar == $Q) ifTrue:[
+                nextChar == $D ifTrue:[
+                    kindClass := QDouble.
+                    value := value asQDouble.
+                    nextChar := source nextPeek.
+                ] ifFalse:[
+                    kindClass := QuadFloat.
+                    value := value asQuadFloat
+                ].
             ] ifFalse:[    
+                kindClass := LongFloat.
                 value := value asLongFloat
             ].
         ] ifFalse:[
-            ((nextChar == $f or:[nextChar == $F]) and:[parserFlags singlePrecisionFloatF]) ifTrue:[
+            ((kindChar == $f or:[kindChar == $F]) and:[parserFlags singlePrecisionFloatF]) ifTrue:[
+                kindClass := ShortFloat.
                 value := value asShortFloat
             ] ifFalse:[
                 value := value asFloat.
             ].
         ].
         type := #Float.
-        nextChar := source nextPeek.
         (nextChar notNil and:[(nextChar isDigit"Radix:tokenRadix") or:['+-' includes:nextChar]]) ifTrue:[
             expSign := 1.
             (nextChar == $+) ifTrue:[
@@ -3300,18 +3312,28 @@
             "/ are actually still in the float range.
             "/ happens eg. for 1.7976931348623157e+308
             nextChar := source peek.
-            value isInfinite ifTrue:[
-                PrimitiveFailure handle:[:ex |
+            "/ Also, the above raisedToInteger generates an additional error,
+            "/ which is not present, if we use the strtox functions from the C-library.
+            "/ Therefore, always use the low level fastFromString: converter
+            true "value isInfinite" ifTrue:[
+                Error handle:[:ex |
                     "/ self halt.
                 ] do:[
-                    value := Float fastFromString:source collection at:pos1.
+                    chars := (source collection copyFrom:pos1 to:source position) string asSingleByteStringIfPossible.
+                    value := kindClass fastFromString:chars at:1.
                 ].    
             ].    
         ].
     ] ifFalse:[
         value isLimitedPrecisionReal ifTrue:[
             "/ no type specified - makes it a float
-            value := value asFloat.
+            "/ value := value asFloat.
+            Error handle:[:ex |
+                value := value asFloat
+            ] do:[
+                chars := (source collection copyFrom:pos1 to:source position) asSingleByteStringIfPossible.
+                value := Float fastFromString:chars at:1.
+            ].
         ].
 
         parserFlags allowFixedPointLiterals == true ifTrue:[