{-# LANGUAGE TypeFamilies
           , MultiParamTypeClasses
           , FlexibleInstances
           #-}

-- | Simple AST elements of Haskell
module Language.Haskell.Tools.AST.Representation.Names where
  
import Language.Haskell.Tools.AST.Ann (Ann(..), AnnListG(..))

data UOperator dom stage
  = UBacktickOp { _operatorName :: Ann UQualifiedName dom stage 
                } -- ^ A normal name used as an operator with backticks: @ a `mod` b @
  | UNormalOp { _operatorName :: Ann UQualifiedName dom stage 
              } -- ^ A normal operator used as an operator.

data UName dom stage
  = UParenName { _simpleName :: Ann UQualifiedName dom stage 
               } -- ^ Parenthesized name: @ foldl (+) 0 @
  | UNormalName { _simpleName :: Ann UQualifiedName dom stage 
                } -- ^ A normal, non-operator name.
  | UImplicitName { _simpleName :: Ann UQualifiedName dom stage 
                  } -- ^ Implicit name: @ ?var @

-- | Possible qualified names. Contains also implicit names.
-- Linear implicit parameter: @%x@. Non-linear implicit parameter: @?x@.
data UQualifiedName dom stage
  = UQualifiedName { _qualifiers :: AnnListG UNamePart dom stage
                  , _unqualifiedName :: Ann UNamePart dom stage
                  }

nameFromList :: AnnListG UNamePart dom stage -> UQualifiedName dom stage
nameFromList (AnnListG a xs) | not (null xs) 
  = UQualifiedName (AnnListG a (init xs)) (last xs) 
nameFromList _ = error "nameFromList: empty list"
         
-- | Parts of a qualified name.         
data UNamePart dom stage
  = UNamePart { _simpleNameStr :: String } 
               
-- | Program elements formatted as string literals (import packages, pragma texts)
data UStringNode dom stage
  = UStringNode { _stringNodeStr :: String }