packages feed

uuagc-0.9.54: src-ag/TfmToVisage.ag

-- !!!! The Visage AST does not support nonterminals with type variables!
-- !!!! Type variables in data type declarations are ignored.

INCLUDE "AbstractSyntax.ag"
INCLUDE "Patterns.ag"
INCLUDE "Expression.ag"
INCLUDE "DistChildAttr.ag"

imports {
import AbstractSyntax
import VisagePatterns
import VisageSyntax
import qualified Data.Map as Map
import Data.Map (Map)
}

{
-- Maps a rule to a pair
-- Later, I expect to map to a list of rules, because we might need to unfold.


-- Checks that a certain alias is in fact a Var in the old representation of the AG system
isVar (Alias _ _ (Underscore _)) = True
isVar _ = False

type VisageRuleMap = [(String, VisageRule)]

splitVRules :: [VisageRule] -> VisageRuleMap
splitVRules vrs = concat (map unfoldvrs vrs)

unfoldvrs :: VisageRule -> VisageRuleMap
unfoldvrs vr@(VRule attrfields _ _ _ _) = zip (map (getName . fst) attrfields) (map (copyRule vr) attrfields)

copyRule :: VisageRule -> (Identifier,Identifier) -> VisageRule
copyRule (VRule attrfields _ pat expr owrt) (field,attr) = VRule attrfields attr pat expr owrt

getForField :: String -> VisageRuleMap -> [VisageRule]
getForField field xs = map snd (filter ((field ==) . fst) xs)

{-
   Delivers a map from fieldname to VisageRule with all references to others underscored.
   So, (lhs.x, rt.y, loc.z) = (0,1,2) becomes something like
   [("lhs", (lhs.x,_,_) = (0,1,2)

   At this point, we do not use this anymore.

allways :: VisageRule -> VisageRuleMap
allways vr@(VRule vrfields _ _ _ _) = zip vrfields (map (underScoreRule vr) (nub vrfields))

splitVRules :: [VisageRule] -> VisageRuleMap
splitVRules vrs = concat (map allways vrs)

underScoreRule :: VisageRule -> String -> VisageRule
underScoreRule (VRule fields pat expr owrt rule) s = VRule fields (underScore s pat) expr owrt rule

underScore :: String -> VisagePattern -> VisagePattern
underScore field (VConstr name pats) = VConstr name (map (underScore field) pats)
underScore field (VProduct pos pats) = VProduct pos (map (underScore field) pats)
underScore field vp@(VVar vfield attr)  =
   if (field == getName vfield)
   then vp
   else (VUnderscore (getPos vfield))
-- Should I recurse into the pat of VAlias?
underScore field vp@(VAlias afield attr pat) =
   if (field == getName afield)
   then vp
   else (VUnderscore (getPos afield))
underScore field vp@(VUnderscore pos) = vp

-}
}


ATTR Expression Pattern Patterns [ | | self : SELF ]

ATTR Grammar  [ || visage:{VisageGrammar} ]
ATTR Nonterminal  [ || vnont:{VisageNonterminal} ]
ATTR Nonterminals  [ || vnonts:{[VisageNonterminal]} ]
ATTR Production  [ || vprod:{VisageProduction} ]
ATTR Productions  [ || vprods:{[VisageProduction]} ]
ATTR Rule [ || vrule : {VisageRule} ]
ATTR Rules [ || vrules : {[VisageRule]} ]
ATTR Child    [ rulemap : {VisageRuleMap} || vchild:{VisageChild} ]
ATTR Children [ rulemap : {VisageRuleMap} || vchildren:{[VisageChild]} ]
ATTR Pattern [ || vpat:{VisagePattern} ]
ATTR Patterns [ || vpats: {[VisagePattern]} ]

SEM Grammar
  | Grammar
      lhs.visage = VGrammar @nonts.vnonts

SEM Nonterminals
  | Cons
      lhs.vnonts = @hd.vnont : @tl.vnonts
  | Nil
      lhs.vnonts = []

SEM Nonterminal
  | Nonterminal
      lhs.vnont = VNonterminal @nt @inh @syn @prods.vprods

SEM Productions
  | Cons
      lhs.vprods = @hd.vprod : @tl.vprods
  | Nil
      lhs.vprods = []

SEM Production
  | Production
      lhs.vprod        = VProduction @con @children.vchildren @lhsrules @locrules
      loc.splitVRules  = splitVRules @rules.vrules
      loc.locrules     = getForField "loc" @splitVRules
      loc.lhsrules     = getForField "lhs" @splitVRules
      children.rulemap = @splitVRules

SEM Children
  | Cons        lhs.vchildren = @hd.vchild : @tl.vchildren
  | Nil         lhs.vchildren = []

SEM Child
  | Child lhs.vchild = VChild @name @tp @loc.inh @loc.syn (getForField (getName @name) @lhs.rulemap)

SEM Rules
  | Cons        lhs.vrules = @hd.vrule : @tl.vrules
  | Nil         lhs.vrules = []

-- The undefined may seem strange, but it really belongs there.
SEM Rule
  | Rule  lhs.vrule  = VRule @pattern.fieldattrs undefined @pattern.vpat @rhs.self @owrt

SEM Patterns
  | Cons        lhs.vpats = @hd.vpat : @tl.vpats
  | Nil         lhs.vpats = []

SEM Pattern
  | Constr      lhs.vpat = VConstr @name @pats.vpats
  | Product     lhs.vpat = VProduct @pos @pats.vpats
  | Alias       lhs.vpat = if (isVar @self)
                           then VVar @field @attr
                           else VAlias @field @attr @pat.vpat
  | Underscore  lhs.vpat = VUnderscore @pos

-- All (field,attrs) in a pattern
ATTR Patterns -> Pattern [ | | fieldattrs USE { ++ } { [] } : { [(Identifier,Identifier)] } ]

SEM Pattern
  | Alias       lhs.fieldattrs = [(@field, @attr)]