{-# LANGUAGE ImplicitParams #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE Rank2Types #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE FlexibleContexts #-} -------------------------------------------------------------------------------- -- | -- Module : Data.Comp.PAG.Internal -- Copyright : (c) 2014 Patrick Bahr, Emil Axelsson -- License : BSD3 -- Maintainer : Patrick Bahr -- Stability : experimental -- Portability : non-portable (GHC Extensions) -- -- This module defines the types for parametric attribute grammars -- along with some utility functions. -- -------------------------------------------------------------------------------- module Data.Comp.PAG.Internal ( module Data.Comp.PAG.Internal , module I ) where import Data.Comp.Mapping import Data.Comp.Term import Data.Comp.Multi.Projection import Data.Comp.AG.Internal as I (explicit) -- | This function provides access to attributes of the immediate -- children of the current node. below :: (?below :: child -> q a, p :< q) => child -> p a below = pr . ?below -- | This function provides access to attributes of the current node above :: (?above :: q a, p :< q) => p a above = pr ?above -- | The type of semantic functions for synthesised attributes. For -- defining semantic functions use the type 'Syn', which includes the -- synthesised attribute that is defined by the semantic function into -- the available attributes. type Syn' f p q g = forall child a . (?below :: child -> p a, ?above :: p a) => f child -> q (Context g a) -- | The type of semantic functions for synthesised attributes. type Syn f p q g = (q :< p) => Syn' f p q g -- | Combines the semantic functions for two synthesised attributes to -- form a semantic function for the compound attribute consisting of -- the two original attributes. prodSyn :: (p :< c, q :< c) => Syn f c p g -> Syn f c q g -> Syn f c (p :*: q) g prodSyn sp sq t = (sp t :*: sq t) -- | Combines the semantic functions for two synthesised attributes to -- form a semantic function for the compound attribute consisting of -- the two original attributes. (|*|) :: (p :< c, q :< c) => Syn f c p g -> Syn f c q g -> Syn f c (p :*: q) g (|*|) = prodSyn -- | The type of semantic functions for inherited attributes. For -- defining semantic functions use the type 'Inh', which includes the -- inherited attribute that is defined by the semantic function into -- the available attributes. type Inh' f p q g = forall m i a . (Mapping m i, ?below :: i -> p a, ?above :: p a) => f i -> m (q (Context g a)) -- | The type of semantic functions for inherited attributes. type Inh f p q g = (q :< p) => Inh' f p q g -- | Combines the semantic functions for two inherited attributes to -- form a semantic function for the compound attribute consisting of -- the two original attributes. prodInh :: (p :< c, q :< c, Functor p, Functor q) => Inh f c p g -> Inh f c q g -> Inh f c (p :*: q) g prodInh sp sq t = prodMapWith (:*:) (fmap Hole above) (fmap Hole above) (sp t) (sq t) -- | Combines the semantic functions for two inherited attributes to -- form a semantic function for the compound attribute consisting of -- the two original attributes. (>*<) :: (p :< c, q :< c, Functor p, Functor q) => Inh f c p g -> Inh f c q g -> Inh f c (p:*:q) g (>*<) = prodInh