@@ -15,6 +15,7 @@ import Prelude
1515import Control.Alt ((<|>))
1616
1717import Data.Array as A
18+ import Data.Char as Char
1819import Data.Foldable as F
1920import Data.HugeNum as HN
2021import Data.HugeInt as HI
@@ -23,11 +24,13 @@ import Data.Json.Extended.Signature.Core (EJsonF(..), EJsonMap(..))
2324import Data.List as L
2425import Data.Maybe as M
2526import Data.String as S
27+ import Data.Traversable (sequence )
2628import Data.Tuple as T
2729
2830import Text.Parsing.Parser as P
2931import Text.Parsing.Parser.Combinators as PC
3032import Text.Parsing.Parser.String as PS
33+ import Text.Parsing.Parser.Token as PT
3134
3235squares
3336 ∷ ∀ m a
@@ -64,11 +67,29 @@ commaSep p = do
6467 pure o
6568
6669stringInner ∷ ∀ m . Monad m ⇒ P.ParserT String m String
67- stringInner = A .many stringChar <#> S .fromCharArray
70+ stringInner = A .many charAtom <#> S .fromCharArray
6871 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
7293
7394quoted ∷ ∀ a m . Monad m ⇒ P.ParserT String m a → P.ParserT String m a
7495quoted = PC .between quote quote
@@ -185,10 +206,20 @@ parseHugeNum
185206 . Monad m
186207 ⇒ P.ParserT String m HN.HugeNum
187208parseHugeNum = 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
190217 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' ])
192223
193224parseScientific
194225 ∷ ∀ m
@@ -208,7 +239,7 @@ parseBooleanLiteral =
208239 ]
209240
210241parseDecimalLiteral ∷ ∀ m . Monad m ⇒ P.ParserT String m HN.HugeNum
211- parseDecimalLiteral = parseHugeNum <|> parseScientific
242+ parseDecimalLiteral = parseSigned ( parseHugeNum <|> parseScientific)
212243
213244parseHugeIntLiteral ∷ ∀ m . Monad m ⇒ P.ParserT String m HI.HugeInt
214245parseHugeIntLiteral = parseSigned (parseNat (HI .fromInt 10 ) HI .fromInt)
0 commit comments