@@ -15,6 +15,7 @@ import Prelude
15
15
import Control.Alt ((<|>))
16
16
17
17
import Data.Array as A
18
+ import Data.Char as Char
18
19
import Data.Foldable as F
19
20
import Data.HugeNum as HN
20
21
import Data.HugeInt as HI
@@ -23,11 +24,13 @@ import Data.Json.Extended.Signature.Core (EJsonF(..), EJsonMap(..))
23
24
import Data.List as L
24
25
import Data.Maybe as M
25
26
import Data.String as S
27
+ import Data.Traversable (sequence )
26
28
import Data.Tuple as T
27
29
28
30
import Text.Parsing.Parser as P
29
31
import Text.Parsing.Parser.Combinators as PC
30
32
import Text.Parsing.Parser.String as PS
33
+ import Text.Parsing.Parser.Token as PT
31
34
32
35
squares
33
36
∷ ∀ m a
@@ -64,11 +67,29 @@ commaSep p = do
64
67
pure o
65
68
66
69
stringInner ∷ ∀ m . Monad m ⇒ P.ParserT String m String
67
- stringInner = A .many stringChar <#> S .fromCharArray
70
+ stringInner = A .many charAtom <#> S .fromCharArray
68
71
where
69
- stringChar = PC .try stringEscape <|> stringLetter
70
- stringLetter = PS .satisfy (_ /= ' "' )
71
- stringEscape = PS .string " \\\" " $> ' "'
72
+ charAtom = PC .tryRethrow do
73
+ ch ← PS .anyChar
74
+ case ch of
75
+ ' "' → P .fail " Expected string character"
76
+ ' \\ ' → charEscape
77
+ _ → pure ch
78
+
79
+ charEscape = do
80
+ ch ← PS .anyChar
81
+ case ch of
82
+ ' t' → pure ' \t '
83
+ ' r' → pure ' \r '
84
+ ' n' → pure ' \n '
85
+ ' u' → hexEscape
86
+ _ → pure ch
87
+
88
+ hexEscape = do
89
+ hex ← S .fromCharArray <$> sequence (A .replicate 4 PT .hexDigit)
90
+ case Int .fromStringAs Int .hexadecimal hex of
91
+ M.Nothing → P .fail " Expected character escape sequence"
92
+ M.Just i → pure $ Char .fromCharCode i
72
93
73
94
quoted ∷ ∀ a m . Monad m ⇒ P.ParserT String m a → P.ParserT String m a
74
95
quoted = PC .between quote quote
@@ -185,10 +206,20 @@ parseHugeNum
185
206
. Monad m
186
207
⇒ P.ParserT String m HN.HugeNum
187
208
parseHugeNum = do
188
- chars ← A .many (PS .oneOf [' 0' ,' 1' ,' 2' ,' 3' ,' 4' ,' 5' ,' 6' ,' 7' ,' 8' ,' 9' ,' -' ,' .' ]) <#> S .fromCharArray
189
- case HN .fromString chars of
209
+ head ← parseDigits
210
+ _ ← PS .char ' .'
211
+ str ← PC .tryRethrow do
212
+ tail ← parseDigits
213
+ when (tail == " " ) do
214
+ P .fail " Expected decimal part"
215
+ pure (head <> " ." <> tail)
216
+ case HN .fromString str of
190
217
M.Just num → pure num
191
- M.Nothing → P .fail $ " Failed to parse decimal: " <> chars
218
+ M.Nothing → P .fail $ " Failed to parse decimal: " <> str
219
+ where
220
+ parseDigits =
221
+ S .fromCharArray
222
+ <$> A .many (PS .oneOf [' 0' ,' 1' ,' 2' ,' 3' ,' 4' ,' 5' ,' 6' ,' 7' ,' 8' ,' 9' ])
192
223
193
224
parseScientific
194
225
∷ ∀ m
@@ -208,7 +239,7 @@ parseBooleanLiteral =
208
239
]
209
240
210
241
parseDecimalLiteral ∷ ∀ m . Monad m ⇒ P.ParserT String m HN.HugeNum
211
- parseDecimalLiteral = parseHugeNum <|> parseScientific
242
+ parseDecimalLiteral = parseSigned ( parseHugeNum <|> parseScientific)
212
243
213
244
parseHugeIntLiteral ∷ ∀ m . Monad m ⇒ P.ParserT String m HI.HugeInt
214
245
parseHugeIntLiteral = parseSigned (parseNat (HI .fromInt 10 ) HI .fromInt)
0 commit comments