-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Attribute Grammars in the form of an EDSL -- -- Library of strongly typed Attribute Grammars implemented using -- type-level programming @package AspectAG @version 0.2 -- | Library for First-Class Attribute Grammars. -- -- The library is documented in the paper: Attribute Grammars Fly -- First-Class. How to do aspect oriented programming in Haskell -- -- For more documentation see the AspectAG webpage: -- http://www.cs.uu.nl/wiki/bin/view/Center/AspectAG. module Language.Grammars.AspectAG -- | Field of an attribution. type Att att val = LVPair att val -- | A Family Fam contains a single attribution p for the -- parent and a collection of attributions c for the children. data Fam c p Fam :: c -> p -> Fam c p -- | Field of the record of attributions for the children. type Chi ch atts = LVPair ch atts -- | The type Rule states that a rule takes as input the synthesized -- attributes of the children sc and the inherited attributes of -- the parent ip and returns a function from the output -- constructed thus far (inherited attributes of the children |ic| and -- synthesized attributes of the parent sp) to the extended -- output. type Rule sc ip ic sp ic' sp' = Fam sc ip -> Fam ic sp -> Fam ic' sp' -- | The function inhdef introduces a new inherited attribute for a -- collection of non-terminals. It takes the following parameters: -- att: the attribute which is being defined, nts: the -- non-terminals with which this attribute is being associated, and -- vals: a record labelled with child names and containing -- values, describing how to compute the attribute being defined at each -- of the applicable child positions. It builds a function which updates -- the output constructed thus far.|| inhdef :: (Defs att nts vals ic ic') => att -> nts -> vals -> (Fam ic sp -> Fam ic' sp) -- | The function syndef adds the definition of a synthesized -- attribute. It takes a label att representing the name of the -- new attribute, a value val to be assigned to this attribute, -- and it builds a function which updates the output constructed thus -- far. syndef :: (HExtend (Att att val) sp sp') => att -> val -> (Fam ic sp -> Fam ic sp') -- | The function inhmod modifies an inherited attribute for a -- collection of non-terminals. It takes the following parameters: -- att: the attribute which is being defined, nts: the -- non-terminals with which this attribute is being associated, and -- vals: a record labelled with child names and containing -- values, describing how to compute the attribute being defined at each -- of the applicable child positions. It builds a function which updates -- the output constructed thus far.|| inhmod :: (Mods att nts vals ic ic') => att -> nts -> vals -> (Fam ic sp -> Fam ic' sp) -- | The function synmod modifies the definition of a synthesized -- attribute. It takes a label att representing the name of the -- attribute, a value val to be assigned to this attribute, and -- it builds a function which updates the output constructed thus far. synmod :: (HUpdateAtLabel att val sp sp') => att -> val -> Fam ic sp -> Fam ic sp' -- | Composition of two rules. ext :: Rule sc ip ic' sp' ic'' sp'' -> Rule sc ip ic sp ic' sp' -> Rule sc ip ic sp ic'' sp'' class At l m v | l -> v at :: (At l m v) => l -> m v lhs :: Proxy Lhs def :: Reader (Fam chi par) a -> ((Fam chi par) -> a) inhdefM :: (Defs att nts a ic ic') => att -> nts -> Reader (Fam sc ip) a -> Rule sc ip ic sp ic' sp syndefM :: (HExtend (Att att a) sp sp') => att -> Reader (Fam sc ip) a -> Rule sc ip ic sp ic sp' inhmodM :: (Mods att nts a ic ic') => att -> nts -> Reader (Fam sc ip) a -> Rule sc ip ic sp ic' sp synmodM :: (HUpdateAtHNat n (Att att a) sp sp', HFind att ls n, RecordLabels sp ls) => att -> Reader (Fam sc ip) a -> Rule sc ip ic (Record sp) ic (Record sp') -- | Field of an aspect. It associates a production prd with a -- rule rule. type Prd prd rule = LVPair prd rule (.+.) :: (Com r r' r'') => r -> r' -> r'' -- | Semantic function of a terminal sem_Lit :: a -> Record HNil -> a -- | The function knit takes the combined rules for a node and the -- semantic functions of the children, and builds a function from the -- inherited attributes of the parent to its synthesized attributes. knit :: (Kn fc ic sc, Empties fc ec) => Rule sc ip ec (Record HNil) ic sp -> fc -> ip -> sp -- | A copy rule copies an inherited attribute from the parent to -- all its children. The function copy takes the name of an -- attribute att and an heterogeneous list of non-terminals -- nts for which the attribute has to be defined, and generates -- a copy rule for this. copy :: (Copy att nts vp ic ic', HasField att ip vp) => att -> nts -> Rule sc ip ic sp ic' sp -- | A use rule declares a synthesized attribute that collects -- information from some of the children. The function use takes -- the following arguments: the attribute to be defined, the list of -- non-terminals for which the attribute is defined, a monoidal operator -- which combines the attribute values, and a unit value to be used in -- those cases where none of the children has such an attribute. use :: (Use att nts a sc, HExtend (Att att a) sp sp') => att -> nts -> (a -> a -> a) -> a -> Rule sc ip ic sp ic sp' -- | In the chain rule a value is threaded in a depth-first way -- through the tree, being updated every now and then. For this we have -- chained attributes (both inherited and synthesized). If a definition -- for a synthesized attribute of the parent with this name is missing we -- look for the right-most child with a synthesized attribute of this -- name. If we are missing a definition for one of the children, we look -- for the right-most of its left siblings which can provide such a -- value, and if we cannot find it there, we look at the inherited -- attributes of the father. chain :: (Chain att nts val sc ic sp ic' sp', HasField att ip val) => att -> nts -> Rule sc ip ic sp ic' sp' -- | The function inhAspect defines an inherited attribute aspect. -- It takes as arguments: the name of the attribute att, the -- list nts of non-terminals where the attribute is defined, the -- list cpys of productions where the copy rule has to be -- applied, and a record defs containing the explicit definitions -- for some productions. inhAspect :: (AttAspect (FnInh att nts) defs defasp, DefAspect (FnCpy att nts) cpys cpyasp, Com cpyasp defasp inhasp) => att -> nts -> cpys -> defs -> inhasp -- | The function synAspect defines a synthesized attribute aspect. synAspect :: (AttAspect (FnSyn att) defs defasp, DefAspect (FnUse att nts op unit) uses useasp, Com useasp defasp synasp) => att -> nts -> op -> unit -> uses -> defs -> synasp -- | A chained attribute definition introduces both an inherited and a -- synthesized attribute. In this case the pattern to be applied is the -- chain rule. chnAspect :: (DefAspect (FnChn att nts) chns chnasp, AttAspect (FnInh att nts) inhdefs inhasp, Com chnasp inhasp asp, AttAspect (FnSyn att) syndefs synasp, Com asp synasp asp') => att -> nts -> chns -> inhdefs -> syndefs -> asp' attAspect :: (AttAspect rdef defs rules) => rdef -> defs -> rules defAspect :: (DefAspect deff prds rules) => deff -> prds -> rules instance (RecordLabels r ls, HFind l ls n, HUpdateAtHNat n (LVPair l v) r r') => HUpdateAtLabel l v (Record r) (Record r') instance HasLabel l HNil HFalse instance (HEq l lp b, HasLabel l r b', HOr b b' b'') => HasLabel l (HCons (LVPair lp vp) r) b'' instance (HasLabel l r b) => HasLabel l (Record r) b instance (Chain att nts val sc ic sp ic' sp', HasField att ip val, TypeCast (Rule sc ip ic sp ic' sp') r) => Poly (FnChn att nts) r instance (Use att nts a sc, HExtend (LVPair att a) sp sp', TypeCast (Rule sc ip ic sp ic sp') r) => Poly (FnUse att nts (a -> a -> a) a) r instance (Copy att nts vp ic ic', HasField att ip vp, TypeCast (Rule sc ip ic sp ic' sp) r) => Poly (FnCpy att nts) r instance (Poly deff deff', DefAspect deff prds rules, HExtend (Prd prd deff') rules rules') => DefAspect deff (HCons prd prds) rules' instance DefAspect deff HNil (Record HNil) instance (Defs att nts vals ic ic') => Apply (FnInh att nts) (Fam sc ip -> vals) (Rule sc ip ic sp ic' sp) instance (HExtend (LVPair att val) sp sp') => Apply (FnSyn att) (Fam sc ip -> val) (Rule sc ip ic sp ic sp') instance AttAspect rdef (Record HNil) (Record HNil) instance (AttAspect rdef (Record defs) rules, Apply rdef def rule, HExtend (Prd lprd rule) rules rules') => AttAspect rdef (Record (HCons (Prd lprd def) defs)) rules' instance (HasField att sch val, HExtend (Att att val) ich ich') => ChnChi'' HTrue HFalse att val (Chi lch sch) (Chi lch ich) (Chi lch ich') instance (HasField att sch val) => ChnChi'' HTrue HTrue att val (Chi lch sch) ich ich instance (Fail (IncorrectDef att lch (UndefAtt att))) => ChnChi'' HFalse HFalse att val sch (Chi lch ich) ich' instance (Fail (IncorrectDef att lch (UndefAtt att))) => ChnChi'' HFalse HTrue att val sch (Chi lch ich) ich' instance (HasLabel att sch msch, HasLabel att ich mich, ChnChi'' msch mich att val (Chi (Proxy (lch, t)) sch) (Chi (Proxy (lch, t)) ich) pch) => ChnChi' HTrue att val (Chi (Proxy (lch, t)) sch) (Chi (Proxy (lch, t)) ich) pch instance ChnChi' HFalse att val sch ich ich instance (ChnChi att nts val (Record scs) (Record ics) ics', HMember (Proxy t) nts mnts, ChnChi' mnts att val (Chi (Proxy (lch, t)) sch) (Chi (Proxy (lch, t)) ich) pch, HExtend pch ics' ic) => ChnChi att nts val (Record (HCons (Chi (Proxy (lch, t)) sch) scs)) (Record (HCons (Chi (Proxy (lch, t)) ich) ics)) ic instance ChnChi att nts val (Record HNil) (Record HNil) (Record HNil) instance (ChnChi att nts val sc ic ic') => Chain' HTrue att nts val sc ic sp ic' sp instance (ChnChi att nts val sc ic ic', HExtend (Att att val) sp sp') => Chain' HFalse att nts val sc ic sp ic' sp' instance (Chain' msp att nts val sc ic sp ic' sp', HasLabel att sp msp) => Chain att nts val sc ic sp ic' sp' instance (Use att nts a scr) => Use' HFalse att nts a (HCons (LVPair lch b) scr) instance (HasField att (Record vch) a, Use att nts a scr) => Use' HTrue att nts a (HCons (LVPair lch (Record vch)) scr) instance (HMember (Proxy t) nts mnts, Use' mnts att nts a (HCons (LVPair (Proxy (lch, t)) vch) scr)) => Use att nts a (HCons (LVPair (Proxy (lch, t)) vch) scr) instance Use l nt a HNil instance (Use att nts a sc) => Use att nts a (Record sc) instance (HExtend (Att att vp) vch vch') => Copy' HTrue HFalse att vp (Chi lch vch) (Chi lch vch') instance Copy' HTrue HTrue att vp pch pch instance Copy' HFalse mvch att vp pch pch instance (Copy att nts vp (Record ics) ics', HMember (Proxy t) nts mnts, HasLabel att vch mvch, Copy' mnts mvch att vp (Chi (Proxy (lch, t)) vch) pch, HExtend pch ics' ic) => Copy att nts vp (Record (HCons (Chi (Proxy (lch, t)) vch) ics)) ic instance Copy att nts vp (Record HNil) (Record HNil) instance Empties HNil HNil instance (Empties fcr ecr) => Empties (HCons (Chi lch fch) fcr) (HCons (Chi lch (Record HNil)) ecr) instance (Empties fc ec) => Empties (Record fc) (Record ec) instance (Kn fcr icr scr) => Kn (HCons (Chi lch (ich -> sch)) fcr) (HCons (Chi lch ich) icr) (HCons (Chi lch sch) scr) instance Kn HNil HNil HNil instance (Kn fc ic sc) => Kn (Record fc) (Record ic) (Record sc) instance ComSingle HFalse f (Record r) (Record (HCons f r)) instance (HasField lprd r (Rule sc ip ic' sp' ic'' sp''), HUpdateAtLabel lprd (Rule sc ip ic sp ic'' sp'') r r') => ComSingle HTrue (Prd lprd (Rule sc ip ic sp ic' sp')) r r' instance (HasLabel lprd r b, ComSingle b (Prd lprd rprd) r r''', Com r''' (Record r') r'') => Com r (Record (HCons (Prd lprd rprd) r')) r'' instance Com r (Record HNil) r instance (MonadReader (Fam chi par) m) => At (Proxy Lhs) m par instance (HasField (Proxy (lch, nt)) chi v, MonadReader (Fam chi par) m) => At (Proxy (lch, nt)) m v instance (HasField lch ic och, HUpdateAtLabel att vch och och', HUpdateAtLabel lch och' ic ic') => SingleMod HTrue HTrue att (Chi lch vch) ic ic' instance (Fail (IncorrectMod l lch (UndefProd (lch, t)))) => SingleMod HFalse HTrue (Proxy l) (LVPair (Proxy (lch, t)) c) r r' instance (Fail (IncorrectMod l lch (UndefNT t))) => SingleMod HTrue HFalse (Proxy l) (LVPair (Proxy (lch, t)) c) r r' instance (Mods att nts (Record vs) ic ic', HasLabel (Proxy (lch, t)) ic' mch, HMember (Proxy t) nts mnts, SingleMod mch mnts att (Chi (Proxy (lch, t)) vch) ic' ic'') => Mods att nts (Record (HCons (Chi (Proxy (lch, t)) vch) vs)) ic ic'' instance Mods att nts (Record HNil) ic ic instance (HasField lch ic och, HExtend (Att att vch) och och', HUpdateAtLabel lch och' ic ic') => SingleDef HTrue HTrue att (Chi lch vch) ic ic' instance (Fail (IncorrectDef l lch (UndefProd (lch, t)))) => SingleDef HFalse HTrue (Proxy l) (LVPair (Proxy (lch, t)) c) r r' instance (Fail (IncorrectDef l lch (UndefNT t))) => SingleDef HTrue HFalse (Proxy l) (LVPair (Proxy (lch, t)) c) r r' instance (Defs att nts (Record vs) ic ic', HasLabel (Proxy (lch, t)) ic' mch, HMember (Proxy t) nts mnts, SingleDef mch mnts att (Chi (Proxy (lch, t)) vch) ic' ic'') => Defs att nts (Record (HCons (Chi (Proxy (lch, t)) vch) vs)) ic ic'' instance Defs att nts (Record HNil) ic ic module Language.Grammars.AspectAG.Derive deriveAG :: Name -> Q [Dec] attLabel :: String -> Q [Dec] attLabels :: [String] -> Q [Dec] chLabel :: String -> Name -> Q [Dec] chLabels :: [String] -> Name -> Q [Dec] typeList :: String -> String -> Q [Dec]