aboutsummaryrefslogtreecommitdiff
path: root/src/HSVIS/AST.hs
diff options
context:
space:
mode:
authorTom Smeding <tom@tomsmeding.com>2024-02-27 22:17:03 +0100
committerTom Smeding <tom@tomsmeding.com>2024-02-27 22:17:03 +0100
commitfc942fb8dfaad7614567f2dcbd9a911ffd474a06 (patch)
tree4ae17384d7959dbadd581925849582bee5815b5d /src/HSVIS/AST.hs
parent307919760c58e037ec3260fcd0c3c7f7227fd7aa (diff)
Trees that explode
Diffstat (limited to 'src/HSVIS/AST.hs')
-rw-r--r--src/HSVIS/AST.hs310
1 files changed, 259 insertions, 51 deletions
diff --git a/src/HSVIS/AST.hs b/src/HSVIS/AST.hs
index f606d22..7b05e19 100644
--- a/src/HSVIS/AST.hs
+++ b/src/HSVIS/AST.hs
@@ -1,75 +1,162 @@
+{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE StandaloneDeriving #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE LambdaCase #-}
module HSVIS.AST where
+import Data.Bifunctor (bimap, second)
+import qualified Data.Kind as DK
import Data.List.NonEmpty (NonEmpty)
+import Data.Proxy
import HSVIS.Pretty
+-- | An AST type has a single stage argument.
+type ASTType = DK.Type -> DK.Type
+
+-- | Trees that Grow extension type family
+type family X (f :: ASTType) s
+
+-- | Additional constructors
+data family E (f :: ASTType) s
+
+class HasExt f where
+ type HasXField f :: Bool
+ type HasECon f :: Bool
+ type ContainsData f :: [ASTType]
+ extOf :: f s -> X f s
+ extMap :: Proxy f -> Proxy s1 -> Proxy s2
+ -> XMapperTelescope (TransitiveContainsData '[f]) s1 s2
+ (EMapperTelescope (TransitiveContainsData '[f]) s1 s2
+ (f s1 -> f s2))
+
+type family If c a b where
+ If 'True a b = a
+ If 'False a b = b
+
+type family ASTShowPrereqs f s :: DK.Constraint where
+ ASTShowPrereqs f s =
+ (If (HasXField f) (Show (X f s)) (() :: DK.Constraint)
+ ,If (HasECon f) (Show (E f s)) (() :: DK.Constraint)
+ ,ASTShowPrereqsC (ContainsData f) s)
+
+type family ASTShowPrereqsC l s :: DK.Constraint where
+ ASTShowPrereqsC '[] s = ()
+ ASTShowPrereqsC (f ': fs) s = (Show (f s), ASTShowPrereqsC fs s)
+
+type family a && b where
+ 'False && b = 'False
+ 'True && b = b
+
+type family In x l where
+ In x '[] = 'False
+ In x (x ': ys) = 'True
+ In x (_ ': ys) = In x ys
+
+type family Sublist l1 l2 where
+ Sublist '[] l = 'True
+ Sublist (x ': xs) l = In x l && Sublist xs l
+
+type family Union l1 l2 where
+ Union '[] l = l
+ Union (x ': xs) l = If (In x l) (Union xs l) (x ': Union xs l)
+
+type family MapContainsData l where
+ MapContainsData '[] = '[]
+ MapContainsData (f ': fs) = Union (ContainsData f) (MapContainsData fs)
+
+type family TransitiveContainsData fs where
+ TransitiveContainsData fs = TransitiveContainsData' fs (Sublist (Union fs (MapContainsData fs)) fs)
+
+type family TransitiveContainsData' fs isfull where
+ TransitiveContainsData' fs 'True = fs
+ TransitiveContainsData' fs 'False = TransitiveContainsData (Union fs (MapContainsData fs))
+
+type family XMapperTelescope fs s1 s2 a where
+ XMapperTelescope '[] s1 s2 a = a
+ XMapperTelescope (f ': fs) s1 s2 a =
+ If (HasXField f)
+ ((X f s1 -> X f s2) -> XMapperTelescope fs s1 s2 a)
+ (XMapperTelescope fs s1 s2 a)
+
+type family EMapperTelescope fs s1 s2 a where
+ EMapperTelescope '[] s1 s2 a = a
+ EMapperTelescope (f ': fs) s1 s2 a =
+ If (HasECon f)
+ ((X f s1 -> E f s1 -> f s2) -> EMapperTelescope fs s1 s2 a)
+ (EMapperTelescope fs s1 s2 a)
+
+
newtype Name = Name String
deriving (Show, Eq)
-data Program t = Program [DataDef] [FunDef t]
- deriving (Show)
+data Program s = Program [DataDef s] [FunDef s]
+deriving instance (Show (DataDef s), Show (FunDef s)) => Show (Program s)
-data DataDef = DataDef Name [Name] [(Name, [Type])]
- deriving (Show)
+data DataDef s = DataDef (X DataDef s) Name [Name] [(Name, [Type s])]
+deriving instance ASTShowPrereqs DataDef s => Show (DataDef s)
-data FunDef t = FunDef Name (Maybe Type) (NonEmpty (FunEq t))
- deriving (Show)
+data FunDef s = FunDef (X FunDef s) Name (Maybe (Type s)) (NonEmpty (FunEq s))
+deriving instance ASTShowPrereqs FunDef s => Show (FunDef s)
-data FunEq t = FunEq t Name [Pattern t] (RHS t)
- deriving (Show)
+data FunEq s = FunEq (X FunEq s) Name [Pattern s] (RHS s)
+deriving instance ASTShowPrereqs FunEq s => Show (FunEq s)
-data TypeStage = TSTC | TSNormal
- deriving (Show)
+data Kind s
+ = KType (X Kind s)
+ | KFun (X Kind s) (Kind s) (Kind s)
+deriving instance ASTShowPrereqs Kind s => Show (Kind s)
-data GType (stage :: TypeStage) where
- TApp :: GType s -> [GType s] -> GType s
- TTup :: [GType s] -> GType s
- TList :: GType s -> GType s
- TFun :: GType s -> GType s -> GType s
- TCon :: Name -> GType s
- TVar :: Name -> GType s
-
- -- Type constructor used only while type checking
- TUniVar :: Int -> GType 'TSTC
-deriving instance Show (GType stage)
-
-type TCType = GType 'TSTC
-type Type = GType 'TSNormal
-
-data Pattern t
- = PWildcard t
- | PVar t Name
- | PAs t Name (Pattern t)
- | PCon t Name [Pattern t]
- | POp t (Pattern t) Operator (Pattern t)
- | PList t [Pattern t]
- | PTup t [Pattern t]
- deriving (Show)
+data Type s
+ = TApp (X Type s) (Type s) [Type s]
+ | TTup (X Type s) [Type s]
+ | TList (X Type s) (Type s)
+ | TFun (X Type s) (Type s) (Type s)
+ | TCon (X Type s) Name
+ | TVar (X Type s) Name
-data RHS t
- = Guarded [(Expr t, Expr t)] -- currently not parsed
- | Plain (Expr t)
- deriving (Show)
+ -- extension point
+ | TExt (X Type s) !(E Type s)
+deriving instance ASTShowPrereqs Type s => Show (Type s)
-data Expr t
- = ELit t Literal
- | EVar t Name
- | ECon t Name
- | EList t [Expr t]
- | ETup t [Expr t]
- | EApp t (Expr t) [Expr t]
- | EOp t (Expr t) Operator (Expr t)
- | EIf t (Expr t) (Expr t) (Expr t)
- | ECase t (Expr t) [(Pattern t, RHS t)]
- | ELet t [FunDef t] (Expr t)
- | EParseError
- deriving (Show)
+data Pattern s
+ = PWildcard (X Pattern s)
+ | PVar (X Pattern s) Name
+ | PAs (X Pattern s) Name (Pattern s)
+ | PCon (X Pattern s) Name [Pattern s]
+ | POp (X Pattern s) (Pattern s) Operator (Pattern s)
+ | PList (X Pattern s) [Pattern s]
+ | PTup (X Pattern s) [Pattern s]
+deriving instance ASTShowPrereqs Pattern s => Show (Pattern s)
+
+data RHS s
+ = Guarded (X RHS s) [(Expr s, Expr s)] -- currently not parsed
+ | Plain (X RHS s) (Expr s)
+deriving instance ASTShowPrereqs RHS s => Show (RHS s)
+
+data Expr s
+ = ELit (X Expr s) Literal
+ | EVar (X Expr s) Name
+ | ECon (X Expr s) Name
+ | EList (X Expr s) [Expr s]
+ | ETup (X Expr s) [Expr s]
+ | EApp (X Expr s) (Expr s) [Expr s]
+ | EOp (X Expr s) (Expr s) Operator (Expr s)
+ | EIf (X Expr s) (Expr s) (Expr s) (Expr s)
+ | ECase (X Expr s) (Expr s) [(Pattern s, RHS s)]
+ | ELet (X Expr s) [FunDef s] (Expr s)
+ | EError (X Expr s)
+deriving instance ASTShowPrereqs Expr s => Show (Expr s)
data Literal = LInt Integer | LFloat Rational | LChar Char | LString String
deriving (Show)
@@ -80,3 +167,124 @@ data Operator = OAdd | OSub | OMul | ODiv | OMod | OEqu | OPow
instance Pretty Name where
prettysPrec _ (Name n) = showString ("\"" ++ n ++ "\"")
+
+instance HasExt DataDef where
+ type HasXField DataDef = 'True
+ type HasECon DataDef = 'False
+ type ContainsData DataDef = '[Type]
+ extOf (DataDef x _ _ _) = x
+ extMap _ ps1 ps2 fdd fty gty (DataDef x n ps cs) =
+ DataDef (fdd x) n ps (map (second (map (extMap (Proxy @Type) ps1 ps2 fty gty))) cs)
+
+instance HasExt FunDef where
+ type HasXField FunDef = 'True
+ type HasECon FunDef = 'False
+ type ContainsData FunDef = '[Type, FunEq]
+ extOf (FunDef x _ _ _) = x
+ extMap _ ps1 ps2 ffd ffe frh fty fpa fex gty (FunDef x n msig es) =
+ FunDef (ffd x) n (extMap (Proxy @Type) ps1 ps2 fty gty <$> msig)
+ (fmap (extMap (Proxy @FunEq) ps1 ps2 frh ffd fpa fex fty ffe gty) es)
+
+instance HasExt FunEq where
+ type HasXField FunEq = 'True
+ type HasECon FunEq = 'False
+ type ContainsData FunEq = '[Pattern, RHS]
+ extOf (FunEq x _ _ _) = x
+ extMap _ ps1 ps2 frh ffd fpa fex fty ffe gty (FunEq x n ps rhs) =
+ FunEq (ffe x) n (map (extMap (Proxy @Pattern) ps1 ps2 fpa) ps)
+ (extMap (Proxy @RHS) ps1 ps2 frh ffd fpa fex fty ffe gty rhs)
+
+instance HasExt Kind where
+ type HasXField Kind = 'True
+ type HasECon Kind = 'False
+ type ContainsData Kind = '[Kind]
+ extOf (KType x) = x
+ extOf (KFun x _ _) = x
+ extMap _ _ _ f (KType x) = KType (f x)
+ extMap p ps1 ps2 f (KFun x a b) = KFun (f x) (extMap p ps1 ps2 f a) (extMap p ps1 ps2 f b)
+
+instance HasExt Type where
+ type HasXField Type = 'True
+ type HasECon Type = 'True
+ type ContainsData Type = '[Type]
+ extOf (TApp x _ _) = x
+ extOf (TTup x _) = x
+ extOf (TList x _) = x
+ extOf (TFun x _ _) = x
+ extOf (TCon x _) = x
+ extOf (TVar x _) = x
+ extOf (TExt x _) = x
+
+ extMap p ps1 ps2 f g (TApp x a b) = TApp (f x) (extMap p ps1 ps2 f g a) (map (extMap p ps1 ps2 f g) b)
+ extMap p ps1 ps2 f g (TTup x as) = TTup (f x) (map (extMap p ps1 ps2 f g) as)
+ extMap p ps1 ps2 f g (TList x a) = TList (f x) (extMap p ps1 ps2 f g a)
+ extMap p ps1 ps2 f g (TFun x a b) = TFun (f x) (extMap p ps1 ps2 f g a) (extMap p ps1 ps2 f g b)
+ extMap _ _ _ f _ (TCon x n) = TCon (f x) n
+ extMap _ _ _ f _ (TVar x n) = TVar (f x) n
+ extMap _ _ _ _ g (TExt x e) = g x e
+
+instance HasExt Pattern where
+ type HasXField Pattern = 'True
+ type HasECon Pattern = 'False
+ type ContainsData Pattern = '[Pattern]
+ extOf (PWildcard x) = x
+ extOf (PVar x _) = x
+ extOf (PAs x _ _) = x
+ extOf (PCon x _ _) = x
+ extOf (POp x _ _ _) = x
+ extOf (PList x _) = x
+ extOf (PTup x _) = x
+
+ extMap _ _ _ f (PWildcard x) = PWildcard (f x)
+ extMap _ _ _ f (PVar x n) = PVar (f x) n
+ extMap p ps1 ps2 f (PAs x n a) = PAs (f x) n (extMap p ps1 ps2 f a)
+ extMap p ps1 ps2 f (PCon x n as) = PCon (f x) n (map (extMap p ps1 ps2 f) as)
+ extMap p ps1 ps2 f (POp x a n b) = POp (f x) (extMap p ps1 ps2 f a) n (extMap p ps1 ps2 f b)
+ extMap p ps1 ps2 f (PList x as) = PList (f x) (map (extMap p ps1 ps2 f) as)
+ extMap p ps1 ps2 f (PTup x as) = PTup (f x) (map (extMap p ps1 ps2 f) as)
+
+instance HasExt RHS where
+ type HasXField RHS = 'True
+ type HasECon RHS = 'False
+ type ContainsData RHS = '[Expr]
+ extOf (Guarded x _) = x
+ extOf (Plain x _) = x
+
+ extMap _ ps1 ps2 frh ffd fpa fex fty ffe gty (Guarded x l) =
+ Guarded (frh x) (map (bimap (extMap (Proxy @Expr) ps1 ps2 frh ffd fpa fex fty ffe gty)
+ (extMap (Proxy @Expr) ps1 ps2 frh ffd fpa fex fty ffe gty))
+ l)
+ extMap _ ps1 ps2 frh ffd fpa fex fty ffe gty (Plain x e) =
+ Plain (frh x) (extMap (Proxy @Expr) ps1 ps2 frh ffd fpa fex fty ffe gty e)
+
+instance HasExt Expr where
+ type HasXField Expr = 'True
+ type HasECon Expr = 'False
+ type ContainsData Expr = '[Expr, Pattern, RHS, FunDef]
+ extOf (ELit x _) = x
+ extOf (EVar x _) = x
+ extOf (ECon x _) = x
+ extOf (EList x _) = x
+ extOf (ETup x _) = x
+ extOf (EApp x _ _) = x
+ extOf (EOp x _ _ _) = x
+ extOf (EIf x _ _ _) = x
+ extOf (ECase x _ _) = x
+ extOf (ELet x _ _) = x
+ extOf (EError x) = x
+
+ extMap p ps1 ps2 frh ffd fpa fex fty ffe gty = \case
+ ELit x l -> ELit (fex x) l
+ EVar x n -> EVar (fex x) n
+ ECon x n -> ECon (fex x) n
+ EList x es -> EList (fex x) (map (extMap p ps1 ps2 frh ffd fpa fex fty ffe gty) es)
+ ETup x es -> ETup (fex x) (map (extMap p ps1 ps2 frh ffd fpa fex fty ffe gty) es)
+ EApp x a es -> EApp (fex x) (extMap p ps1 ps2 frh ffd fpa fex fty ffe gty a) (map (extMap p ps1 ps2 frh ffd fpa fex fty ffe gty) es)
+ EOp x a n b -> EOp (fex x) (extMap p ps1 ps2 frh ffd fpa fex fty ffe gty a) n (extMap p ps1 ps2 frh ffd fpa fex fty ffe gty b)
+ EIf x a b c -> EIf (fex x) (extMap p ps1 ps2 frh ffd fpa fex fty ffe gty a) (extMap p ps1 ps2 frh ffd fpa fex fty ffe gty b) (extMap p ps1 ps2 frh ffd fpa fex fty ffe gty c)
+ ECase x a l -> ECase (fex x) (extMap p ps1 ps2 frh ffd fpa fex fty ffe gty a)
+ (map (bimap (extMap (Proxy @Pattern) ps1 ps2 fpa)
+ (extMap (Proxy @RHS) ps1 ps2 frh ffd fpa fex fty ffe gty))
+ l)
+ ELet x as b -> ELet (fex x) (map (extMap (Proxy @FunDef) ps1 ps2 ffd ffe frh fty fpa fex gty) as) (extMap p ps1 ps2 frh ffd fpa fex fty ffe gty b)
+ EError x -> EError (fex x)