cparsing-0.1.0.0: MiniC/Representation.hs
{-# LANGUAGE FlexibleInstances, FlexibleContexts, MultiParamTypeClasses, NamedFieldPuns, DeriveDataTypeable #-}
{-# LANGUAGE StandaloneDeriving, TemplateHaskell, ImpredicativeTypes, UndecidableInstances #-}
-- | Extends 'MiniC.AST' with node information types, and class instances for AST nodes.
module MiniC.Representation where
import GHC.Generics (Generic)
import SourceCode.ASTElems
import MiniC.AST
import MiniC.SourceNotation
import SourceCode.SourceTree
import SourceCode.ToSourceTree
import SourceCode.ASTNode
import SourceCode.SourceInfo
import Data.Typeable
import Data.Data
import Data.List
import Data.Maybe
import Data.Function
import Text.Parsec hiding ((<|>), optional, many)
import Text.Parsec.PosOps
import Data.Data.Lens
import Control.Lens
import Control.Applicative
import Debug.Trace
-- | Syntactic and semantic information about an AST node
data NodeInfo src sem
= NodeInfo { _sourceInfo :: src
, _semanticInfo :: sem
}
deriving (Show, Typeable, Data)
makeLenses ''NodeInfo
-- All source info is considered equal, so in a container all AST nodes
-- with the same structure are not differentiated.
instance Eq (NodeInfo source sema) where
_ == _ = True
instance Ord (NodeInfo source sema) where
_ `compare` _ = EQ
-- | An intermediate node information that contains the source range
-- of the node and the remaining input of the parser when it started
-- parsing the element. We could only store the text from which the node
-- was parsed, but then we could not extend nodes from their children.
data BasicInfo -- ^ The node was originally in the source
= BasicInfo { _biRange :: SourceRange
, _biInput :: String
}
| InheritInfo
deriving (Eq, Ord, Typeable, Data)
$(makeLenses ''BasicInfo)
instance SourceInfo BasicInfo where
generateInfo ancestor []
= ancestor & biRange %~ rngStartAsRange
generateInfo _ children
= foldl1 unifyBasicInfo children
noNodeInfo = InheritInfo
deriving instance Typeable SourceTemplateElem
deriving instance Data SourceTemplateElem
deriving instance Typeable NodeIndex
deriving instance Data NodeIndex
-- | Gets the range of a basic info
getRange :: BasicInfo -> Maybe SourceRange
getRange = preview biRange
-- | Combines two basic infos into one
unifyBasicInfo :: BasicInfo -> BasicInfo -> BasicInfo
unifyBasicInfo (BasicInfo rng1 inp1) (BasicInfo rng2 inp2)
= BasicInfo (rng1 `srcRngUnion` rng2)
(if srcRangeBegin rng1 < srcRangeBegin rng2 then inp1 else inp2)
unifyBasicInfo bi InheritInfo = bi
unifyBasicInfo InheritInfo bi = bi
instance Show BasicInfo where
show (BasicInfo rng inp)
= shortShowRng rng ++ " '" ++ takeSourceRange (rngFromStart rng) inp ++ "'"
show InheritInfo = "<inherited>"
-- | The final meta information that can be used to pretty print the AST
data TemplateInfo
= TemplateInfo
{ _niRange :: Maybe SourceRange
, _niTemplate :: Maybe SourceTemplate
}
-- [Comment] -- ^ comments belonging
-- [Attribute] -- ^ attributes
deriving (Eq, Ord, Typeable, Data)
$(makeLenses ''TemplateInfo)
instance SourceInfo TemplateInfo where
generateInfo ancestor []
= TemplateInfo (rngStartAsRange <$> view niRange ancestor) (Just [])
generateInfo _ infs
= TemplateInfo (foldl1 (\a b -> srcRngUnion <$> a <*> b) (infs ^.. traverse.niRange))
(Just (map (\i -> NodeElem (NthChildOf i Current))
(take (length infs) [0..])))
noNodeInfo = TemplateInfo Nothing Nothing
instance Show TemplateInfo where
show (TemplateInfo rng templ) = maybe "" shortShowRng rng ++ "||" ++ maybe "" (concatMap show) templ ++ "||"
nodeTemplate :: TemplateInfo -> SourceTemplate
nodeTemplate (TemplateInfo { _niTemplate = Just t }) = t
-- * Preprocessor-handled source elements
data Comment = LineComment String
| BlockComment String
| DocComment String
data AttributeList a
= AttributeList { attributes :: [Attribute a]
, attributeInfo :: a
} deriving (Show, Eq)
data Attribute a
= Alias { attribAlias :: String
, attribInfo :: a
}
| Aligned { attribAlign :: Int
, attribInfo :: a
}
| AllocSize { attribAllocSizeArgs :: [Int]
, attribInfo :: a
}
| AlwaysInline { attribInfo :: a }
| CDecl { attribInfo :: a }
| Const { attribInfo :: a }
| Constructor { attribInfo :: a }
| Destructor { attribInfo :: a }
| Deprecated { attribInfo :: a }
| Format { attribFormatFunct :: String
, attribFormatStrArg :: Int
, attribFormatCheckArg :: Int
, attribInfo :: a
}
| Malloc { attribInfo :: a }
| Mode { attribMode :: ModeSpec
, attribInfo :: a
}
| NoInline { attribInfo :: a }
| NoReturn { attribInfo :: a }
| Optimize { attribOptArgs :: [Either String Int]
, attribInfo :: a
}
| Packed { attribInfo :: a }
| Pure { attribInfo :: a }
| RegParam { attribRegNum :: Int
, attribInfo :: a
}
| Section { attribSection :: String
, attribInfo :: a
}
| StdCall { attribInfo :: a }
| TransparentUnion { attribInfo :: a }
| Unused { attribInfo :: a }
| Used { attribInfo :: a }
| Visibility { attribVisibility :: VisibilityMode
, attribInfo :: a
}
| Weak { attribInfo :: a }
deriving (Show, Eq)
data ModeSpec = ByteMode | WordMode | PointerMode
deriving (Show, Eq)
data VisibilityMode = DefaultVisibility | HiddenVisibility | InternalVisibility | ProtectedVisibility
deriving (Show, Eq)