packages feed

hic-0.0.0.1: src/Language/Cimple/Hic.hs

{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE RankNTypes #-}
module Language.Cimple.Hic
    ( lower
    ) where

import           Data.Fix                                  (Fix (..), foldFix)
import           Data.Maybe                                (listToMaybe,
                                                            mapMaybe)
import qualified Language.Cimple                           as C
import           Language.Cimple.Hic.Ast
import           Language.Cimple.Hic.Feature               (featureLower)
import qualified Language.Cimple.Hic.Inference.Iteration   as Iteration
import qualified Language.Cimple.Hic.Inference.Raise       as Raise
import qualified Language.Cimple.Hic.Inference.Scoped      as Scoped
import qualified Language.Cimple.Hic.Inference.TaggedUnion as TaggedUnion

-- | Lowers a Hic AST back to a standard Cimple AST.
lower :: Node lexeme -> C.Node lexeme
lower = foldFix $ \case
    CimpleNode f -> Fix f
    HicNode h    -> lowerHic h

lowerHic :: HicNode lexeme (C.Node lexeme) -> C.Node lexeme
lowerHic h =
    let features = [TaggedUnion.feature, Scoped.feature, Raise.feature, Iteration.feature]
        applyLower f = featureLower f h
    in case listToMaybe $ mapMaybe applyLower features of
        Just n  -> n
        Nothing -> error "lowerHic: No feature could lower this node"