module Language.SequentCore.Translate (
fromCoreExpr, fromCoreBind, fromCoreBinds, fromCoreAlt,
commandToCoreExpr, valueToCoreExpr, frameToCoreExpr,
bindToCore, bindsToCore, altToCore
) where
import Language.SequentCore.Syntax
import qualified CoreSyn as Core
import DataCon
import MkCore
fromCoreExpr :: Core.Expr b -> Command b
fromCoreExpr = go [] []
where
go binds frames expr =
case expr of
Core.Var x -> done $ Var x
Core.Lit l -> done $ Lit l
Core.App e1 e2 -> go binds (App (fromCoreExpr e2) : frames) e1
Core.Lam x e -> done $ Lam x (fromCoreExpr e)
Core.Let bs e -> go (fromCoreBind bs : binds) frames e
Core.Case e x t as -> go binds (Case x t (map fromCoreAlt as) : frames) e
Core.Cast e co -> go binds (Cast co : frames) e
Core.Tick ti e -> go binds (Tick ti : frames) e
Core.Type t -> done $ Type t
Core.Coercion co -> done $ Coercion co
where done value = mkCommand (reverse binds) value frames
fromCoreAlt :: Core.Alt b -> Alt b
fromCoreAlt (ac, bs, e) = Alt ac bs (fromCoreExpr e)
fromCoreBind :: Core.Bind b -> Bind b
fromCoreBind bind =
case bind of
Core.NonRec b e -> NonRec b (fromCoreExpr e)
Core.Rec bs -> Rec [ (b, fromCoreExpr e) | (b,e) <- bs ]
fromCoreBinds :: [Core.Bind b] -> [Bind b]
fromCoreBinds = map fromCoreBind
commandToCoreExpr :: SeqCoreCommand -> Core.CoreExpr
commandToCoreExpr cmd = foldr addLet baseExpr (cmdLet cmd)
where
addLet b e = mkCoreLet (bindToCore b) e
baseExpr = foldl (flip frameToCoreExpr)
(valueToCoreExpr (cmdValue cmd))
(cmdCont cmd)
valueToCoreExpr :: SeqCoreValue -> Core.CoreExpr
valueToCoreExpr val =
case val of
Lit l -> Core.Lit l
Var x -> Core.Var x
Lam b c -> Core.Lam b (commandToCoreExpr c)
Cons ct as -> mkCoreApps (Core.Var (dataConWorkId ct))
(map commandToCoreExpr as)
Type t -> Core.Type t
Coercion co -> Core.Coercion co
frameToCoreExpr :: SeqCoreFrame -> (Core.CoreExpr -> Core.CoreExpr)
frameToCoreExpr frame e =
case frame of
App e2 -> mkCoreApp e (commandToCoreExpr e2)
Case b t as -> Core.Case e b t (map altToCore as)
Cast co -> Core.Cast e co
Tick ti -> Core.Tick ti e
bindToCore :: SeqCoreBind -> Core.CoreBind
bindToCore bind =
case bind of
NonRec b c -> Core.NonRec b (commandToCoreExpr c)
Rec bs -> Core.Rec [ (b,commandToCoreExpr c) | (b,c) <- bs ]
bindsToCore :: [SeqCoreBind] -> [Core.CoreBind]
bindsToCore = map bindToCore
altToCore :: SeqCoreAlt -> Core.CoreAlt
altToCore (Alt ac bs c) = (ac, bs, commandToCoreExpr c)