ddci-core-0.2.0.1: DDCI/Core/Command/Trans.hs
module DDCI.Core.Command.Trans
( cmdTrans
, cmdTransEval)
where
import DDCI.Core.Command.Check
import DDCI.Core.Command.Eval
import DDCI.Core.Transform
import DDCI.Core.State
import DDCI.Core.IO
import DDC.Core.Eval.Env
import DDC.Core.Eval.Name
import DDC.Core.Check
import DDC.Core.Exp
import DDC.Type.Equiv
import DDC.Base.Pretty
-- | Apply the current transform to an expression.
cmdTrans :: State -> Int -> String -> IO ()
cmdTrans state lineStart str
= cmdParseCheckExp state lineStart str >>= goStore
where
-- Expression had a parse or type error.
goStore Nothing
= do return ()
-- Expression is well-typed.
goStore (Just (x, t1, eff1, clo1))
= do tr <- applyTrans state (x, t1, eff1, clo1)
case tr of
Nothing -> return ()
Just x' -> outDocLn state $ ppr x'
-- | Transform an expression, or display errors
applyTrans :: State -> (Exp () Name, Type Name, Effect Name, Closure Name) -> IO (Maybe (Exp () Name))
applyTrans state (x, t1, _eff1, _clo1)
= do let x' = applyTransformX (stateTransform state) x
case checkExp primDataDefs primKindEnv primTypeEnv x' of
Right (_, t2, eff2, clo2)
| equivT t1 t2
-- , equivT eff1 eff2 -- TODO: result can have smaller effect
-- , equivT clo1 clo2 -- TODO: result can have smaller closure
-> do return (Just x')
| otherwise
-> do putStrLn $ renderIndent $ vcat
[ text "* CRASH AND BURN: Transform is not type preserving."
, ppr x'
, text "::" <+> ppr t2
, text ":!:" <+> ppr eff2
, text ":$:" <+> ppr clo2 ]
return Nothing
Left err
-> do putStrLn $ renderIndent $ vcat
[ text "* CRASH AND BURN: Type error in transformed program."
, ppr err
, text "" ]
outDocLn state $ text "Transformed expression:"
outDocLn state $ ppr x'
return Nothing
-- | Apply the current transform to an expression, then evaluate and display the result
cmdTransEval :: State -> Int -> String -> IO ()
cmdTransEval state lineStart str
= cmdParseCheckExp state lineStart str >>= goStore
where
-- Expression had a parse or type error.
goStore Nothing
= do return ()
-- Expression is well-typed.
goStore (Just (x, t1, eff1, clo1))
= do tr <- applyTrans state (x, t1, eff1, clo1)
case tr of
Nothing -> return ()
Just x'
-> do outDocLn state $ ppr x'
evalExp state (x',t1,eff1,clo1)
return ()