module DDC.Source.Tetra.ToCore
(toCoreModule)
where
import qualified DDC.Source.Tetra.Module as S
import qualified DDC.Source.Tetra.DataDef as S
import qualified DDC.Source.Tetra.Exp as S
import qualified DDC.Source.Tetra.Prim as S
import qualified DDC.Core.Tetra.Prim as C
import qualified DDC.Core.Compounds as C
import qualified DDC.Core.Module as C
import qualified DDC.Core.Exp as C
import qualified DDC.Type.DataDef as C
import qualified DDC.Type.Sum as Sum
import Data.Maybe
import DDC.Core.Exp
( Bind (..)
, Bound (..)
, Type (..)
, TyCon (..)
, Pat (..)
, DaCon (..)
, Witness (..)
, WiCon (..))
import DDC.Core.Module
( ExportSource (..)
, ImportSource (..))
toCoreModule :: a -> S.Module a S.Name -> C.Module a C.Name
toCoreModule a mm
= C.ModuleCore
{ C.moduleName = S.moduleName mm
, C.moduleExportTypes
= [ (toCoreN n, ExportSourceLocalNoType (toCoreN n))
| n <- S.moduleExportTypes mm ]
, C.moduleExportValues
= [ (toCoreN n, ExportSourceLocalNoType (toCoreN n))
| n <- S.moduleExportValues mm ]
, C.moduleImportTypes
= [ (toCoreN n, toCoreImportSource isrc)
| (n, isrc) <- S.moduleImportTypes mm ]
, C.moduleImportValues
= [ (toCoreN n, toCoreImportSource isrc)
| (n, isrc) <- S.moduleImportValues mm ]
, C.moduleDataDefsLocal
= [ toCoreDataDef def
| S.TopData _ def <- S.moduleTops mm ]
, C.moduleBody
= C.XLet a (letsOfTops (S.moduleTops mm))
(C.xUnit a) }
letsOfTops :: [S.Top a S.Name] -> C.Lets a C.Name
letsOfTops tops
= C.LRec $ mapMaybe bindOfTop tops
bindOfTop
:: S.Top a S.Name
-> Maybe (Bind C.Name, C.Exp a C.Name)
bindOfTop (S.TopBind _ b x)
= Just (toCoreB b, toCoreX x)
bindOfTop _ = Nothing
toCoreImportSource :: ImportSource S.Name -> ImportSource C.Name
toCoreImportSource src
= case src of
ImportSourceAbstract t
-> ImportSourceAbstract (toCoreT t)
ImportSourceModule mn n t
-> ImportSourceModule mn (toCoreN n) (toCoreT t)
ImportSourceSea v t
-> ImportSourceSea v (toCoreT t)
toCoreT :: Type S.Name -> Type C.Name
toCoreT tt
= case tt of
TVar u -> TVar (toCoreU u)
TCon tc -> TCon (toCoreTC tc)
TForall b t -> TForall (toCoreB b) (toCoreT t)
TApp t1 t2 -> TApp (toCoreT t1) (toCoreT t2)
TSum ts -> TSum $ Sum.fromList (toCoreT (Sum.kindOfSum ts))
$ map toCoreT
$ Sum.toList ts
toCoreTC :: TyCon S.Name -> TyCon C.Name
toCoreTC tc
= case tc of
TyConSort sc -> TyConSort sc
TyConKind kc -> TyConKind kc
TyConWitness wc -> TyConWitness wc
TyConSpec sc -> TyConSpec sc
TyConBound u k -> TyConBound (toCoreU u) (toCoreT k)
TyConExists n k -> TyConExists n (toCoreT k)
toCoreDataDef :: S.DataDef S.Name -> C.DataDef C.Name
toCoreDataDef def
= C.DataDef
{ C.dataDefTypeName
= toCoreN $ S.dataDefTypeName def
, C.dataDefParams
= map toCoreB $ S.dataDefParams def
, C.dataDefCtors
= Just
$ [ toCoreDataCtor def tag ctor
| ctor <- S.dataDefCtors def
| tag <- [0..] ]
, C.dataDefIsAlgebraic
= True
}
toCoreDataCtor
:: S.DataDef S.Name
-> Integer
-> S.DataCtor S.Name
-> C.DataCtor C.Name
toCoreDataCtor dataDef tag ctor
= C.DataCtor
{ C.dataCtorName = toCoreN (S.dataCtorName ctor)
, C.dataCtorTag = tag
, C.dataCtorFieldTypes = map toCoreT (S.dataCtorFieldTypes ctor)
, C.dataCtorResultType = toCoreT (S.dataCtorResultType ctor)
, C.dataCtorTypeName = toCoreN (S.dataDefTypeName dataDef)
, C.dataCtorTypeParams = map toCoreB (S.dataDefParams dataDef) }
toCoreX :: S.Exp a S.Name -> C.Exp a C.Name
toCoreX xx
= case xx of
S.XVar a u -> C.XVar a (toCoreU u)
S.XCon a dc -> C.XCon a (toCoreDC dc)
S.XLAM a b x -> C.XLAM a (toCoreB b) (toCoreX x)
S.XLam a b x -> C.XLam a (toCoreB b) (toCoreX x)
S.XApp a x1 x2 -> C.XApp a (toCoreX x1) (toCoreX x2)
S.XLet a lts x -> C.XLet a (toCoreLts lts) (toCoreX x)
S.XCase a x alts -> C.XCase a (toCoreX x) (map toCoreA alts)
S.XCast a c x -> C.XCast a (toCoreC c) (toCoreX x)
S.XType a t -> C.XType a (toCoreT t)
S.XWitness a w -> C.XWitness a (toCoreW w)
S.XDefix{} -> error "source-tetra.toCoreX: found XDefix node"
S.XInfixOp{} -> error "source-tetra.toCoreX: found XInfixOp node"
S.XInfixVar{} -> error "source-tetra.toCoreX: found XInfixVar node"
toCoreLts :: S.Lets a S.Name -> C.Lets a C.Name
toCoreLts lts
= case lts of
S.LLet b x
-> C.LLet (toCoreB b) (toCoreX x)
S.LRec bxs
-> C.LRec [(toCoreB b, toCoreX x) | (b, x) <- bxs ]
S.LPrivate bks Nothing bts
-> C.LPrivate (map toCoreB bks) Nothing (map toCoreB bts)
S.LPrivate bks (Just tParent) bts
-> C.LPrivate (map toCoreB bks)
(Just $ toCoreT tParent) (map toCoreB bts)
toCoreC :: S.Cast a S.Name -> C.Cast a C.Name
toCoreC cc
= case cc of
S.CastWeakenEffect eff -> C.CastWeakenEffect (toCoreT eff)
S.CastPurify w -> C.CastPurify (toCoreW w)
S.CastBox -> C.CastBox
S.CastRun -> C.CastRun
toCoreA :: S.Alt a S.Name -> C.Alt a C.Name
toCoreA aa
= case aa of
S.AAlt w x -> C.AAlt (toCoreP w) (toCoreX x)
toCoreP :: Pat S.Name -> Pat C.Name
toCoreP pp
= case pp of
PDefault -> PDefault
PData dc bs -> PData (toCoreDC dc) (map toCoreB bs)
toCoreDC :: DaCon S.Name -> DaCon C.Name
toCoreDC dc
= case dc of
DaConUnit
-> DaConUnit
DaConPrim n t
-> DaConPrim
{ daConName = toCoreN n
, daConType = toCoreT t }
DaConBound n
-> DaConBound (toCoreN n)
toCoreW :: Witness a S.Name -> Witness a C.Name
toCoreW ww
= case ww of
S.WVar a u -> C.WVar a (toCoreU u)
S.WCon a wc -> C.WCon a (toCoreWC wc)
S.WApp a w1 w2 -> C.WApp a (toCoreW w1) (toCoreW w2)
S.WJoin a w1 w2 -> C.WJoin a (toCoreW w1) (toCoreW w2)
S.WType a t -> C.WType a (toCoreT t)
toCoreWC :: WiCon S.Name -> WiCon C.Name
toCoreWC wc
= case wc of
WiConBuiltin wb -> WiConBuiltin wb
WiConBound u t -> WiConBound (toCoreU u) (toCoreT t)
toCoreB :: Bind S.Name -> Bind C.Name
toCoreB bb
= case bb of
BName n t -> BName (toCoreN n) (toCoreT t)
BAnon t -> BAnon (toCoreT t)
BNone t -> BNone (toCoreT t)
toCoreU :: Bound S.Name -> Bound C.Name
toCoreU uu
= case uu of
UName n -> UName (toCoreN n)
UIx i -> UIx i
UPrim n t -> UPrim (toCoreN n) (toCoreT t)
toCoreN :: S.Name -> C.Name
toCoreN nn
= case nn of
S.NameVar str -> C.NameVar str
S.NameCon str -> C.NameCon str
S.NameTyConTetra tc -> C.NameTyConTetra (toCoreTyConTetra tc)
S.NameOpStore tc -> C.NameOpStore tc
S.NamePrimTyCon p -> C.NamePrimTyCon p
S.NamePrimArith p -> C.NamePrimArith p
S.NameLitBool b -> C.NameLitBool b
S.NameLitNat n -> C.NameLitNat n
S.NameLitInt i -> C.NameLitInt i
S.NameLitWord w b -> C.NameLitWord w b
S.NameHole -> C.NameHole
toCoreTyConTetra :: S.TyConTetra -> C.TyConTetra
toCoreTyConTetra tc
= case tc of
S.TyConTetraRef -> C.TyConTetraRef
S.TyConTetraTuple n -> C.TyConTetraTuple n