251 lines
7.6 KiB
Haskell
251 lines
7.6 KiB
Haskell
-- recursion-schemes
|
|
{-# LANGUAGE DeriveFunctor, DeriveFoldable, DeriveTraversable
|
|
, TemplateHaskell, TypeFamilies #-}
|
|
{-# LANGUAGE OverloadedStrings, PatternSynonyms #-}
|
|
{-# LANGUAGE TypeFamilies, TypeFamilyDependencies #-}
|
|
{-# LANGUAGE UndecidableInstances, ImpredicativeTypes #-}
|
|
module Rlp.Syntax
|
|
(
|
|
-- * AST
|
|
RlpProgram(..)
|
|
, progDecls
|
|
, Decl(..), Decl', RlpExpr(..), RlpExpr'
|
|
, Pat(..), Pat'
|
|
, Assoc(..)
|
|
, Lit(..), Lit'
|
|
, RlpType(..), RlpType'
|
|
, ConAlt(..)
|
|
, Binding(..), Binding'
|
|
|
|
-- * Trees That Grow boilerplate
|
|
-- ** Extension points
|
|
, IdP, XRec, UnXRec(..), MapXRec(..)
|
|
-- *** Decl
|
|
, XFunD, XTySigD, XInfixD, XDataD, XXDeclD
|
|
-- *** RlpExpr
|
|
, XLetE, XVarE, XLamE, XCaseE, XIfE, XAppE, XLitE
|
|
, XParE, XOAppE, XXRlpExprE
|
|
-- ** Pattern synonyms
|
|
-- *** Decl
|
|
, pattern FunD, pattern TySigD, pattern InfixD, pattern DataD
|
|
-- *** RlpExpr
|
|
, pattern LetE, pattern VarE, pattern LamE, pattern CaseE, pattern IfE
|
|
, pattern AppE, pattern LitE, pattern ParE, pattern OAppE
|
|
, pattern XRlpExprE
|
|
)
|
|
where
|
|
----------------------------------------------------------------------------------
|
|
import Data.Text (Text)
|
|
import Data.Text qualified as T
|
|
import Data.String (IsString(..))
|
|
import Data.Functor.Foldable.TH (makeBaseFunctor)
|
|
import Data.Functor.Classes
|
|
import Data.Kind (Type)
|
|
import Lens.Micro
|
|
import Lens.Micro.TH
|
|
import Core.Syntax hiding (Lit, Type, Binding, Binding')
|
|
import Core (HasRHS(..), HasLHS(..))
|
|
----------------------------------------------------------------------------------
|
|
|
|
data RlpModule p = RlpModule
|
|
{ _rlpmodName :: Text
|
|
, _rlpmodProgram :: RlpProgram p
|
|
}
|
|
|
|
-- | dear god.
|
|
type PhaseShow p =
|
|
( Show (XRec p (Pat p)), Show (XRec p (RlpExpr p))
|
|
, Show (XRec p (Lit p)), Show (IdP p)
|
|
, Show (XRec p (RlpType p))
|
|
, Show (XRec p (Binding p))
|
|
)
|
|
|
|
newtype RlpProgram p = RlpProgram [Decl' p]
|
|
|
|
progDecls :: Lens' (RlpProgram p) [Decl' p]
|
|
progDecls = lens
|
|
(\ (RlpProgram ds) -> ds)
|
|
(const RlpProgram)
|
|
|
|
deriving instance (PhaseShow p, Show (XRec p (Decl p))) => Show (RlpProgram p)
|
|
|
|
data RlpType p = FunConT
|
|
| FunT (RlpType' p) (RlpType' p)
|
|
| AppT (RlpType' p) (RlpType' p)
|
|
| VarT (IdP p)
|
|
| ConT (IdP p)
|
|
|
|
type RlpType' p = XRec p (RlpType p)
|
|
|
|
deriving instance (PhaseShow p)
|
|
=> Show (RlpType p)
|
|
|
|
data Decl p = FunD' (XFunD p) (IdP p) [Pat' p] (RlpExpr' p) (Maybe (Where p))
|
|
| TySigD' (XTySigD p) [IdP p] (RlpType' p)
|
|
| DataD' (XDataD p) (IdP p) [IdP p] [ConAlt p]
|
|
| InfixD' (XInfixD p) Assoc Int (IdP p)
|
|
| XDeclD' !(XXDeclD p)
|
|
|
|
deriving instance
|
|
( Show (XFunD p), Show (XTySigD p)
|
|
, Show (XDataD p), Show (XInfixD p)
|
|
, Show (XXDeclD p)
|
|
, PhaseShow p
|
|
)
|
|
=> Show (Decl p)
|
|
|
|
type family XFunD p
|
|
type family XTySigD p
|
|
type family XDataD p
|
|
type family XInfixD p
|
|
type family XXDeclD p
|
|
|
|
pattern FunD :: (XFunD p ~ ())
|
|
=> IdP p -> [Pat' p] -> RlpExpr' p -> Maybe (Where p)
|
|
-> Decl p
|
|
pattern TySigD :: (XTySigD p ~ ()) => [IdP p] -> RlpType' p -> Decl p
|
|
pattern DataD :: (XDataD p ~ ()) => IdP p -> [IdP p] -> [ConAlt p] -> Decl p
|
|
pattern InfixD :: (XInfixD p ~ ()) => Assoc -> Int -> IdP p -> Decl p
|
|
pattern XDeclD :: (XXDeclD p ~ ()) => Decl p
|
|
|
|
pattern FunD n as e wh = FunD' () n as e wh
|
|
pattern TySigD ns t = TySigD' () ns t
|
|
pattern DataD n as cs = DataD' () n as cs
|
|
pattern InfixD a p n = InfixD' () a p n
|
|
pattern XDeclD = XDeclD' ()
|
|
|
|
type Decl' p = XRec p (Decl p)
|
|
|
|
data Assoc = InfixL
|
|
| InfixR
|
|
| Infix
|
|
deriving (Show)
|
|
|
|
data ConAlt p = ConAlt (IdP p) [RlpType' p]
|
|
|
|
deriving instance (Show (IdP p), Show (XRec p (RlpType p))) => Show (ConAlt p)
|
|
|
|
data RlpExpr p = LetE' (XLetE p) [Binding' p] (RlpExpr' p)
|
|
| VarE' (XVarE p) (IdP p)
|
|
| LamE' (XLamE p) [Pat p] (RlpExpr' p)
|
|
| CaseE' (XCaseE p) (RlpExpr' p) [(Alt p, Where p)]
|
|
| IfE' (XIfE p) (RlpExpr' p) (RlpExpr' p) (RlpExpr' p)
|
|
| AppE' (XAppE p) (RlpExpr' p) (RlpExpr' p)
|
|
| LitE' (XLitE p) (Lit p)
|
|
| ParE' (XParE p) (RlpExpr' p)
|
|
| OAppE' (XOAppE p) (IdP p) (RlpExpr' p) (RlpExpr' p)
|
|
| XRlpExprE' !(XXRlpExprE p)
|
|
|
|
type family XLetE p
|
|
type family XVarE p
|
|
type family XLamE p
|
|
type family XCaseE p
|
|
type family XIfE p
|
|
type family XAppE p
|
|
type family XLitE p
|
|
type family XParE p
|
|
type family XOAppE p
|
|
type family XXRlpExprE p
|
|
|
|
pattern LetE :: (XLetE p ~ ()) => [Binding' p] -> RlpExpr' p -> RlpExpr p
|
|
pattern VarE :: (XVarE p ~ ()) => IdP p -> RlpExpr p
|
|
pattern LamE :: (XLamE p ~ ()) => [Pat p] -> RlpExpr' p -> RlpExpr p
|
|
pattern CaseE :: (XCaseE p ~ ()) => RlpExpr' p -> [(Alt p, Where p)] -> RlpExpr p
|
|
pattern IfE :: (XIfE p ~ ()) => RlpExpr' p -> RlpExpr' p -> RlpExpr' p -> RlpExpr p
|
|
pattern AppE :: (XAppE p ~ ()) => RlpExpr' p -> RlpExpr' p -> RlpExpr p
|
|
pattern LitE :: (XLitE p ~ ()) => Lit p -> RlpExpr p
|
|
pattern ParE :: (XParE p ~ ()) => RlpExpr' p -> RlpExpr p
|
|
pattern OAppE :: (XOAppE p ~ ()) => IdP p -> RlpExpr' p -> RlpExpr' p -> RlpExpr p
|
|
pattern XRlpExprE :: (XXRlpExprE p ~ ()) => RlpExpr p
|
|
|
|
pattern LetE bs e = LetE' () bs e
|
|
pattern VarE n = VarE' () n
|
|
pattern LamE as e = LamE' () as e
|
|
pattern CaseE e as = CaseE' () e as
|
|
pattern IfE c a b = IfE' () c a b
|
|
pattern AppE f x = AppE' () f x
|
|
pattern LitE l = LitE' () l
|
|
pattern ParE e = ParE' () e
|
|
pattern OAppE n a b = OAppE' () n a b
|
|
pattern XRlpExprE = XRlpExprE' ()
|
|
|
|
deriving instance
|
|
( Show (XLetE p), Show (XVarE p), Show (XLamE p)
|
|
, Show (XCaseE p), Show (XIfE p), Show (XAppE p)
|
|
, Show (XLitE p), Show (XParE p), Show (XOAppE p)
|
|
, Show (XXRlpExprE p)
|
|
, PhaseShow p
|
|
) => Show (RlpExpr p)
|
|
|
|
type RlpExpr' p = XRec p (RlpExpr p)
|
|
|
|
class UnXRec p where
|
|
unXRec :: XRec p a -> a
|
|
|
|
class MapXRec p where
|
|
mapXRec :: (a -> b) -> XRec p a -> XRec p b
|
|
|
|
type family XRec p a = (r :: Type) | r -> p a
|
|
|
|
type family IdP p
|
|
|
|
type Where p = [Binding p]
|
|
|
|
-- do we want guards?
|
|
data Alt p = AltA (Pat' p) (RlpExpr' p)
|
|
|
|
deriving instance (PhaseShow p) => Show (Alt p)
|
|
|
|
data Binding p = PatB (Pat' p) (RlpExpr' p)
|
|
| FunB (IdP p) [Pat' p] (RlpExpr' p)
|
|
|
|
type Binding' p = XRec p (Binding p)
|
|
|
|
deriving instance (Show (XRec p (Pat p)), Show (XRec p (RlpExpr p)), Show (IdP p)
|
|
) => Show (Binding p)
|
|
|
|
data Pat p = VarP (IdP p)
|
|
| LitP (Lit' p)
|
|
| ConP (IdP p) [Pat' p]
|
|
|
|
deriving instance (PhaseShow p) => Show (Pat p)
|
|
|
|
type Pat' p = XRec p (Pat p)
|
|
|
|
data Lit p = IntL Int
|
|
| CharL Char
|
|
| ListL [RlpExpr' p]
|
|
|
|
deriving instance (PhaseShow p) => Show (Lit p)
|
|
|
|
type Lit' p = XRec p (Lit p)
|
|
|
|
-- instance HasLHS Alt Alt Pat Pat where
|
|
-- _lhs = lens
|
|
-- (\ (AltA p _) -> p)
|
|
-- (\ (AltA _ e) p' -> AltA p' e)
|
|
|
|
-- instance HasRHS Alt Alt RlpExpr RlpExpr where
|
|
-- _rhs = lens
|
|
-- (\ (AltA _ e) -> e)
|
|
-- (\ (AltA p _) e' -> AltA p e')
|
|
|
|
-- makeBaseFunctor ''RlpExpr
|
|
|
|
-- showsTernaryWith :: (Int -> x -> ShowS)
|
|
-- -> (Int -> y -> ShowS)
|
|
-- -> (Int -> z -> ShowS)
|
|
-- -> String -> Int
|
|
-- -> x -> y -> z
|
|
-- -> ShowS
|
|
-- showsTernaryWith sa sb sc name p a b c = showParen (p > 10)
|
|
-- $ showString name
|
|
-- . showChar ' ' . sa 11 a
|
|
-- . showChar ' ' . sb 11 b
|
|
-- . showChar ' ' . sc 11 c
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
makeLenses ''RlpModule
|
|
|