1 {-# LANGUAGE AllowAmbiguousTypes #-}
2 {-# LANGUAGE ConstraintKinds #-}
3 {-# LANGUAGE DataKinds #-}
4 {-# LANGUAGE EmptyDataDeriving #-}
5 {-# LANGUAGE PolyKinds #-}
6 {-# LANGUAGE QuantifiedConstraints #-}
7 {-# LANGUAGE RankNTypes #-}
8 {-# LANGUAGE UndecidableInstances #-}
9 {-# LANGUAGE UndecidableSuperClasses #-}
10 {-# LANGUAGE ViewPatterns #-}
11 {-# LANGUAGE NoMonomorphismRestriction #-}
12 {-# OPTIONS_GHC -Wno-missing-signatures #-}
13 {-# OPTIONS_GHC -Wno-orphans #-}
15 -- {-# OPTIONS_GHC -Wno-monomorphism-restriction #-}
17 module Symantic.Syntaxes where
19 import Control.Arrow (left)
20 import Data.Either (Either (..))
21 import Data.Eq (Eq (..))
22 import Data.Function (fix, ($), (.))
24 import Data.Kind (Type)
25 import Data.Maybe (Maybe (..))
26 import Data.Monoid (Monoid (..))
27 import Data.Void (Void)
28 import Symantic.Semantics.Forall (Forall (..), PerSyntax, PerSyntaxable (..))
29 import Symantic.Syntaxes.Classes (Instantiable (..), Syntaxes, Unabstractable)
30 import Symantic.Syntaxes.Classes qualified as Sym
31 import Text.Show (Show (..))
32 import Type.Reflection (eqTypeRep, typeRep, (:~~:) (..))
33 import Prelude (error)
36 import Symantic.Typer ()
39 forall syns prov finalSyns.
40 finalSyns ~ (Instantiable ': Unabstractable ': syns) =>
41 (forall k. ProvenanceKindOf (Ty @k) prov) =>
42 (forall k. ProvenanceKindOf (Var @k) prov) =>
45 Syntaxes finalSyns (Forall finalSyns) =>
46 Parsers finalSyns finalSyns prov =>
48 Either (PerSyntax finalSyns (ErrorParser prov)) (TermVT finalSyns prov '[])
49 parse ast = unParser (fix openParser ast) CtxTyZ
51 openParser final (BinTree0 e) = parsers @finalSyns @finalSyns @prov final e
52 -- Instantiable and Unabstractable are always required.
53 openParser final (BinTree2 fT xT) = Parser $ \ctx -> do
54 TermVT fTy (f :: OpenTerm finalSyns fVS a2b) <- unParser (final fT) ctx
55 TermVT xTy (a :: OpenTerm finalSyns aVS a) <- unParser (final xT) ctx
62 { tyAppFun = TyConst{tyConst = eqTypeRep (typeRep @(->)) -> Just HRefl}
67 let (fxTy', xTy') = appendVars fxTy xTy
68 mgu <- (perSyntax . ErrorParserInstantiableUnify) `left` unifyType mempty fxTy' xTy'
69 let fxTy'' = subst mgu fxTy'
70 let xTy'' = subst mgu xTy'
71 case eqTy fxTy'' xTy'' of
72 Nothing -> Left $ perSyntax $ ErrorParserInstantiableArgumentMismatch (TyVT fxTy'') (TyVT xTy'')
74 normalizeVarsTy rTy $ \case
75 -- TyApp (TyApp _c qr') tr' ->
77 Right $ TermVT rTy' (f .@ a)
78 _ -> Left $ perSyntax $ ErrorParserInstantiableNotAFunction (TyVT fTy)
79 data instance ErrorParser prov Instantiable
80 = ErrorParserInstantiableArgumentMismatch (TyVT prov) (TyVT prov)
81 | ErrorParserInstantiableNotAFunction (TyVT prov)
82 | ErrorParserInstantiableUnify (ErrorUnify prov)
86 class Parsers syns finalSyns prov where
87 parsers :: OpenParser finalSyns prov
88 instance PerSyntaxable finalSyns Unabstractable => Parsers '[] finalSyns prov where
89 parsers _final tok = Parser $ \_ctx ->
90 Left $ perSyntax $ ErrorParserUnabstractableInvalid tok
91 data instance ErrorParser prov Unabstractable
92 = ErrorParserUnabstractableInvalid (TokenTerm prov)
95 ( TokenParser syn finalSyns prov
96 , Parsers syns finalSyns prov
98 Parsers (syn ': syns) finalSyns prov
100 parsers final = tokenParser @syn @finalSyns (parsers @syns @finalSyns final) final
102 -- ** Type 'OpenParser'
103 type OpenParser syns prov =
106 {-final-} (TermAST prov -> Parser syns prov) ->
110 -- ** Class 'TokenParser'
111 class TokenParser syn finalSyns prov where
113 {-next-} (TokenTerm prov -> Parser finalSyns prov) ->
114 OpenParser finalSyns prov
116 ( Syntaxes finalSyns (Forall finalSyns)
118 TokenParser Instantiable finalSyns prov
120 tokenParser next _final = next
121 data instance ErrorParser prov (AbstractableTy (Ty prov '[]))
122 = ErrorParserAbstractableUnknown Name
123 | ErrorParserAbstractableNotAType (TyVT prov)
126 ( Syntaxes finalSyns (Forall finalSyns)
127 , forall sem. Syntaxes finalSyns sem => Unabstractable sem
128 , forall sem. Syntaxes finalSyns sem => Instantiable sem
129 , PerSyntaxable finalSyns (AbstractableTy (Ty prov '[]))
130 , forall k. ProvenanceKindOf (Ty @k) prov
132 TokenParser (AbstractableTy (Ty prov '[])) finalSyns prov
134 tokenParser _next _final (TokenTermVar varName) = Parser go
136 go :: forall vs. CtxTy prov vs Void -> Either (PerSyntax finalSyns (ErrorParser prov)) (TermVT finalSyns prov vs)
137 go CtxTyZ = Left $ perSyntax $ ErrorParserAbstractableUnknown varName
139 go (CtxTyS n ty _) | n == varName = Right $ TermVT ty V
141 go (CtxTyS _n _typ tys) = do
142 TermVT ty ot <- go tys
143 Right $ TermVT ty (W ot)
144 tokenParser _next final (TokenTermAbst argName (TyT (argTy :: Ty prov '[] a)) bT) =
146 case eqTy (monoTy @Type @prov) (kindOf argTy) of
147 Nothing -> Left $ perSyntax $ ErrorParserAbstractableNotAType (TyVT argTy)
149 TermVT resTy (res :: OpenTerm syn resVS res) <-
150 unParser (final bT) (CtxTyS argName argTy ctx)
151 let argTy' = allocVarsR (lenVar resTy) argTy
153 TermVT (argTy' ~> resTy) $
155 E d -> E (Sym.const .@ d)
157 W e -> E Sym.const `appOpenTerm` e
159 tokenParser next _final e = next e
161 ( Syntaxes finalSyns (Forall finalSyns)
162 , forall sem. Syntaxes finalSyns sem => Addable sem
164 TokenParser Addable finalSyns prov
166 tokenParser next _final = \case
168 | Right (i :: Int) <- safeRead s ->
172 (tyOfTypeRep (lenVar ctx) (typeRep @Int))
176 TokenTermAtom "neg" -> Parser $ \_ctx ->
177 Right $ TermVT (monoTy @Int ~> monoTy @Int) $ E neg
178 TokenTermAtom "add" -> Parser $ \_ctx ->
179 Right $ TermVT (monoTy @Int ~> monoTy @Int ~> monoTy @Int) $ E add
182 ( Syntaxes syns (Forall syns)
183 , forall sem. Syntaxes syns sem => Unabstractable sem
185 TokenParser Unabstractable syns prov
187 tokenParser next _final = \case
188 TokenTermAtom "id" -> Parser $ \_ctx ->
189 Right $ TermVT (aTy @'[] ~> aTy) $ E Sym.id
190 TokenTermAtom "(<*>)" -> Parser $ \_ctx ->
192 TermVT ((aTy ~> bTy ~> cTy @'[]) ~> (aTy ~> bTy) ~> aTy ~> cTy) $
194 TokenTermAtom "const" -> Parser $ \_ctx ->
195 Right $ TermVT (aTy ~> bTy @'[] ~> aTy) $ E Sym.const
196 TokenTermAtom "(.)" -> Parser $ \_ctx ->
197 Right $ TermVT ((bTy ~> cTy @'[]) ~> (aTy ~> bTy) ~> aTy ~> cTy) $ E (Sym..)
198 TokenTermAtom "flip" -> Parser $ \_ctx ->
199 Right $ TermVT ((aTy ~> bTy ~> cTy @'[]) ~> bTy ~> aTy ~> cTy) $ E Sym.flip
200 TokenTermAtom "($)" -> Parser $ \_ctx ->
201 Right $ TermVT ((aTy ~> bTy @'[]) ~> aTy ~> bTy) $ E (Sym.$)
205 class Addable sem where
206 lit :: Int -> sem Int
207 neg :: sem (Int -> Int)
208 add :: sem (Int -> Int -> Int)
209 data instance ErrorParser prov Addable
213 class Mulable sem where
214 mul :: sem Int -> sem Int -> sem Int
215 instance (forall sem. Syntaxes syn sem => Addable sem) => Addable (Forall syn) where
216 lit n = Forall (lit n)
219 instance (forall sem. Syntaxes syn sem => Mulable sem) => Mulable (Forall syn) where
220 mul (Forall a) (Forall b) = Forall (mul a b)
226 -- tree0Parser :: (forall sem. syn sem => Addable sem, syn (Forall syn)) => Either ErrMsg (Forall syn Int)
227 -- tree0Parser = unParser $ parse tree0Print
231 -- ( forall sem. syn sem => Mulable sem
232 -- , forall sem. syn sem => Addable sem
233 -- , syn (Forall syn)
237 -- (TermAST prov -> Parser syn prov) ->
238 -- TermAST prov -> Parser syn prov
239 -- parseMulable final (BinTree2 (BinTree2 (BinTree0 (TokenTermAtom "mul")) aT) bT) =
240 -- Parser $ \ctx -> do
241 -- case (final aT, final bT) of
242 -- (Parser aE, Parser bE) -> do
243 -- TermVT aTy (Forall a :: Forall syn a) <- aE ctx
244 -- case eqTy aTy TyConst{tyConst = Const{constType = typeRep @Int, constMeta = mempty::prov}, tyConstLen = lenVar aTy} of
245 -- Nothing -> Left "TypeError: Mulable 1"
247 -- TermVT bTy (Forall b :: Forall syn b) <- bE ctx
248 -- case eqTy bTy TyConst{tyConst = Const{constType = typeRep @Int, constMeta = mempty::prov}, tyConstLen = lenVar bTy} of
249 -- Nothing -> Left "TypeError: Mulable 2"
251 -- Right $ TermVT aTy (Forall @_ @a $ mul a b)
252 -- parseMulable final t = parseAddable final t
258 printConst n = Printer (BinTree0 (TokenTermAtom n))
260 instance Sym.Unabstractable (Printer prov) where
261 ap = printConst "(<*>)"
262 const = printConst "const"
264 (.) = printConst "(.)"
265 flip = printConst "flip"
266 ($) = printConst "($)"
267 instance Addable (Printer prov) where
268 lit n = Printer $ BinTree0 (TokenTermAtom (show n))
269 neg = printConst "neg"
270 add = printConst "add"
271 instance Mulable (Printer prov) where
273 instance Instantiable (Printer prov) where
274 Printer f .@ Printer a = Printer $ BinTree2 f a
275 instance (Monoid prov) => AbstractableTy (Ty prov '[]) (Printer prov) where
276 lamTy xTy (f :: Printer prov a -> Printer prov b) =
282 (unPrinter (f (Printer (BinTree0 (TokenTermVar "x")))))
285 -- * Type 'FinalSyntaxes'
286 type FinalSyntaxes prov = '[AbstractableTy (Ty prov '[]), Addable]
289 tree0 = add .@ lit 8 .@ (neg .@ (add .@ lit 1 .@ lit 2))
291 -- tree1 = mul (add (lit 8) (neg (add (lit 1) (lit 2)))) (lit 2)
292 tree2 = fun @() (\x -> add .@ x .@ lit 0)
293 tree3 = fun @() (\x -> add .@ x .@ x)
294 tree4 = Sym.ap .@ add .@ Sym.id
295 tree0Print = print tree0
297 -- tree1Print = print tree1
298 tree2Print = print tree2
299 tree3Print = print tree3
300 tree4Print = print tree4
302 tree0ParsePrint :: TermAST ()
303 tree0ParsePrint = case parse @(FinalSyntaxes ()) @() tree0Print of
304 Left e -> error $ show e
305 Right (TermVT _ty (unE -> Forall sem)) -> print sem
307 -- tree1ParsePrint :: TermAST ()
308 -- tree1ParsePrint = case parse @(FinalSyntaxes ()) @() tree1Print of
310 -- Right (TermVT _ty (unE -> Forall sem)) -> print sem
312 tree2ParsePrint :: TermAST ()
313 tree2ParsePrint = case parse @(FinalSyntaxes ()) @() tree2Print of
314 Left e -> error $ show e
315 Right (TermVT _ty (unE -> Forall sem)) -> print sem
317 tree3ParsePrint :: TermAST ()
318 tree3ParsePrint = case parse @(FinalSyntaxes ()) @() tree3Print of
319 Left e -> error $ show e
320 Right (TermVT _ty (unE -> Forall sem)) -> print sem
322 tree3ParsePrint' :: TermAST ()
323 tree3ParsePrint' = case parse @(FinalSyntaxes ()) @() tree3ParsePrint of
324 Left e -> error $ show e
325 Right (TermVT _ty (unE -> Forall sem)) -> print sem
327 tree4ParsePrint :: TermAST ()
328 tree4ParsePrint = case parse @(FinalSyntaxes ()) @() tree4Print of
329 Left e -> error $ show e
330 Right (TermVT _ty (unE -> Forall sem)) -> print sem