1 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
2 {-# LANGUAGE UndecidableInstances #-}
3 {-# OPTIONS_GHC -fno-warn-orphans #-}
4 module Language.Symantic.Typing.Grammar where
6 import Control.Applicative (Applicative(..))
7 import Data.List (foldl1')
8 import Data.String (IsString(..))
9 import Data.Text (Text)
10 import qualified Data.Char as Char
12 import Language.Symantic.Grammar
13 import Language.Symantic.Typing.Variable
16 newtype NameTy = NameTy Text
17 deriving (Eq, Ord, Show)
18 instance IsString NameTy where
19 fromString = NameTy . fromString
21 -- ** Type 'NameConst'
22 type NameConst = NameTy
28 -- | /Abstract Syntax Tree/ of 'Token_Type'.
29 type AST_Type src = BinTree (Token_Type src) -- (EToken src '[Proxy K.Type])
31 -- ** Type 'Token_Type'
33 = Token_Type_Const (At src NameTy)
34 | Token_Type_Var (At src NameVar)
37 -- * Class 'Gram_Type'
38 -- | Read an 'AST_Type' from a textual source.
49 , Gram_Meta (Text_of_Source src) g
50 , Inj_Source (Text_of_Source src) src
51 ) => Gram_Type src g where
52 g_type :: CF g (AST_Type src)
53 g_type = rule "type" $ g_type_fun
54 g_type_fun :: CF g (AST_Type src)
55 g_type_fun = rule "type_fun" $
56 infixrG g_type_list (withSource $ op <$ symbol "->")
57 where op src = BinTree2 . BinTree2 (BinTree0 $ Token_Type_Const $ At src "(->)")
58 -- TODO: maybe not harcoding g_type_list and g_type_tuple2
59 g_type_list :: CF g (AST_Type src)
60 g_type_list = rule "type_list" $
61 withSource $ inside mk
62 (symbol "[") (optional g_type) (symbol "]")
63 (const <$> g_type_tuple2)
65 mk Nothing src = tok src
66 mk (Just a) src = BinTree2 (tok src) a
67 tok src = BinTree0 $ Token_Type_Const $ At src "[]"
68 g_type_tuple2 :: CF g (AST_Type src)
69 g_type_tuple2 = rule "type_tuple2" $
70 try (parens (infixrG (g_type) (withSource $ op <$ symbol ","))) <+> (g_type_app)
71 where op src = BinTree2 . BinTree2 (BinTree0 $ Token_Type_Const $ At src "(,)")
72 g_type_app :: CF g (AST_Type src)
73 g_type_app = rule "type_app" $
74 foldl1' BinTree2 <$> some (g_type_atom)
75 g_type_atom :: CF g (AST_Type src)
76 g_type_atom = rule "type_atom" $
77 try (parens g_type) <+>
81 g_type_name_const :: CF g (AST_Type src)
82 g_type_name_const = rule "type_name_const" $
84 (\n ns src -> BinTree0 $ Token_Type_Const $ At src $ fromString $ n:ns)
85 <$> unicat (Unicat Char.UppercaseLetter)
86 <*> many (choice $ unicat <$> [Unicat_Letter, Unicat_Number])
87 g_type_name_var :: CF g (AST_Type src)
88 g_type_name_var = rule "type_name_var" $
90 (\n ns src -> BinTree0 $ Token_Type_Var $ At src $ fromString $ n:ns)
91 <$> unicat (Unicat Char.LowercaseLetter)
92 <*> many (choice $ unicat <$> [Unicat_Letter, Unicat_Number])
93 g_type_symbol :: CF g (AST_Type src)
94 g_type_symbol = rule "type_symbol" $
95 withSource $ (mk <$>) $
96 parens $ many $ cf_of_Terminal $ choice g_ok `but` choice g_ko
98 mk s src = BinTree0 $ Token_Type_Const $ At src (fromString $ "(" ++ s ++ ")")
104 g_ko = char <$> ['(', ')', '`']
106 deriving instance Gram_Type src g => Gram_Type src (CF g)
107 instance Inj_Source (Text_of_Source src) src => Gram_Type src EBNF
108 instance Inj_Source (Text_of_Source src) src => Gram_Type src RuleEBNF
110 -- | List of the rules of 'Gram_Type'.
111 gram_type :: Gram_Type () g => [CF g (AST_Type ())]