2 module Language.Symantic.Compiling.Read where
4 import Control.Arrow (left)
5 import qualified Data.Kind as K
7 import Language.Symantic.Grammar
8 import Language.Symantic.Typing
10 import Language.Symantic.Compiling.Term
11 import Language.Symantic.Compiling.Module
12 import Language.Symantic.Compiling.Beta
15 -- | Convenient type alias for 'readTerm' and related functions.
16 type ReadTerm src ss ts =
18 Inj_Source (TypeVT src) src =>
19 Inj_Source (KindK src) src =>
20 Inj_Source (AST_Type src) src =>
25 Either (Error_Term src) (TermVT src ss ts)
27 -- | Read a 'TermVT' from and 'AST_Term'.
28 readTerm :: forall src ss ts. ReadTerm src ss ts
29 readTerm n2t ctxTy ast = do
30 ts <- go ctxTy `traverse` ast
31 inj_Error `left` betaTerms ts
37 Either (Error_Term src) (TermVT src ss ts')
38 go _ts (Token_Term (TermAVT te)) = Right $ TermVT te
39 go _ts (Token_TermVT te) = Right $ liftTermVT te
40 go ts (Token_Term_Var _src name) = teVar name ts
41 go _ts (Token_Term_App _src) = Right $ TermVT teApp
42 go ts (Token_Term_Abst _src name_arg ast_ty_arg ast_body) = do
43 TypeVT ty_arg <- inj_Error `left` readType n2t ast_ty_arg
44 when_EqKind (inj_Kind @K.Type) (kindOf ty_arg) $ \Refl ->
45 case lenVars ty_arg of
46 LenS{} -> Left $ Error_Term_polymorphic $ TypeVT ty_arg
47 LenZ | (TypeK qa, TypeK ta) <- unQualTy ty_arg -> do
48 TermVT (Term qr tr (TeSym res)) <- readTerm n2t (CtxTyS name_arg ta ts) ast_body
49 let (qa', qr') = appendVars qa qr
50 let (ta', tr') = appendVars ta tr
52 case (proveConstraint qa', proveConstraint qr') of
53 -- NOTE: remove provable Constraints to keep those smaller.
54 (Just Dict, Just Dict) -> TermVT $
55 Term @_ @_ @_ @_ @(_ #> _) (noConstraintLen (lenVars tr')) (ta' ~> tr') $
56 TeSym $ \c -> lam $ \arg -> res (arg `CtxTeS` c)
57 (Just Dict, Nothing) -> TermVT $
58 Term @_ @_ @_ @_ @(_ #> _) qr' (ta' ~> tr') $
59 TeSym $ \c -> lam $ \arg -> res (arg `CtxTeS` c)
60 (Nothing, Just Dict) -> TermVT $
61 Term @_ @_ @_ @_ @(_ #> _) qa' (ta' ~> tr') $
62 TeSym $ \c -> lam $ \arg -> res (arg `CtxTeS` c)
63 (Nothing, Nothing) -> TermVT $
64 Term @_ @_ @_ @_ @(_ #> _) (qa' # qr') (ta' ~> tr') $
65 TeSym $ \c -> lam $ \arg -> res (arg `CtxTeS` c)
66 go ts (Token_Term_Let _src name ast_arg ast_body) = do
67 TermVT (Term qa ta (TeSym arg)) <- readTerm n2t ts ast_arg
69 LenS{} -> Left $ Error_Term_polymorphic $ TypeVT (qa #> ta)
71 TermVT (Term qr tr (TeSym res)) <- readTerm n2t (CtxTyS name ta ts) ast_body
72 let (qa', qr') = appendVars qa qr
73 let tr' = allocVarsL (lenVars ta) tr
75 case (proveConstraint qa', proveConstraint qr') of
76 -- NOTE: remove provable Constraints to keep those smaller.
77 (Just Dict, Just Dict) -> TermVT $
78 Term @_ @_ @_ @_ @(_ #> _) (noConstraintLen (lenVars tr')) tr' $
79 TeSym $ \c -> let_ (arg c) $ \a -> res (a `CtxTeS` c)
80 (Just Dict, Nothing) -> TermVT $
81 Term @_ @_ @_ @_ @(_ #> _) qr' tr' $
82 TeSym $ \c -> let_ (arg c) $ \a -> res (a `CtxTeS` c)
83 (Nothing, Just Dict) -> TermVT $
84 Term @_ @_ @_ @_ @(_ #> _) qa' tr' $
85 TeSym $ \c -> let_ (arg c) $ \a -> res (a `CtxTeS` c)
86 (Nothing, Nothing) -> TermVT $
87 Term @_ @_ @_ @_ @(_ #> _) (qa' # qr') tr' $
88 TeSym $ \c -> let_ (arg c) $ \a -> res (a `CtxTeS` c)
93 NameTe -> CtxTy src ts -> Either (Error_Term src) (TermVT src ss ts)
94 teVar name CtxTyZ = Left $ Error_Term_unknown name
95 teVar name (CtxTyS n ty _) | n == name =
96 Right $ TermVT $ Term @_ @_ @_ @_ @(_ #> _) noConstraint ty $
97 TeSym $ \(te `CtxTeS` _) -> te
98 teVar name (CtxTyS _n _typ ts') = do
99 TermVT (Term q t (TeSym te)) <- teVar @ss name ts'
100 Right $ TermVT $ Term @_ @_ @_ @_ @(_ #> _) q t $
101 TeSym $ \(_ `CtxTeS` ts) -> te ts
104 Source src => Constable (->) =>
105 Term src ss ts '[Proxy (a::K.Type), Proxy (b::K.Type)] ((a -> b) -> a -> b)
107 Term noConstraint ((a ~> b) ~> a ~> b) $
110 a :: Source src => Type src '[Proxy a, Proxy b] (a::K.Type)
112 b :: Source src => Type src '[Proxy a, Proxy b] (b::K.Type)
113 b = tyVar "b" $ VarS varZ
115 -- | Reduce number of 'Token_Term_App' in given 'AST_Term' by converting them into 'BinTree2'.
117 -- NOTE: 'Token_Term_App' exists only to handle unifix operators applied to arguments.
118 reduceTeApp :: AST_Term src ss -> AST_Term src ss
119 reduceTeApp (BinTree2 x y) =
120 case reduceTeApp x of
121 BinTree0 Token_Term_App{} `BinTree2` x' -> reduceTeApp x' `BinTree2` reduceTeApp y
122 _ -> reduceTeApp x `BinTree2` reduceTeApp y
123 reduceTeApp (BinTree0 (Token_Term_Abst src n ty te)) = BinTree0 $ Token_Term_Abst src n ty (reduceTeApp te)
124 reduceTeApp (BinTree0 (Token_Term_Let src n bo te)) = BinTree0 $ Token_Term_Let src n (reduceTeApp bo) (reduceTeApp te)
125 reduceTeApp x@BinTree0{} = x
127 -- ** Type 'ReadTermCF'
128 -- | Like 'ReadTerm', but 'CtxTe'-free.
130 -- Useful in 'readTermWithCtx' to help GHC's type solver, which
131 -- "Cannot instantiate unification variable with a type involving foralls".
132 data ReadTermCF src ss
134 { unReadTermCF :: forall ts. ReadTerm src ss ts }
136 -- | Like 'readTerm' but with given context, and no more.
140 Inj_Source (TypeVT src) src =>
141 Inj_Source (KindK src) src =>
142 Inj_Source (AST_Type src) src =>
144 f (NameTe, TermT src ss '[] '[]) ->
147 Either (Error_Term src) (TermVT src ss '[])
148 readTermWithCtx env =
149 readTermWithCtxClose $
150 readTermWithCtxPush env readTerm
152 -- | Like 'readTerm' but with given context.
153 readTermWithCtxPush ::
155 f (NameTe, TermT src ss '[] '[]) ->
156 (forall ts'. ReadTerm src ss ts') ->
158 readTermWithCtxPush env readTe =
160 (\t (ReadTermCF r) -> ReadTermCF $ readTermWithCtxPush1 t r)
161 (ReadTermCF readTe) env
163 -- | Like 'readTerm' but with given 'TermT' pushed onto 'CtxTy' and 'CtxTe'.
164 readTermWithCtxPush1 ::
165 (NameTe, TermT src ss '[] '[]) ->
166 (forall ts'. ReadTerm src ss ts') ->
168 readTermWithCtxPush1 (n, TermT (Term qn tn (TeSym te_n))) readTe n2t ctxTy ast = do
169 TermVT (Term q t (TeSym te)) <- readTe n2t (CtxTyS n (qn #> tn) ctxTy) ast
170 case proveConstraint qn of
171 Nothing -> Left $ Error_Term_proofless $ TypeVT qn
173 Right $ TermVT $ Term @_ @_ @_ @_ @(_ #> _) q t $ TeSym $ \c ->
174 let cte = qual qn $ te_n CtxTeZ in
177 -- | Close a 'ReadTerm' context.
178 readTermWithCtxClose ::
179 (forall ts'. ReadTerm src ss ts') ->
181 Inj_Source (TypeVT src) src =>
182 Inj_Source (KindK src) src =>
183 Inj_Source (AST_Type src) src =>
187 Either (Error_Term src) (TermVT src ss '[])
188 readTermWithCtxClose readTe n2t ast = readTe n2t CtxTyZ ast
190 -- * Type 'Error_Term'
192 = Error_Term_unknown NameTe
193 | Error_Term_polymorphic (TypeVT src)
194 | Error_Term_qualified (TypeVT src)
195 | Error_Term_proofless (TypeVT src)
196 | Error_Term_Type (Error_Type src)
197 | Error_Term_Beta (Error_Beta src)
198 {- Error_Term_Con_Type (Con_Type src ss) -}
199 {- Error_Term_Con_Kind (Con_Kind src) -}
201 instance Inj_Error (Error_Type src) (Error_Term src) where
202 inj_Error = Error_Term_Type
203 instance Inj_Error (Error_Beta src) (Error_Term src) where
204 inj_Error = Error_Term_Beta
205 instance Inj_Error (Con_Kind src) (Error_Term src) where
206 inj_Error = Error_Term_Type . inj_Error
209 -- | A 'Source' usable when using 'readTerm'.
212 | SrcTe_Input (Span inp)
213 | SrcTe_AST_Term (AST_Term (SrcTe inp ss) ss)
214 | SrcTe_AST_Type (AST_Type (SrcTe inp ss))
215 | SrcTe_Kind (KindK (SrcTe inp ss))
216 | SrcTe_Type (TypeVT (SrcTe inp ss))
220 type instance Source_Input (SrcTe inp ss) = inp
222 instance Source (SrcTe inp ss) where
223 noSource = SrcTe_Less
224 instance Inj_Source (Span inp) (SrcTe inp ss) where
225 inj_Source = SrcTe_Input
226 instance Inj_Source (AST_Term (SrcTe inp ss) ss) (SrcTe inp ss) where
227 inj_Source = SrcTe_AST_Term
228 instance Inj_Source (AST_Type (SrcTe inp ss)) (SrcTe inp ss) where
229 inj_Source = SrcTe_AST_Type
230 instance Inj_Source (KindK (SrcTe inp ss)) (SrcTe inp ss) where
231 inj_Source = SrcTe_Kind
232 instance Inj_Source (TypeVT (SrcTe inp ss)) (SrcTe inp ss) where
233 inj_Source = SrcTe_Type