2 | import Control.Monad.Identity
3 | import Control.Monad.Trans
8 | import Data.String.Parser
15 | commaSep1' : Monad m => ParseT m a -> ParseT m (List1 a)
16 | commaSep1' p = p `sepBy1` (token ",")
19 | blockCommentChunk : Parser String
21 | blockComment <|> characters <|> character <|> endOfLine
23 | characters : Parser String
24 | characters = (takeWhile1 predicate)
26 | predicate : Char -> Bool
28 | '\x20' <= c && c <= '\x10FFFF' && c /= '-' && c /= '{'
32 | character : Parser String
33 | character = do x <- satisfy predicate
36 | predicate : Char -> Bool
37 | predicate c = '\x20' <= c && c <= '\x10FFFF' || c == '\n' || c == '\t'
39 | endOfLine : Parser String
40 | endOfLine = (string "\r\n" <?> "newline")
42 | blockCommentContinue : Parser String
43 | blockCommentContinue = endOfComment <|> continue
45 | endOfComment : Parser String
46 | endOfComment = token "-}" *> pure ""
48 | continue : Parser String
50 | c <- blockCommentChunk
51 | c' <- blockCommentContinue
55 | blockComment : Parser String
58 | c <- blockCommentContinue
62 | lineComment : Parser String
63 | lineComment = token "--" *> takeWhile (\c => c /= '\n') <* token "\n"
66 | whitespace : Parser ()
67 | whitespace = skip blockComment <|> skip (some lineComment) <|> spaces
70 | hexNumber : Parser Int
71 | hexNumber = choice (the (List (Lazy (Parser Int))) [ hexDigit, hexUpper, hexLower ])
73 | hexDigit : Parser Int
75 | c <- satisfy (\c => '0' <= c && c <= '9')
76 | pure (ord c - ord '0')
77 | hexUpper : Parser Int
79 | c <- satisfy (\c => 'A' <= c && c <= 'F')
80 | pure (10 + ord c - ord 'A')
81 | hexLower : Parser Int
83 | c <- satisfy (\c => 'a' <= c && c <= 'f')
84 | pure (10 + ord c - ord 'a')
88 | isSurrogate : Int -> Bool
90 | ((0xD800 <= x) && (x <= 0xDBFF))
91 | || ((0xDC00 <= x) && (x <= 0xDFFF))
103 | validCodepoint : Int -> Bool
104 | validCodepoint c = not (isSurrogate c
110 | unicode : Parser Char
113 | n <- bracedEscapeSequence <|> fourCharacterEscapeSequence
116 | toNumber : List Int -> Int
117 | toNumber = foldl (\x,y => x * 16 + y) 0
118 | vectToList : Vect m a -> List a
120 | vectToList (y :: xs) = y :: toList xs
121 | fourCharacterEscapeSequence : Parser Int
122 | fourCharacterEscapeSequence = do
123 | ns <- ntimes 4 hexNumber
124 | guard (validCodepoint (toNumber (vectToList ns)))
125 | <|> fail "Invalid Unicode code point"
126 | pure (toNumber (vectToList ns))
127 | bracedEscapeSequence : Parser Int
128 | bracedEscapeSequence = do
130 | ns <- some hexNumber
131 | guard (validCodepoint (toNumber ns)
132 | && (toNumber ns) <= 0x10fffd)
133 | <|> fail "Invalid Unicode code point"