1 {-# LANGUAGE AllowAmbiguousTypes #-}
2 {-# LANGUAGE PolyKinds #-}
3 {-# LANGUAGE TypeInType #-}
4 {-# LANGUAGE ViewPatterns #-}
5 {-# LANGUAGE UndecidableInstances #-}
6 {-# OPTIONS_GHC -fno-warn-orphans #-}
7 module Compiling.Test where
10 import Test.Tasty.HUnit
11 import Debug.Trace (trace)
13 import Control.Arrow (left)
14 import Data.Functor.Identity (Identity(..))
15 import Data.Proxy (Proxy(..))
16 import Data.Text (Text)
17 import Data.Type.Equality
18 import qualified Control.Monad.Classes as MC
19 import qualified Control.Monad.Classes.Run as MC
20 import qualified Control.Monad.Trans.State.Strict as SS
21 import qualified Data.List as List
22 import qualified Data.Text as Text
23 import qualified Text.Megaparsec as P
25 import Language.Symantic
26 import qualified Language.Symantic.Grammar as Gram
28 import Grammar.Megaparsec
32 -- P.ParsecT instances
34 type instance MC.CanDo (P.ParsecT e s m) eff = 'False
35 instance ParsecC e s => Gram_Name (P.ParsecT e s m)
36 -- instance ParsecC e s => Gram.Gram_Meta () (P.ParsecT e s m) where
37 -- withMeta = (($ ()) <$>)
40 , Gram.Gram_Source src (P.ParsecT e s m)
41 ) => Gram_Term_Type src (P.ParsecT e s m)
42 instance (ParsecC e s, Show err) => Gram.Gram_Error err (P.ParsecT e s m) where
46 Left err -> fail $ show err
50 , Gram.Gram_Source src (P.ParsecT e s m)
51 , Gram.Gram_Error Error_Term_Gram (P.ParsecT e s m)
52 , Gram_Term_Atoms src ss (P.ParsecT e s m)
53 , Gram_State (Imports, Modules src ss) (P.ParsecT e s m)
54 ) => Gram_Term src ss (P.ParsecT e s m)
59 Gram_Term src ss (P.ParsecT P.Dec Text (SS.StateT (Imports, Modules src ss) Identity)) =>
61 Either (P.ParseError Char P.Dec) (AST_Term src ss)
63 let mods :: Modules src ss = either (error . show) id inj_Modules in
64 let imps = importModulesAs [] mods in
66 MC.evalStateStrict (imps, mods) $
68 where g = Gram.unCF $ g_term <* Gram.eoi
73 , Gram_Term src ss (P.ParsecT P.Dec Text (SS.StateT (Imports, Modules src ss) Identity))
77 , Syms ss (BetaT View)
81 , Inj_Source (TypeVT src) src
82 , Inj_Source (TypeT src '[]) src
83 , Inj_Source (KindK src) src
84 , Inj_Source (AST_Type src) src
88 Either ( Type src '[] t
89 , Either (P.ParseError Char P.Dec)
91 (Type src '[] t, t, Text) ->
93 test_readTerm inp expected =
94 testCase (elide inp) $
95 case reduceTeApp <$> test_parseTerm @ss inp of
96 Left err -> Left (Left err) @?= snd `left` expected
98 let tys = inj_Name2Type (Proxy @ss) in
99 case readTerm tys CtxTyZ ast of
100 Left err -> Left (Right err) @?= snd `left` expected
103 TermVT (Term q t (TeSym te)) ->
105 Left (_, err) -> Right ("…"::Text) @?= Left err
106 Right (ty_expected::Type src '[] t, _::t, _::Text) ->
107 (>>= (@?= (\(_::Type src '[] t, err) -> err) `left` expected)) $
109 LenS{} -> return $ Left $ Right $ Error_Term_polymorphic (TypeVT t)
111 case proveConstraint q of
112 Nothing -> return $ Left $ Right $ Error_Term_qualified $ TypeVT t
114 case t `eqType` ty_expected of
115 Nothing -> return $ Left $ Right $
116 Error_Term_Beta $ Error_Beta_Unify $
117 Error_Unify_mismatch (TypeVT t) (TypeVT ty_expected)
119 return $ Right (t, eval $ te CtxTeZ, view $ betaT $ te CtxTeZ)
121 maybeRight :: Either l r -> Maybe r
122 maybeRight (Right r) = Just r
123 maybeRight Left{} = Nothing
125 elide :: Text -> String
126 elide s | Text.length s > 42 = List.take 42 (Text.unpack s) List.++ ['…']
127 elide s = Text.unpack s
129 dbg :: Show a => String -> a -> a
130 dbg msg x = trace (msg ++ " = " ++ Prelude.show x) x