diff --git a/src/Text/Parsing/StringParser/CodePoints.purs b/src/Text/Parsing/StringParser/CodePoints.purs index 3a8a9d6..54dde1d 100644 --- a/src/Text/Parsing/StringParser/CodePoints.purs +++ b/src/Text/Parsing/StringParser/CodePoints.purs @@ -26,12 +26,13 @@ import Prelude import Control.Alt ((<|>)) import Data.Array ((..)) import Data.Array.NonEmpty as NEA -import Data.Char (toCharCode) +import Data.Char (fromCharCode, toCharCode) import Data.Either (Either(..)) +import Data.Enum (fromEnum) import Data.Foldable (class Foldable, foldMap, elem, notElem) import Data.Maybe (Maybe(..)) -import Data.String.CodePoints (drop, length, indexOf', stripPrefix) -import Data.String.CodeUnits (charAt, singleton) +import Data.String.CodePoints (codePointAt, drop, indexOf', length, stripPrefix) +import Data.String.CodeUnits (singleton) import Data.String.Pattern (Pattern(..)) import Data.String.Regex as Regex import Data.String.Regex.Flags (noFlags) @@ -48,9 +49,13 @@ eof = Parser \s -> -- | Match any character. anyChar :: Parser Char anyChar = Parser \{ str, pos } -> - case charAt pos str of - Just chr -> Right { result: chr, suffix: { str, pos: pos + 1 } } + case codePointAt pos str of + Just cp -> case toChar cp of + Just chr -> Right { result: chr, suffix: { str, pos: pos + 1 } } + Nothing -> Left { pos, error: ParseError $ "CodePoint " <> show cp <> " is not a character" } Nothing -> Left { pos, error: ParseError "Unexpected EOF" } + where + toChar = fromCharCode <<< fromEnum -- | Match any digit. anyDigit :: Parser Char diff --git a/test/CodePoints.purs b/test/CodePoints.purs index 2fb37d2..76c52d6 100644 --- a/test/CodePoints.purs +++ b/test/CodePoints.purs @@ -17,7 +17,7 @@ import Test.Assert (assert', assert) import Text.Parsing.StringParser (Parser, runParser, try) import Text.Parsing.StringParser.Combinators (many1, endBy1, sepBy1, optionMaybe, many, manyTill, many1Till, chainl, fix, between) import Text.Parsing.StringParser.Expr (Assoc(..), Operator(..), buildExprParser) -import Text.Parsing.StringParser.CodePoints (anyDigit, eof, string, anyChar, regex) +import Text.Parsing.StringParser.CodePoints (anyDigit, char, eof, string, anyChar, regex) parens :: forall a. Parser a -> Parser a parens = between (string "(") (string ")") @@ -97,3 +97,6 @@ testCodePoints = do assert $ canParse (many1Till (string "a") (string "and")) $ (fold <<< take 10000 $ repeat "a") <> "and" -- check correct order assert $ expectResult (NonEmptyList ('a' :| 'b':'c':Nil)) (many1Till anyChar (string "d")) "abcd" + assert $ expectResult "\x458CA" (string "\x458CA" <* char ']' <* eof ) "\x458CA]" + assert $ expectResult "\x458CA" (string "\x458CA" <* string ")" <* eof ) "\x458CA)" + assert $ expectResult '\xEEE2' (char '\xEEE2' <* eof ) "\xEEE2"