1 {-# LANGUAGE UndecidableInstances #-}
2 {-# OPTIONS_GHC -fno-warn-orphans #-}
3 module Compiling.Term.Test where
6 import Test.Tasty.HUnit
8 import qualified Control.Arrow as Arrow
9 import qualified Control.Monad as Monad
10 import qualified Control.Monad.Classes as MC
11 import qualified Control.Monad.Classes.Run as MC
12 -- import Control.Monad.IO.Class (MonadIO(..))
13 import qualified Control.Monad.Trans.State.Strict as SS
14 import qualified Data.Foldable as Foldable
15 import Data.Functor.Identity (Identity(..))
16 import qualified Data.Map.Strict as Map
17 import Data.Proxy (Proxy(..))
18 import Data.Text (Text)
19 import Data.Type.Equality ((:~:)(Refl))
21 import qualified Text.Megaparsec as P
23 import Language.Symantic.Compiling
24 import Language.Symantic.Interpreting
25 import Language.Symantic.Parsing
26 import qualified Language.Symantic.Parsing.Grammar as Gram
27 import Language.Symantic.Typing
29 import Parsing.Grammar.Test
35 -- P.ParsecT instances
37 type instance MC.CanDo (P.ParsecT e s m) eff = 'False
38 instance ParsecC e s => Gram_Term_Name (P.ParsecT e s m)
39 instance ParsecC e s => Gram.Gram_Meta Meta (P.ParsecT e s m) where
40 metaG = (($ ()) Pre.<$>)
43 , Gram.Gram_Meta meta (P.ParsecT e s m)
44 ) => Gram_Term_Type meta (P.ParsecT e s m)
47 ) => Gram_Error (P.ParsecT e s m) where
48 term_unError (Gram.CF me) = Gram.CF $ do
51 Left err -> Monad.fail $ Pre.show err
52 Right a -> Monad.return a
55 , Gram.Gram_Meta meta (P.ParsecT e s m)
56 , MC.MonadState (Tokenizers meta ts) m
57 , Gram_Term_AtomsR meta ts ts (P.ParsecT e s m)
58 ) => Gram_Term ts meta (P.ParsecT e s m) where
59 term_tokenizers (Gram.CF ma) = Gram.CF $ do
61 toks :: Tokenizers meta ts <- MC.get
63 term_abst_args_body (Gram.CF args) (Gram.CF body) = Gram.CF $ do
66 toks :: Tokenizers meta ts <- MC.get
69 { tokenizers_prefix = del (tokenizers_prefix toks) as
70 , tokenizers_infix = del (tokenizers_infix toks) as
71 , tokenizers_postfix = del (tokenizers_postfix toks) as
73 body Pre.<* MC.put toks
75 where del = Foldable.foldr (\(n, _) -> Map.adjust (Map.delete n) [])
77 test_tokenizer :: forall is.
78 ( Inj_Tokens Meta is [Proxy (->), Proxy Integer]
79 , Gram_Term is Meta (P.ParsecT P.Dec String (SS.StateT (Tokenizers Meta is) Identity))
81 ) => String -> Either (P.ParseError Char P.Dec) (EToken Meta is)
84 MC.evalStateStrict (tokenizers::Tokenizers Meta is) $
86 Gram.unCF $ (termG Pre.<* Gram.eoi)
93 , Show_Const (Consts_of_Ifaces is)
95 , Sym_of_Ifaces is HostI
96 , Sym_of_Ifaces is TextI
98 , Inj_Tokens Meta is [Proxy (->), Proxy Integer]
99 , Gram_Term is Meta (P.ParsecT P.Dec String (SS.StateT (Tokenizers Meta is) Identity))
102 -> Either ( Type (Consts_of_Ifaces is) h
103 , Either (P.ParseError Char P.Dec)
104 (Error_Term Meta is) )
105 (Type (Consts_of_Ifaces is) h, h, Text)
107 test_compile inp expected =
108 testCase (elide inp) $
109 case test_tokenizer inp of
110 Left err -> Left (Left err) @?= Pre.snd `Arrow.left` expected
113 Left err -> Left (Right err) @?= Pre.snd `Arrow.left` expected
114 Right (ETerm typ (Term te)) ->
116 Left (_, err) -> Right ("…"::Text) @?= Left err
117 Right (ty_expected::Type (Consts_of_Ifaces is) h, _::h, _::Text) ->
118 (Monad.>>= (@?= (\(_::Type (Consts_of_Ifaces is) h, err) -> err) `Arrow.left` expected)) $
119 case typ `eq_type` ty_expected of
120 Nothing -> Monad.return $ Left $ Right $
121 Error_Term_Constraint_Type $ Right $
123 (Right $ At Nothing $ EType typ)
124 (At Nothing $ EType ty_expected)
126 let h = host_from_term te
132 -- , (text_from_term :: Repr_Text h -> Text) r
135 maybeRight :: Either l r -> Maybe r
136 maybeRight (Right r) = Just r
137 maybeRight Left{} = Nothing