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

Reply via email to