1 {-# LANGUAGE AllowAmbiguousTypes #-}
2 {-# LANGUAGE ConstraintKinds #-}
3 {-# LANGUAGE ExistentialQuantification #-}
5 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
6 {-# LANGUAGE PolyKinds #-}
7 {-# LANGUAGE UndecidableInstances #-}
8 module Language.Symantic.Compiling.Module where
10 import Data.Bool (not)
11 import Data.Map.Strict (Map)
12 import Data.Maybe (fromMaybe)
13 import Data.Semigroup (Semigroup(..))
15 import Data.String (IsString(..))
16 import Prelude hiding (mod, not, any)
17 import qualified Data.Map.Strict as Map
19 import Language.Symantic.Grammar
20 import Language.Symantic.Typing
21 import Language.Symantic.Compiling.Term
23 -- * Class 'ModuleFor'
24 class ModuleFor src ss s where
25 moduleFor :: (PathMod, Module src ss)
26 moduleFor = ([], moduleEmpty)
28 importModules :: PathMod -> Modules src ss -> Imports NameTe
29 importModules as (Modules mods) =
30 Imports $ Map.singleton as $
32 (\pm (ByFixity mp mi mq) acc ->
36 , byPostfix = pm <$ mq
41 newtype Modules src ss
43 { modules :: Map PathMod (Module src ss)
46 unionModules :: Modules src ss -> Modules src ss -> Either Error_Module (Modules src ss)
47 unionModules mx@(Modules x) my@(Modules y) =
50 Nothing -> Right $ unionModulesUnchecked mx my
53 Map PathMod (Module src ss) ->
54 Map PathMod (Module src ss) ->
57 case Map.intersectionWith (,) x' y' of
58 xy | null xy -> Nothing
61 Map.filter (not . null) $
65 inter a b byPostfix in
68 e -> Just $ Error_Module_colliding_Term e
70 inter a b f = Map.keysSet $ Map.intersection (f a) (f b)
72 unionModulesUnchecked :: Modules src ss -> Modules src ss -> Modules src ss
73 unionModulesUnchecked (Modules x) (Modules y) =
74 Modules $ Map.unionWith (<>) x y
76 -- ** Type 'Error_Module'
78 = Error_Module_colliding_Term (Map PathMod (Set NameTe))
79 | Error_Module_ambiguous (Mod NameTe) (Map PathMod NameTe)
80 | Error_Module_missing PathMod
81 | Error_Module_missing_Term (Mod NameTe) -- FixyA
85 type Module src ss = ByFixity (ModuleFixy src ss Unifix)
86 (ModuleFixy src ss Infix)
87 (ModuleFixy src ss Unifix)
89 moduleEmpty :: Module src ss
90 moduleEmpty = ByFixity
96 moduleWhere :: forall src ss. Source src => PathMod -> [DefTerm src ss] -> (PathMod, Module src ss)
99 { byInfix = mk $ \(n `WithFixity` fixy := t) ->
101 Fixity2 inf -> [(n, Tokenizer inf $ Token_Term . setSource (TermAVT t))]
103 , byPrefix = mk $ \(n `WithFixity` fixy := t) ->
105 Fixity1 pre@Prefix{} -> [(n, Tokenizer pre $ Token_Term . setSource (TermAVT t))]
107 , byPostfix = mk $ \(n `WithFixity` fixy := t) ->
109 Fixity1 post@Postfix{} -> [(n, Tokenizer post $ Token_Term . setSource (TermAVT t))]
114 (DefTerm src ss -> [(NameTe, Tokenizer src ss fixy)]) ->
115 Map NameTe (Tokenizer src ss fixy)
116 mk = Map.fromList . (`foldMap` lst)
118 -- *** Type 'ModuleFixy'
119 type ModuleFixy src ss fixy = Map NameTe (Tokenizer src ss fixy)
121 -- ** Type 'Tokenizer'
122 data Tokenizer src ss fixy
124 { token_fixity :: fixy
125 , token_term :: src -> Token_Term src ss
127 instance (Source src, Eq fixy) => Eq (Tokenizer src ss fixy) where
128 Tokenizer fx x == Tokenizer fy y = fx == fy && (x noSource) == (y noSource)
129 instance Source src => Show (Tokenizer src ss fixy) where
130 show (Tokenizer _fx x) = show (x noSource)
132 -- ** Type 'AST_Term'
133 -- | /Abstract Syntax Tree/ of 'Token_Term'.
134 type AST_Term src ss = BinTree (Token_Term src ss)
136 -- ** Type 'Token_Term'
137 data Token_Term src ss
138 = Token_Term (TermAVT src ss)
139 | Token_TermVT (TermVT src ss '[])
140 | Token_Term_Abst src NameTe (AST_Type src) (AST_Term src ss)
141 | Token_Term_Var src NameTe
142 | Token_Term_Let src NameTe (AST_Term src ss) (AST_Term src ss)
144 -- deriving (Eq, Show)
145 instance Source src => Eq (Token_Term src ss) where
146 Token_Term x == Token_Term y = x == y
147 Token_TermVT x == Token_TermVT y = x == y
148 Token_Term_Abst _ nx ax rx == Token_Term_Abst _ ny ay ry = nx == ny && ax == ay && rx == ry
149 Token_Term_Var _ x == Token_Term_Var _ y = x == y
150 Token_Term_Let _ nx ax rx == Token_Term_Let _ ny ay ry = nx == ny && ax == ay && rx == ry
151 Token_Term_App _ == Token_Term_App _ = True
153 instance Source src => Show (Token_Term src ss) where
154 showsPrec p (Token_Term x) =
155 showParen (p >= 10) $
156 showString "Token_Term" .
157 showChar ' ' . showsPrec 10 x
158 showsPrec p (Token_TermVT x) =
159 showParen (p >= 10) $
160 showString "Token_TermVT" .
161 showChar ' ' . showsPrec 10 x
162 showsPrec p (Token_Term_Abst _ n a r) =
163 showParen (p >= 10) $
164 showString "Token_Term_Abst" .
165 showChar ' ' . showsPrec 10 n .
166 showChar ' ' . showsPrec 10 a .
167 showChar ' ' . showsPrec 10 r
168 showsPrec p (Token_Term_Var _ x) =
169 showParen (p >= 10) $
170 showString "Token_Term_Var" .
171 showChar ' ' . showsPrec 10 x
172 showsPrec p (Token_Term_Let _ n a r) =
173 showParen (p >= 10) $
174 showString "Token_Term_Let" .
175 showChar ' ' . showsPrec 10 n .
176 showChar ' ' . showsPrec 10 a .
177 showChar ' ' . showsPrec 10 r
178 showsPrec _p (Token_Term_App _) = showString "Token_Term_App"
181 newtype NameTe = NameTe Name
182 deriving (Eq, Ord, Show)
183 instance IsString NameTe where
184 fromString = NameTe . fromString
185 instance NameOf NameTe where
186 nameOf (NameTe n) = n
188 -- * Class 'ModulesInj'
189 type ModulesInj src ss
190 = ModulesInjR src ss ss
195 Either Error_Module (Modules src ss)
196 modulesInj = modulesInjR @_ @_ @ss
198 -- ** Class 'ModulesInjR'
199 class ModulesInjR src (ss::[*]) (rs::[*]) where
200 modulesInjR :: Either Error_Module (Modules src ss)
201 instance ModulesInjR src ss '[] where
202 modulesInjR = Right $ Modules mempty
205 , ModulesInjR src ss rs
206 ) => ModulesInjR src ss (Proxy s ': rs) where
208 x <- modulesInjR @_ @_ @rs
209 let (n, m) = moduleFor @_ @_ @s
210 Modules (Map.singleton n m) `unionModules` x
215 (:=) (WithFixity NameTe)
216 (forall ts. Term src ss ts vs t)
218 -- | Lookup given 'Mod' 'NameTe' into the 'Infix' 'TermDef' of given 'Modules'.
220 -- NOTE: 'Token_Term_App' is returned for the space 'NameTe'.
223 Fixy (ModuleFixy src ss Unifix)
224 (ModuleFixy src ss Infix)
225 (ModuleFixy src ss Unifix)
226 (ModuleFixy src ss fixy) ->
230 Either Error_Module (Tokenizer src ss fixy)
231 lookupDefTerm FixyInfix _is ([] `Mod` " ") _ms =
233 { token_term = Token_Term_App @src @ss
234 , token_fixity = Infix (Just AssocL) 9
236 lookupDefTerm fixy imps mn@(m `Mod` n) (Modules mods) =
237 let m' = m `fromMaybe` lookupImports fixy mn imps in
238 maybe (Left $ Error_Module_missing m') Right (Map.lookup m' mods) >>=
239 maybe (Left $ Error_Module_missing_Term mn) Right .
240 Map.lookup n . selectByFixity fixy
242 -- | Delete given 'Mod' 'NameTe' into given 'Modules'.
243 deleteDefTerm :: Mod NameTe -> Modules src ss -> Modules src ss
244 deleteDefTerm (m `Mod` n) (Modules ms) = Modules $ Map.adjust del m ms
246 { byPrefix = Map.delete n $ byPrefix mod
247 , byInfix = Map.delete n $ byInfix mod
248 , byPostfix = Map.delete n $ byPostfix mod
251 -- | Delete given 'Mod' 'NameTe' into 'byInfix's of given 'Modules'.
252 deleteDefTermInfix :: Mod NameTe -> Modules src ss -> Modules src ss
253 deleteDefTermInfix (m `Mod` n) (Modules ms) = Modules $ Map.adjust del m ms
254 where del mod = mod{byInfix = Map.delete n $ byInfix mod}
256 -- | Delete given 'Mod' 'NameTe' into 'byPrefix's of given 'Modules'.
257 deleteDefTermPrefix :: Mod NameTe -> Modules src ss -> Modules src ss
258 deleteDefTermPrefix (m `Mod` n) (Modules ms) = Modules $ Map.adjust del m ms
259 where del mod = mod{byPrefix = Map.delete n $ byPrefix mod}
261 -- | Delete given 'Mod' 'NameTe' into 'byPostfix's of given 'Modules'.
262 deleteDefTermPostix :: Mod NameTe -> Modules src ss -> Modules src ss
263 deleteDefTermPostix (m `Mod` n) (Modules ms) = Modules $ Map.adjust del m ms
264 where del mod = mod{byPostfix = Map.delete n $ byPostfix mod}
269 Mod (DefTerm src ss) -> Modules src ss -> Modules src ss
270 insertDefTerm (m `Mod` (n `WithFixity` fixy := t)) (Modules ms) =
271 Modules $ Map.insert m (insertFixity ins fixy moduleEmpty) ms
273 ins :: fx -> ModuleFixy src ss fx -> ModuleFixy src ss fx
274 ins fx = Map.insert n $ Tokenizer fx $ Token_Term . setSource (TermAVT t)
279 Mod (TermVT src ss '[]) -> NameTe -> Fixity ->
280 Modules src ss -> Modules src ss
281 insertTermVT (m `Mod` t) n fixy (Modules ms) =
282 Modules $ Map.insert m (insertFixity ins fixy moduleEmpty) ms
284 ins :: fx -> ModuleFixy src ss fx -> ModuleFixy src ss fx
285 ins fx = Map.insert n $ Tokenizer fx $ Token_TermVT . setSource t
288 (forall fx. fx -> ModuleFixy src ss fx -> ModuleFixy src ss fx) ->
289 Fixity -> Module src ss -> Module src ss
290 insertFixity ins fx mod =
292 Fixity1 uni@Prefix{} -> mod {byPrefix = ins uni $ byPrefix mod}
293 Fixity2 inf@Infix{} -> mod {byInfix = ins inf $ byInfix mod}
294 Fixity1 uni@Postfix{} -> mod {byPostfix = ins uni $ byPostfix mod}