morloc-0.33.0: library/Morloc/CodeGenerator/Internal.hs
{-|
Module : Morloc.CodeGenerator.Internal
Description : Miscellaneous backend utilities
Copyright : (c) Zebulun Arendsee, 2020
License : GPL-3
Maintainer : zbwrnz@gmail.com
Stability : experimental
-}
module Morloc.CodeGenerator.Internal
(
weaveTypes
, weaveTypesGCP
, weaveTypesGCM
, typeP2typeM
) where
import Morloc.CodeGenerator.Namespace
import qualified Morloc.Monad as MM
weaveTypes :: Maybe Type -> Type -> MorlocMonad TypeP
weaveTypes g0 t0 = case (g0 >>= langOf, langOf t0) of
(_, Nothing) -> MM.throwError . CallTheMonkeys
$ "Expected a language-specific type as the second argument"
(Just _, _) -> MM.throwError . CallTheMonkeys
$ "Expected a general type as the first argument"
(_, Just lang) -> return $ f lang g0 t0
where
f :: Lang -> Maybe Type -> Type -> TypeP
f lang (Just (UnkT (TV _ v1))) (UnkT (TV _ v2)) = UnkP (PV lang (Just v1) v2)
f lang _ (UnkT (TV _ v)) = UnkP (PV lang Nothing v)
f lang (Just (VarT (TV _ v1))) (VarT (TV _ v2)) = VarP (PV lang (Just v1) v2)
f lang _ (VarT (TV _ v2)) = VarP (PV lang Nothing v2)
f lang (Just (FunT t11 t12)) (FunT t21 t22)
= FunP (f lang (Just t11) t21) (f lang (Just t12) t22)
f lang _ (FunT t1 t2)
= FunP (f lang Nothing t1) (f lang Nothing t2)
f lang (Just (ArrT (TV _ v1) ts1)) (ArrT (TV _ v2) ts2)
= ArrP (PV lang (Just v1) v2) (zipWith (f lang) (map Just ts1) ts2)
f lang _ (ArrT (TV _ v) ts)
= ArrP (PV lang Nothing v) (map (f lang Nothing) ts)
f lang (Just (NamT _ (TV _ v1) ts1 rs1)) (NamT r2 (TV _ v2) ts2 rs2)
= NamP r2 (PV lang (Just v1) v2) (zipWith (f lang) (map Just ts1) ts2)
$ zip
(zipWith (PV lang) (map (Just . fst) rs1) (map fst rs2))
(zipWith (f lang) (map (Just . snd) rs1) (map snd rs2))
f lang _ (NamT r (TV _ v) ts rs)
= NamP r (PV lang Nothing v) (map (f lang Nothing) ts)
$ zip
(map (PV lang Nothing) (map fst rs))
(map (f lang Nothing) (map snd rs))
weaveTypesGCP :: GMeta -> CType -> MorlocMonad TypeP
weaveTypesGCP g (CType t) = weaveTypes (unGType <$> metaGType g) t
weaveTypesGCM :: GMeta -> CType -> MorlocMonad TypeM
weaveTypesGCM g (CType t) = typeP2typeM <$> weaveTypes (unGType <$> metaGType g) t
typeP2typeM :: TypeP -> TypeM
typeP2typeM f@(FunP _ _) = case decompose f of
(inputs, output) -> Function (map typeP2typeM inputs) (typeP2typeM output)
typeP2typeM (UnkP _) = Passthrough
typeP2typeM t = Native t