I want to be able to run the GHC parser in one of two modes, batch which
functions as now, and interactive which will (eventually) be incremental.
In addition, the hsSyn AST for each will have different TTG[1] annotations,
so that it can better support IDE usage.
I think this can be done by changing the types in HsExtension to introduce
a 'Process' type as follows
data Pass = Parsed Process | Renamed | Typechecked
deriving (Data)
data Process = Batch | Interactive
deriving (Show, Data)
We then rename the pass synonyms so that batch is the default
type GhcPs = GhcPass ('Parsed 'Batch)
type GhcPsI = GhcPass ('Parsed 'Interactive)
I have attached a simple proof of concept file, which emulates parsing and
renaming.
Is this an appropriate approach to take?
Alan
[1] Trees That Grow https://ghc.haskell.org/trac/ghc/wiki/
ImplementingTreesThatGrow
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE StandaloneDeriving #-}
-- Next two needed for the Show instances
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE UndecidableInstances #-}
import Data.Data hiding ( Fixity )
main :: IO ()
main = putStrLn "hello"
data NoExt = NoExt
deriving (Data,Eq,Ord,Show)
-- | Used as a data type index for the hsSyn AST
data GhcPass (c :: Pass)
deriving instance Eq (GhcPass c)
deriving instance Typeable c => Data (GhcPass c)
data Pass = Parsed Process | Renamed | Typechecked
deriving (Data)
data Process = Batch | Interactive
deriving (Show, Data)
-- Type synonyms as a shorthand for tagging
type GhcPs = GhcPass ('Parsed 'Batch)
type GhcPsI = GhcPass ('Parsed 'Interactive)
type GhcRn = GhcPass 'Renamed
type GhcTc = GhcPass 'Typechecked
type GhcTcId = GhcTc
-- | Maps the "normal" id type for a given pass
type family IdP p
type instance IdP (GhcPass ('Parsed _)) = RdrName
type instance IdP GhcRn = Name
type instance IdP GhcTc = Id
data RdrName = RdrName String deriving Show
data Name = Name String deriving Show
data Id = Id String deriving Show
-- ---------------------------------------------------------------------
data AST p = AST (XAST p) [Decl p]
deriving instance (Show (XAST p),Show (XD p), Show (IdP p)) => Show (AST p)
type family XAST p
type instance XAST GhcPs = NoExt
type instance XAST GhcPsI = Int
type instance XAST GhcRn = NoExt
type instance XAST GhcTc = NoExt
data Decl p = D (XD p) (IdP p)
deriving instance (Show (XD p), Show (IdP p)) => Show (Decl p)
type family XD p
type instance XD GhcPs = NoExt
type instance XD GhcPsI = Int
type instance XD GhcRn = NoExt
type instance XD GhcTc = NoExt
-- ---------------------------------------------------------------------
parseBatch :: String -> AST GhcPs
parseBatch str = AST NoExt [D NoExt (RdrName str)]
parseInteractive :: String -> AST GhcPsI
parseInteractive str = AST 1 [D 2 (RdrName str)]
rename :: AST (GhcPass ('Parsed p)) -> AST GhcRn
rename (AST _ ds) = AST NoExt ds'
where
ds' = map rn ds
rn (D _ (RdrName s)) = (D NoExt (Name s))
i s = rename $ parseInteractive s
b s = rename $ parseBatch s
_______________________________________________
ghc-devs mailing list
[email protected]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs