packages feed

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