@@ -22,19 +22,20 @@ import Prelude
22
22
23
23
import Data.Array (elem , notElem )
24
24
import Data.CodePoint.Unicode (isAlpha , isAlphaNum , isDecDigit , isHexDigit , isLower , isOctDigit , isSpace , isUpper )
25
- import Data.Either (Either (..))
25
+ import Data.Either (Either (..), either )
26
26
import Data.Int as Data.Int
27
27
import Data.Maybe (Maybe (..))
28
28
import Data.Number (infinity , nan )
29
29
import Data.Number as Data.Number
30
30
import Data.String (CodePoint , singleton , takeWhile )
31
31
import Data.String.CodePoints (codePointFromChar )
32
32
import Data.String.CodeUnits as SCU
33
- import Data.Tuple (Tuple (..), fst )
33
+ import Data.Tuple (fst )
34
34
import Parsing (ParserT , fail )
35
- import Parsing.Combinators (choice , skipMany , (<?>), (<~?>))
36
- import Parsing.String (consumeWith , match , satisfy , satisfyCodePoint )
35
+ import Parsing.Combinators (choice , tryRethrow , (<?>), (<| >), (<~?>))
36
+ import Parsing.String (consumeWith , match , regex , satisfy , satisfyCodePoint )
37
37
import Parsing.String as Parser.String
38
+ import Partial.Unsafe (unsafeCrashWith )
38
39
39
40
-- | Parse a digit. Matches any char that satisfies `Data.CodePoint.Unicode.isDecDigit`.
40
41
digit :: forall m . ParserT String m Char
@@ -84,26 +85,24 @@ alphaNum = satisfyCP isAlphaNum <?> "letter or digit"
84
85
-- | * `"NaN"`
85
86
-- | * `"-Infinity"`
86
87
number :: forall m . ParserT String m Number
87
- -- TODO because the JavaScript parseFloat function will successfully parse
88
- -- a Number up until it doesn't understand something and then return
89
- -- the partially parsed Number, this parser will sometimes consume more
90
- -- String that it actually parses. Example "1..3" will parse as 1.0.
91
- -- So this needs improvement.
92
88
number =
93
89
choice
94
- [ Parser.String .string " Infinity" *> pure infinity
95
- , Parser.String .string " +Infinity" *> pure infinity
96
- , Parser.String .string " -Infinity" *> pure (negate infinity)
97
- , Parser.String .string " NaN" *> pure nan
98
- , do
99
- Tuple section _ <- Parser.String .match do
100
- _ <- oneOf [ ' +' , ' -' , ' .' , ' 0' , ' 1' , ' 2' , ' 3' , ' 4' , ' 5' , ' 6' , ' 7' , ' 8' , ' 9' ]
101
- skipMany $ oneOf [ ' e' , ' E' , ' +' , ' -' , ' .' , ' 0' , ' 1' , ' 2' , ' 3' , ' 4' , ' 5' , ' 6' , ' 7' , ' 8' , ' 9' ]
90
+ [ tryRethrow do
91
+ section <- numberRegex
102
92
-- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseFloat
103
93
case Data.Number .fromString section of
104
- Nothing -> fail $ " Could not parse Number " <> section
94
+ Nothing -> fail $ " Bug in number parser "
105
95
Just x -> pure x
106
- ]
96
+ , Parser.String .string " Infinity" *> pure infinity
97
+ , Parser.String .string " +Infinity" *> pure infinity
98
+ , Parser.String .string " -Infinity" *> pure (negate infinity)
99
+ , Parser.String .string " NaN" *> pure nan
100
+ ] <|> fail " Expected Number"
101
+
102
+ numberRegex :: forall m . ParserT String m String
103
+ numberRegex = either (\errm -> unsafeCrashWith errm) identity $ regex pattern mempty
104
+ where
105
+ pattern = " [+-]?[0-9]*(\\ .[0-9]*)?([eE][+-]?[0-9]*(\\ .[0-9]*))?"
107
106
108
107
-- | Parser based on the __Data.Int.fromString__ function.
109
108
-- |
@@ -114,14 +113,17 @@ number =
114
113
-- | * `"-3"`
115
114
-- | * `"+300"`
116
115
intDecimal :: forall m . ParserT String m Int
117
- intDecimal = do
118
- Tuple section _ <- Parser.String .match do
119
- _ <- oneOf [ ' +' , ' -' , ' 0' , ' 1' , ' 2' , ' 3' , ' 4' , ' 5' , ' 6' , ' 7' , ' 8' , ' 9' ]
120
- skipMany $ oneOf [ ' 0' , ' 1' , ' 2' , ' 3' , ' 4' , ' 5' , ' 6' , ' 7' , ' 8' , ' 9' ]
116
+ intDecimal = tryRethrow do
117
+ section <- intDecimalRegex <|> fail " Expected Int"
121
118
case Data.Int .fromString section of
122
- Nothing -> fail $ " Could not parse Int " <> section
119
+ Nothing -> fail $ " Bug in intDecimal parser "
123
120
Just x -> pure x
124
121
122
+ intDecimalRegex :: forall m . ParserT String m String
123
+ intDecimalRegex = either (\errm -> unsafeCrashWith errm) identity $ regex pattern mempty
124
+ where
125
+ pattern = " [+-]?[0-9]*"
126
+
125
127
-- | Helper function
126
128
satisfyCP :: forall m . (CodePoint -> Boolean ) -> ParserT String m Char
127
129
satisfyCP p = Parser.String .satisfy (p <<< codePointFromChar)
0 commit comments