1 {-# LANGUAGE AllowAmbiguousTypes #-}
2 {-# LANGUAGE PolyKinds #-}
3 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
4 {-# LANGUAGE UndecidableInstances #-}
5 {-# OPTIONS_GHC -fno-warn-orphans #-}
6 module Language.Symantic.Typing.Grammar where
8 import Control.Applicative (Applicative(..))
9 import Data.List (foldl1')
10 import Data.Proxy (Proxy(..))
11 import Data.Semigroup (Semigroup(..))
12 import Data.String (IsString(..))
13 import Prelude hiding (any)
14 import qualified Data.Char as Char
15 import qualified Data.Text as Text
16 import Data.Map.Strict (Map)
17 import qualified Data.Map.Strict as Map
19 import Language.Symantic.Grammar as G
20 import Language.Symantic.Typing.Kind
21 import Language.Symantic.Typing.Variable
22 import Language.Symantic.Typing.List
23 import Language.Symantic.Typing.Module
24 import Language.Symantic.Typing.Type
27 -- | /Abstract Syntax Tree/ of 'Token_Type'.
28 type AST_Type src = BinTree (Token_Type src)
30 -- ** Type 'Token_Type'
32 = Token_Type_Const (At src (Mod NameTy))
33 | Token_Type_Var (At src NameVar)
34 -- deriving (Eq, Show)
35 instance Source src => Eq (Token_Type src) where
36 Token_Type_Const (At _ x) == Token_Type_Const (At _ y) = x == y
37 Token_Type_Var (At _ x) == Token_Type_Var (At _ y) = x == y
39 instance Source src => Show (Token_Type src) where
40 showsPrec p (Token_Type_Const (At _ x)) =
42 showString "Token_Type_Const" .
43 showChar ' ' . showsPrec 10 x
44 showsPrec p (Token_Type_Var (At _ x)) =
46 showString "Token_Type_Var" .
47 showChar ' ' . showsPrec 10 x
50 type ModulesTy src = Map (Mod NameTy) (TypeTLen src)
53 -- | Like 'TypeT', but needing a @(@'Len'@ vs)@ to be built.
55 -- Useful to build a 'ModulesTy' which can be used
56 -- whatever will be the @(@'Len'@ vs)@ given to 'readTyVars'.
57 newtype TypeTLen src = TypeTLen (forall vs. Len vs -> TypeT src vs)
58 instance Source src => Eq (TypeTLen src) where
59 TypeTLen x == TypeTLen y = x LenZ == y LenZ
60 instance (Source src, Show (TypeT src '[])) => Show (TypeTLen src) where
61 showsPrec p (TypeTLen t) = showsPrec p $ t LenZ
63 -- ** Class 'ModulesTyInj'
64 -- | Derive a 'ModulesTy' from the given type-level list
65 -- of 'Proxy'-fied /type constants/.
66 class ModulesTyInj ts where
67 modulesTyInj :: Source src => ModulesTy src
68 instance ModulesTyInj '[] where
69 modulesTyInj = Map.empty
71 ( KindInjP (Ty_of_Type (K c))
72 , K c ~ Type_of_Ty (Ty_of_Type (K c))
75 ) => ModulesTyInj (Proxy c ': ts) where
79 (TypeTLen $ \len -> TypeT $ TyConst noSource len $
80 constKiInj @(K c) @c $
81 kindInjP @(Ty_of_Type (K c)) noSource) $
98 g_PathMod :: CF g PathMod
99 g_PathMod = rule "PathMod" $
104 g_NameMod :: CF g NameMod
105 g_NameMod = rule "NameMod" $
106 NameMod . Text.pack <$> identG
108 identG = (:) <$> headG <*> many (cfOf tailG)
109 headG = unicat $ Unicat Char.UppercaseLetter
110 tailG :: Terminal g Char
112 unicat Unicat_Letter <+>
115 deriving instance Gram_Mod g => Gram_Mod (CF g)
116 instance Gram_Mod EBNF
117 instance Gram_Mod RuleEBNF
119 -- * Class 'Gram_Type_Name'
132 ) => Gram_Type_Name g where
133 g_ModNameTy :: CF g (Mod NameTy)
134 g_ModNameTy = rule "ModNameTy" $
139 g_ModNameTyId :: CF g (Mod NameTy)
140 g_ModNameTyId = rule "ModNameTyId" $
142 <$> option [] (try $ g_PathMod <* char '.')
144 g_NameTyId :: CF g NameTy
145 g_NameTyId = rule "NameTyId" $
146 NameTy . Text.pack <$> identTyG
148 identTyG = (:) <$> headTyG <*> many (cfOf tailTyG)
149 headTyG = unicat $ Unicat Char.UppercaseLetter
150 tailTyG :: Terminal g Char
152 unicat Unicat_Letter <+>
155 g_ModNameTyOp :: CF g (Mod NameTy)
156 g_ModNameTyOp = rule "ModNameTyOp" $
158 <$> option [] (try $ g_PathMod <* char '.')
160 g_NameTyOp :: CF g NameTy
161 g_NameTyOp = rule "NameTyOp" $
162 NameTy . Text.pack <$> many (cfOf okG)
164 okG :: Terminal g Char
165 okG = choice (unicat <$>
170 koG = choice (char <$> ['(', ')', '`', '\'', '[', ']'])
172 deriving instance Gram_Type_Name g => Gram_Type_Name (CF g)
173 instance Gram_Type_Name EBNF
174 instance Gram_Type_Name RuleEBNF
176 -- * Class 'Gram_Type'
177 -- | Read an 'AST_Type' from a textual source.
193 ) => Gram_Type src g where
194 g_type :: CF g (AST_Type src)
195 g_type = rule "type" $ g_type_fun
196 g_type_fun :: CF g (AST_Type src)
197 g_type_fun = rule "type_fun" $
198 infixrG g_type_list (source $ op <$ symbol "->")
199 where op src = BinTree2 . BinTree2 (BinTree0 $ Token_Type_Const $ At src $ nameTyOf $ Proxy @(->))
200 -- TODO: maybe not harcoding g_type_list and g_type_tuple2
201 g_type_list :: CF g (AST_Type src)
202 g_type_list = rule "type_list" $
204 (symbol "[") (optional g_type) (symbol "]")
205 (const <$> g_type_tuple2)
207 mk Nothing src = tok src
208 mk (Just a) src = BinTree2 (tok src) a
209 tok src = BinTree0 $ Token_Type_Const $ At src $ nameTyOf $ Proxy @[]
210 g_type_tuple2 :: CF g (AST_Type src)
211 g_type_tuple2 = rule "type_tuple2" $
212 try (parens (infixrG (g_type) (source $ op <$ symbol ","))) <+> (g_type_app)
213 where op src = BinTree2 . BinTree2 (BinTree0 $ Token_Type_Const $ At src $ nameTyOf $ Proxy @(,))
214 g_type_app :: CF g (AST_Type src)
215 g_type_app = rule "type_app" $
216 foldl1' BinTree2 <$> some (g_type_atom)
217 g_type_atom :: CF g (AST_Type src)
218 g_type_atom = rule "type_atom" $
219 try (parens g_type) <+>
220 g_type_name_const <+>
223 g_type_name_const :: CF g (AST_Type src)
224 g_type_name_const = rule "type_name_const" $
226 (\n src -> BinTree0 $ Token_Type_Const $ At src n)
228 -- <$> unicat (Unicat Char.UppercaseLetter)
229 -- <*> many (choice $ unicat <$> [Unicat_Letter, Unicat_Number])
230 g_type_name_var :: CF g (AST_Type src)
231 g_type_name_var = rule "type_name_var" $
233 (\n ns src -> BinTree0 $ Token_Type_Var $ At src $ fromString $ n:ns)
234 <$> unicat (Unicat Char.LowercaseLetter)
235 <*> many (choice $ unicat <$> [Unicat_Letter, Unicat_Number])
237 g_type_symbol :: CF g (AST_Type src)
238 g_type_symbol = rule "type_symbol" $
240 parens $ many $ cfOf $ choice g_ok `but` choice g_ko
242 mk s src = BinTree0 $ Token_Type_Const $ At src $ Mod [] $ fromString $ "(" ++ s ++ ")"
248 g_ko = char <$> ['(', ')', '`']
251 deriving instance Gram_Type src g => Gram_Type src (CF g)
253 ( Gram_Source src EBNF
257 ) => Gram_Type src EBNF
259 ( Gram_Source src RuleEBNF
263 ) => Gram_Type src RuleEBNF
265 -- | List of the rules of 'Gram_Type'.
266 gram_type :: Gram_Type () g => [CF g (AST_Type ())]