{- -----------------------------------------------------------------------------
Copyright 2020-2021 Kevin P. Barry

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
----------------------------------------------------------------------------- -}

-- Author: Kevin P. Barry [ta0kira@gmail.com]

module Test.Pragma (tests) where

import Base.TrackedErrors
import Parser.Common
import Parser.Pragma
import Parser.TextParser
import Test.Common


tests :: [IO (TrackedErrors ())]
tests :: [IO (TrackedErrors ())]
tests = [
    String
-> TextParser [PragmaComment SourceContext]
-> ([PragmaComment SourceContext] -> Bool)
-> IO (TrackedErrors ())
forall a.
Show a =>
String -> TextParser a -> (a -> Bool) -> IO (TrackedErrors ())
checkParseMatch String
"$Comment[ \"this is a pragma with args\" ]$" ((PragmaComment SourceContext -> [PragmaComment SourceContext])
-> ParsecT
     CompilerMessage String Identity (PragmaComment SourceContext)
-> TextParser [PragmaComment SourceContext]
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 (PragmaComment SourceContext
-> [PragmaComment SourceContext] -> [PragmaComment SourceContext]
forall a. a -> [a] -> [a]
:[]) ParsecT
  CompilerMessage String Identity (PragmaComment SourceContext)
pragmaComment)
      (\[PragmaComment SourceContext]
e -> case [PragmaComment SourceContext]
e of
                  [PragmaComment [SourceContext]
_ String
"this is a pragma with args"] -> Bool
True
                  [PragmaComment SourceContext]
_ -> Bool
False),

    String
-> String
-> ParsecT
     CompilerMessage String Identity (PragmaComment SourceContext)
-> IO (TrackedErrors ())
forall a.
Show a =>
String -> String -> TextParser a -> IO (TrackedErrors ())
checkParseError String
"$Comment$" String
"requires arguments" ParsecT
  CompilerMessage String Identity (PragmaComment SourceContext)
pragmaComment
  ]

data PragmaComment c =
  PragmaComment {
    forall c. PragmaComment c -> [c]
pcContext :: [c],
    forall c. PragmaComment c -> String
pcComment :: String
  }
  deriving (Int -> PragmaComment c -> ShowS
[PragmaComment c] -> ShowS
PragmaComment c -> String
(Int -> PragmaComment c -> ShowS)
-> (PragmaComment c -> String)
-> ([PragmaComment c] -> ShowS)
-> Show (PragmaComment c)
forall c. Show c => Int -> PragmaComment c -> ShowS
forall c. Show c => [PragmaComment c] -> ShowS
forall c. Show c => PragmaComment c -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall c. Show c => Int -> PragmaComment c -> ShowS
showsPrec :: Int -> PragmaComment c -> ShowS
$cshow :: forall c. Show c => PragmaComment c -> String
show :: PragmaComment c -> String
$cshowList :: forall c. Show c => [PragmaComment c] -> ShowS
showList :: [PragmaComment c] -> ShowS
Show)

pragmaComment :: TextParser (PragmaComment SourceContext)
pragmaComment :: ParsecT
  CompilerMessage String Identity (PragmaComment SourceContext)
pragmaComment = String
-> Either
     (SourceContext -> PragmaComment SourceContext)
     (SourceContext
      -> ParsecT
           CompilerMessage String Identity (PragmaComment SourceContext))
-> ParsecT
     CompilerMessage String Identity (PragmaComment SourceContext)
forall a.
String
-> Either (SourceContext -> a) (SourceContext -> TextParser a)
-> TextParser a
autoPragma String
"Comment" (Either
   (SourceContext -> PragmaComment SourceContext)
   (SourceContext
    -> ParsecT
         CompilerMessage String Identity (PragmaComment SourceContext))
 -> ParsecT
      CompilerMessage String Identity (PragmaComment SourceContext))
-> Either
     (SourceContext -> PragmaComment SourceContext)
     (SourceContext
      -> ParsecT
           CompilerMessage String Identity (PragmaComment SourceContext))
-> ParsecT
     CompilerMessage String Identity (PragmaComment SourceContext)
forall a b. (a -> b) -> a -> b
$ (SourceContext
 -> ParsecT
      CompilerMessage String Identity (PragmaComment SourceContext))
-> Either
     (SourceContext -> PragmaComment SourceContext)
     (SourceContext
      -> ParsecT
           CompilerMessage String Identity (PragmaComment SourceContext))
forall a b. b -> Either a b
Right SourceContext
-> ParsecT
     CompilerMessage String Identity (PragmaComment SourceContext)
forall {c}.
c -> ParsecT CompilerMessage String Identity (PragmaComment c)
parseAt where
  parseAt :: c -> ParsecT CompilerMessage String Identity (PragmaComment c)
parseAt c
c = do
    String -> TextParser ()
string_ String
"\""
    String
ss <- ParsecT CompilerMessage String Identity Char
-> TextParser () -> ParsecT CompilerMessage String Identity String
forall (m :: * -> *) a end. MonadPlus m => m a -> m end -> m [a]
manyTill ParsecT CompilerMessage String Identity Char
stringChar (String -> TextParser ()
string_ String
"\"")
    TextParser ()
optionalSpace
    PragmaComment c
-> ParsecT CompilerMessage String Identity (PragmaComment c)
forall a. a -> ParsecT CompilerMessage String Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (PragmaComment c
 -> ParsecT CompilerMessage String Identity (PragmaComment c))
-> PragmaComment c
-> ParsecT CompilerMessage String Identity (PragmaComment c)
forall a b. (a -> b) -> a -> b
$ [c] -> String -> PragmaComment c
forall c. [c] -> String -> PragmaComment c
PragmaComment [c
c] String
ss