module Test.Parser (tests) where
import Control.Monad (when)
import Base.CompilerError
import Base.TrackedErrors
import Parser.Common
import Parser.TextParser
import Test.Common
tests :: [IO (TrackedErrors ())]
tests :: [IO (TrackedErrors ())]
tests = [
TextParser Char -> String -> Char -> IO (TrackedErrors ())
forall a.
(Eq a, Show a) =>
TextParser a -> String -> a -> IO (TrackedErrors ())
checkParsesAs TextParser Char
stringChar String
"\\'" Char
'\'',
TextParser Char -> String -> Char -> IO (TrackedErrors ())
forall a.
(Eq a, Show a) =>
TextParser a -> String -> a -> IO (TrackedErrors ())
checkParsesAs TextParser Char
stringChar String
"\\\"" Char
'"',
TextParser Char -> String -> Char -> IO (TrackedErrors ())
forall a.
(Eq a, Show a) =>
TextParser a -> String -> a -> IO (TrackedErrors ())
checkParsesAs TextParser Char
stringChar String
"\\?" Char
'?',
TextParser Char -> String -> Char -> IO (TrackedErrors ())
forall a.
(Eq a, Show a) =>
TextParser a -> String -> a -> IO (TrackedErrors ())
checkParsesAs TextParser Char
stringChar String
"\\\\" Char
'\\',
TextParser Char -> String -> Char -> IO (TrackedErrors ())
forall a.
(Eq a, Show a) =>
TextParser a -> String -> a -> IO (TrackedErrors ())
checkParsesAs TextParser Char
stringChar String
"\\a" Char
'\a',
TextParser Char -> String -> Char -> IO (TrackedErrors ())
forall a.
(Eq a, Show a) =>
TextParser a -> String -> a -> IO (TrackedErrors ())
checkParsesAs TextParser Char
stringChar String
"\\b" Char
'\b',
TextParser Char -> String -> Char -> IO (TrackedErrors ())
forall a.
(Eq a, Show a) =>
TextParser a -> String -> a -> IO (TrackedErrors ())
checkParsesAs TextParser Char
stringChar String
"\\f" Char
'\f',
TextParser Char -> String -> Char -> IO (TrackedErrors ())
forall a.
(Eq a, Show a) =>
TextParser a -> String -> a -> IO (TrackedErrors ())
checkParsesAs TextParser Char
stringChar String
"\\n" Char
'\n',
TextParser Char -> String -> Char -> IO (TrackedErrors ())
forall a.
(Eq a, Show a) =>
TextParser a -> String -> a -> IO (TrackedErrors ())
checkParsesAs TextParser Char
stringChar String
"\\r" Char
'\r',
TextParser Char -> String -> Char -> IO (TrackedErrors ())
forall a.
(Eq a, Show a) =>
TextParser a -> String -> a -> IO (TrackedErrors ())
checkParsesAs TextParser Char
stringChar String
"\\t" Char
'\t',
TextParser Char -> String -> Char -> IO (TrackedErrors ())
forall a.
(Eq a, Show a) =>
TextParser a -> String -> a -> IO (TrackedErrors ())
checkParsesAs TextParser Char
stringChar String
"\\v" Char
'\v',
TextParser Char -> String -> Char -> IO (TrackedErrors ())
forall a.
(Eq a, Show a) =>
TextParser a -> String -> a -> IO (TrackedErrors ())
checkParsesAs TextParser Char
stringChar String
"\n" Char
'\n',
TextParser Char -> String -> Char -> IO (TrackedErrors ())
forall a.
(Eq a, Show a) =>
TextParser a -> String -> a -> IO (TrackedErrors ())
checkParsesAs TextParser Char
stringChar String
"\\x0A" Char
'\n',
TextParser Char -> String -> Char -> IO (TrackedErrors ())
forall a.
(Eq a, Show a) =>
TextParser a -> String -> a -> IO (TrackedErrors ())
checkParsesAs TextParser Char
stringChar String
"\\012" Char
'\n',
TextParser Char -> String -> IO (TrackedErrors ())
forall a. Show a => TextParser a -> String -> IO (TrackedErrors ())
checkParseFail TextParser Char
stringChar String
"\"",
TextParser Char -> String -> IO (TrackedErrors ())
forall a. Show a => TextParser a -> String -> IO (TrackedErrors ())
checkParseFail TextParser Char
stringChar String
"\\q",
TextParser Char -> String -> IO (TrackedErrors ())
forall a. Show a => TextParser a -> String -> IO (TrackedErrors ())
checkParseFail TextParser Char
stringChar String
"\\00",
TextParser Char -> String -> IO (TrackedErrors ())
forall a. Show a => TextParser a -> String -> IO (TrackedErrors ())
checkParseFail TextParser Char
stringChar String
"\\x0",
TextParser String -> String -> String -> IO (TrackedErrors ())
forall a.
(Eq a, Show a) =>
TextParser a -> String -> a -> IO (TrackedErrors ())
checkParsesAs TextParser String
regexChar String
"\\\\" String
"\\\\",
TextParser String -> String -> String -> IO (TrackedErrors ())
forall a.
(Eq a, Show a) =>
TextParser a -> String -> a -> IO (TrackedErrors ())
checkParsesAs TextParser String
regexChar String
"\\n" String
"\\n",
TextParser String -> String -> String -> IO (TrackedErrors ())
forall a.
(Eq a, Show a) =>
TextParser a -> String -> a -> IO (TrackedErrors ())
checkParsesAs TextParser String
regexChar String
"\n" String
"\n",
TextParser String -> String -> String -> IO (TrackedErrors ())
forall a.
(Eq a, Show a) =>
TextParser a -> String -> a -> IO (TrackedErrors ())
checkParsesAs TextParser String
regexChar String
"\\\"" String
"\"",
TextParser String -> String -> IO (TrackedErrors ())
forall a. Show a => TextParser a -> String -> IO (TrackedErrors ())
checkParseFail TextParser String
regexChar String
"\"",
TextParser String -> String -> String -> IO (TrackedErrors ())
forall a.
(Eq a, Show a) =>
TextParser a -> String -> a -> IO (TrackedErrors ())
checkParsesAs (String -> TextParser ()
keyword String
"keyword" TextParser () -> TextParser String -> TextParser String
forall a b.
ParsecT CompilerMessage String Identity a
-> ParsecT CompilerMessage String Identity b
-> ParsecT CompilerMessage String Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TextParser Char -> TextParser String
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
some TextParser Char
ParsecT CompilerMessage String Identity (Token String)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m (Token s)
asciiChar) String
"keyword string" String
"string",
TextParser String -> String -> IO (TrackedErrors ())
forall a. Show a => TextParser a -> String -> IO (TrackedErrors ())
checkParseFail (String -> TextParser ()
keyword String
"keyword" TextParser () -> TextParser String -> TextParser String
forall a b.
ParsecT CompilerMessage String Identity a
-> ParsecT CompilerMessage String Identity b
-> ParsecT CompilerMessage String Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TextParser Char -> TextParser String
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
some TextParser Char
ParsecT CompilerMessage String Identity (Token String)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m (Token s)
asciiChar) String
"keywordstring",
TextParser String -> String -> IO (TrackedErrors ())
forall a. Show a => TextParser a -> String -> IO (TrackedErrors ())
checkParseFail (String -> TextParser ()
keyword String
"keyword" TextParser () -> TextParser String -> TextParser String
forall a b.
ParsecT CompilerMessage String Identity a
-> ParsecT CompilerMessage String Identity b
-> ParsecT CompilerMessage String Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TextParser Char -> TextParser String
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
some TextParser Char
ParsecT CompilerMessage String Identity (Token String)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m (Token s)
asciiChar) String
"keyword_string",
TextParser (Either String String)
-> String -> Either String String -> IO (TrackedErrors ())
forall a.
(Eq a, Show a) =>
TextParser a -> String -> a -> IO (TrackedErrors ())
checkParsesAs
(((String -> Either String String)
-> TextParser String -> TextParser (Either String String)
forall a b.
(a -> b)
-> ParsecT CompilerMessage String Identity a
-> ParsecT CompilerMessage String Identity b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> Either String String
forall a b. a -> Either a b
Left (TextParser String -> TextParser (Either String String))
-> TextParser String -> TextParser (Either String String)
forall a b. (a -> b) -> a -> b
$ String -> TextParser ()
keyword String
"keyword" TextParser () -> TextParser String -> TextParser String
forall a b.
ParsecT CompilerMessage String Identity a
-> ParsecT CompilerMessage String Identity b
-> ParsecT CompilerMessage String Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TextParser Char -> TextParser String
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
some TextParser Char
ParsecT CompilerMessage String Identity (Token String)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m (Token s)
asciiChar) TextParser (Either String String)
-> TextParser (Either String String)
-> TextParser (Either String String)
forall a.
ParsecT CompilerMessage String Identity a
-> ParsecT CompilerMessage String Identity a
-> ParsecT CompilerMessage String Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ((String -> Either String String)
-> TextParser String -> TextParser (Either String String)
forall a b.
(a -> b)
-> ParsecT CompilerMessage String Identity a
-> ParsecT CompilerMessage String Identity b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> Either String String
forall a b. b -> Either a b
Right (TextParser String -> TextParser (Either String String))
-> TextParser String -> TextParser (Either String String)
forall a b. (a -> b) -> a -> b
$ TextParser Char -> TextParser String
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
some TextParser Char
ParsecT CompilerMessage String Identity (Token String)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m (Token s)
asciiChar))
String
"keywordstring"
(String -> Either String String
forall a b. b -> Either a b
Right String
"keywordstring"),
TextParser String -> String -> String -> IO (TrackedErrors ())
forall a.
(Eq a, Show a) =>
TextParser a -> String -> a -> IO (TrackedErrors ())
checkParsesAs (String -> TextParser String
operator String
">>??!" TextParser String -> TextParser String -> TextParser String
forall a b.
ParsecT CompilerMessage String Identity a
-> ParsecT CompilerMessage String Identity b
-> ParsecT CompilerMessage String Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TextParser Char -> TextParser String
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
many TextParser Char
ParsecT CompilerMessage String Identity (Token String)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m (Token s)
asciiChar) String
">>??! !!" String
"!!",
TextParser String -> String -> IO (TrackedErrors ())
forall a. Show a => TextParser a -> String -> IO (TrackedErrors ())
checkParseFail (String -> TextParser String
operator String
">>??!" TextParser String -> TextParser String -> TextParser String
forall a b.
ParsecT CompilerMessage String Identity a
-> ParsecT CompilerMessage String Identity b
-> ParsecT CompilerMessage String Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TextParser Char -> TextParser String
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
many TextParser Char
ParsecT CompilerMessage String Identity (Token String)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m (Token s)
asciiChar) String
">>??!!!"
]
checkParsesAs :: (Eq a, Show a) => TextParser a -> String -> a -> IO (TrackedErrors ())
checkParsesAs :: forall a.
(Eq a, Show a) =>
TextParser a -> String -> a -> IO (TrackedErrors ())
checkParsesAs TextParser a
p String
s a
m = TrackedErrors () -> IO (TrackedErrors ())
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (TrackedErrors () -> IO (TrackedErrors ()))
-> TrackedErrors () -> IO (TrackedErrors ())
forall a b. (a -> b) -> a -> b
$ do
let parsed :: TrackedErrors a
parsed = TextParser a -> String -> String -> TrackedErrors a
forall a. TextParser a -> String -> String -> TrackedErrors a
readSingleWith TextParser a
p String
"(string)" String
s
TrackedErrors a -> TrackedErrors ()
forall {m :: * -> *} {a}.
ErrorContextM m =>
TrackedErrorsT Identity a -> m ()
check TrackedErrors a
parsed
a
e <- TrackedErrors a
parsed
Bool -> TrackedErrors () -> TrackedErrors ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (a
e a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= a
m) (TrackedErrors () -> TrackedErrors ())
-> TrackedErrors () -> TrackedErrors ()
forall a b. (a -> b) -> a -> b
$
String -> TrackedErrors ()
forall a. String -> TrackedErrorsT Identity a
forall (m :: * -> *) a. ErrorContextM m => String -> m a
compilerErrorM (String -> TrackedErrors ()) -> String -> TrackedErrors ()
forall a b. (a -> b) -> a -> b
$ String -> String
forall a. Show a => a -> String
show String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" does not parse as " String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
m String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
":\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
e
where
check :: TrackedErrorsT Identity a -> m ()
check TrackedErrorsT Identity a
c
| TrackedErrorsT Identity a -> Bool
forall (t :: (* -> *) -> * -> *) a.
(ErrorContextT t, ErrorContextM (t Identity)) =>
t Identity a -> Bool
isCompilerError TrackedErrorsT Identity a
c = String -> m ()
forall a. String -> m a
forall (m :: * -> *) a. ErrorContextM m => String -> m a
compilerErrorM (String -> m ()) -> String -> m ()
forall a b. (a -> b) -> a -> b
$ String
"Parse '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"':\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ CompilerMessage -> String
forall a. Show a => a -> String
show (TrackedErrorsT Identity a -> CompilerMessage
forall a. TrackedErrors a -> CompilerMessage
getCompilerError TrackedErrorsT Identity a
c)
| Bool
otherwise = () -> m ()
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
checkParseFail :: Show a => TextParser a -> String -> IO (TrackedErrors ())
checkParseFail :: forall a. Show a => TextParser a -> String -> IO (TrackedErrors ())
checkParseFail TextParser a
p String
s = do
let parsed :: TrackedErrors a
parsed = TextParser a -> String -> String -> TrackedErrors a
forall a. TextParser a -> String -> String -> TrackedErrors a
readSingleWith TextParser a
p String
"(string)" String
s
TrackedErrors () -> IO (TrackedErrors ())
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (TrackedErrors () -> IO (TrackedErrors ()))
-> TrackedErrors () -> IO (TrackedErrors ())
forall a b. (a -> b) -> a -> b
$ TrackedErrors a -> TrackedErrors ()
forall {m :: * -> *} {a}.
(ErrorContextM m, Show a) =>
TrackedErrorsT Identity a -> m ()
check TrackedErrors a
parsed
where
check :: TrackedErrorsT Identity a -> m ()
check TrackedErrorsT Identity a
c
| TrackedErrorsT Identity a -> Bool
forall (t :: (* -> *) -> * -> *) a.
(ErrorContextT t, ErrorContextM (t Identity)) =>
t Identity a -> Bool
isCompilerError TrackedErrorsT Identity a
c = () -> m ()
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise = String -> m ()
forall a. String -> m a
forall (m :: * -> *) a. ErrorContextM m => String -> m a
compilerErrorM (String -> m ()) -> String -> m ()
forall a b. (a -> b) -> a -> b
$ String
"Parse '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"': Expected failure but got\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++
a -> String
forall a. Show a => a -> String
show (TrackedErrorsT Identity a -> a
forall a. TrackedErrors a -> a
getCompilerSuccess TrackedErrorsT Identity a
c) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n"