{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE Strict #-} module Language.Cimple.DescribeAst ( HasLocation (..) , describeLexeme , describeNode , getLoc ) where import Data.Fix (Fix (..), foldFix, unFix) import Data.Text (Text) import qualified Data.Text as Text import Language.Cimple.Ast (Node, NodeF (..)) import qualified Language.Cimple.Flatten as Flatten import Language.Cimple.Lexer (AlexPosn (..), Lexeme (..), lexemeLine) import Language.Cimple.Tokens (LexemeClass (..)) class HasLocation a where sloc :: FilePath -> a -> Text instance HasLocation (Lexeme text) where sloc :: FilePath -> Lexeme text -> Text sloc FilePath file Lexeme text l = FilePath -> Text Text.pack FilePath file Text -> Text -> Text forall a. Semigroup a => a -> a -> a <> Text ":" Text -> Text -> Text forall a. Semigroup a => a -> a -> a <> FilePath -> Text Text.pack (Int -> FilePath forall a. Show a => a -> FilePath show (Lexeme text -> Int forall text. Lexeme text -> Int lexemeLine Lexeme text l)) instance HasLocation lexeme => HasLocation (Node lexeme) where sloc :: FilePath -> Node lexeme -> Text sloc FilePath file Node lexeme n = case (NodeF lexeme [lexeme] -> [lexeme]) -> Node lexeme -> [lexeme] forall (f :: * -> *) a. Functor f => (f a -> a) -> Fix f -> a foldFix NodeF lexeme [lexeme] -> [lexeme] forall lexeme. NodeF lexeme [lexeme] -> [lexeme] Flatten.lexemes Node lexeme n of [] -> FilePath -> Text Text.pack FilePath file Text -> Text -> Text forall a. Semigroup a => a -> a -> a <> Text ":0:0" lexeme l:[lexeme] _ -> FilePath -> lexeme -> Text forall a. HasLocation a => FilePath -> a -> Text sloc FilePath file lexeme l getLoc :: Node (Lexeme l) -> Lexeme l getLoc :: Node (Lexeme l) -> Lexeme l getLoc Node (Lexeme l) n = case (NodeF (Lexeme l) [Lexeme l] -> [Lexeme l]) -> Node (Lexeme l) -> [Lexeme l] forall (f :: * -> *) a. Functor f => (f a -> a) -> Fix f -> a foldFix NodeF (Lexeme l) [Lexeme l] -> [Lexeme l] forall lexeme. NodeF lexeme [lexeme] -> [lexeme] Flatten.lexemes Node (Lexeme l) n of [] -> FilePath -> Lexeme l forall a. HasCallStack => FilePath -> a error FilePath "getLoc: node has no lexemes" Lexeme l l:[Lexeme l] _ -> Lexeme l l describeNode :: Show a => Node a -> String describeNode :: Node a -> FilePath describeNode Node a node = case Node a -> NodeF a (Node a) forall (f :: * -> *). Fix f -> f (Fix f) unFix Node a node of PreprocIf{} -> FilePath "#if/#endif block" PreprocIfdef{} -> FilePath "#ifdef/#endif block" PreprocIfndef{} -> FilePath "#ifndef/#endif block" NodeF a (Node a) _ -> NodeF a FilePath -> FilePath forall a. Show a => a -> FilePath show (NodeF a FilePath -> FilePath) -> NodeF a FilePath -> FilePath forall a b. (a -> b) -> a -> b $ FilePath ellipsis FilePath -> NodeF a (Node a) -> NodeF a FilePath forall (f :: * -> *) a b. Functor f => a -> f b -> f a <$ Node a -> NodeF a (Node a) forall (f :: * -> *). Fix f -> f (Fix f) unFix Node a node where ellipsis :: String ellipsis :: FilePath ellipsis = FilePath "..." describeLexemeClass :: LexemeClass -> Maybe String describeLexemeClass :: LexemeClass -> Maybe FilePath describeLexemeClass = LexemeClass -> Maybe FilePath forall a. IsString a => LexemeClass -> Maybe a d where d :: LexemeClass -> Maybe a d LexemeClass IdConst = a -> Maybe a forall a. a -> Maybe a Just a "constant name" d LexemeClass IdFuncType = a -> Maybe a forall a. a -> Maybe a Just a "function type name" d LexemeClass IdStdType = a -> Maybe a forall a. a -> Maybe a Just a "standard type name" d LexemeClass IdSueType = a -> Maybe a forall a. a -> Maybe a Just a "type name" d LexemeClass IdVar = a -> Maybe a forall a. a -> Maybe a Just a "variable name" d LexemeClass LitChar = a -> Maybe a forall a. a -> Maybe a Just a "character literal" d LexemeClass LitInteger = a -> Maybe a forall a. a -> Maybe a Just a "integer literal" d LexemeClass LitString = a -> Maybe a forall a. a -> Maybe a Just a "string literal" d LexemeClass LitSysInclude = a -> Maybe a forall a. a -> Maybe a Just a "system include" d LexemeClass PctAmpersand = a -> Maybe a forall a. a -> Maybe a Just a "address-of or bitwise-and operator" d LexemeClass PctAmpersandAmpersand = a -> Maybe a forall a. a -> Maybe a Just a "logical-and operator" d LexemeClass PctAmpersandEq = a -> Maybe a forall a. a -> Maybe a Just a "bitwise-and-assign operator" d LexemeClass PctArrow = a -> Maybe a forall a. a -> Maybe a Just a "pointer-member-access operator" d LexemeClass PctAsterisk = a -> Maybe a forall a. a -> Maybe a Just a "pointer-type, dereference, or multiply operator" d LexemeClass PctAsteriskEq = a -> Maybe a forall a. a -> Maybe a Just a "multiply-assign operator" d LexemeClass PctCaret = a -> Maybe a forall a. a -> Maybe a Just a "bitwise-xor operator" d LexemeClass PctCaretEq = a -> Maybe a forall a. a -> Maybe a Just a "xor-assign operator" d LexemeClass PctColon = a -> Maybe a forall a. a -> Maybe a Just a "ternary operator" d LexemeClass PctComma = a -> Maybe a forall a. a -> Maybe a Just a "comma" d LexemeClass PctEllipsis = a -> Maybe a forall a. a -> Maybe a Just a "ellipsis" d LexemeClass PctEMark = a -> Maybe a forall a. a -> Maybe a Just a "logical not operator" d LexemeClass PctEMarkEq = a -> Maybe a forall a. a -> Maybe a Just a "not-equals operator" d LexemeClass PctEq = a -> Maybe a forall a. a -> Maybe a Just a "assignment operator" d LexemeClass PctEqEq = a -> Maybe a forall a. a -> Maybe a Just a "equals operator" d LexemeClass PctGreater = a -> Maybe a forall a. a -> Maybe a Just a "greater-than operator" d LexemeClass PctGreaterEq = a -> Maybe a forall a. a -> Maybe a Just a "greater-or-equals operator" d LexemeClass PctGreaterGreater = a -> Maybe a forall a. a -> Maybe a Just a "right-shift operator" d LexemeClass PctGreaterGreaterEq = a -> Maybe a forall a. a -> Maybe a Just a "right-shift-assign operator" d LexemeClass PctLBrace = a -> Maybe a forall a. a -> Maybe a Just a "left brace" d LexemeClass PctLBrack = a -> Maybe a forall a. a -> Maybe a Just a "left square bracket" d LexemeClass PctLess = a -> Maybe a forall a. a -> Maybe a Just a "less-than operator" d LexemeClass PctLessEq = a -> Maybe a forall a. a -> Maybe a Just a "less-or-equals operator" d LexemeClass PctLessLess = a -> Maybe a forall a. a -> Maybe a Just a "left-shift operator" d LexemeClass PctLessLessEq = a -> Maybe a forall a. a -> Maybe a Just a "left-shift-assign operator" d LexemeClass PctLParen = a -> Maybe a forall a. a -> Maybe a Just a "left parenthesis" d LexemeClass PctMinus = a -> Maybe a forall a. a -> Maybe a Just a "minus operator" d LexemeClass PctMinusEq = a -> Maybe a forall a. a -> Maybe a Just a "minus-assign operator" d LexemeClass PctMinusMinus = a -> Maybe a forall a. a -> Maybe a Just a "decrement operator" d LexemeClass PctPeriod = a -> Maybe a forall a. a -> Maybe a Just a "member access operator" d LexemeClass PctPercent = a -> Maybe a forall a. a -> Maybe a Just a "modulus operator" d LexemeClass PctPercentEq = a -> Maybe a forall a. a -> Maybe a Just a "modulus-assign operator" d LexemeClass PctPipe = a -> Maybe a forall a. a -> Maybe a Just a "bitwise-or operator" d LexemeClass PctPipeEq = a -> Maybe a forall a. a -> Maybe a Just a "bitwise-or-assign operator" d LexemeClass PctPipePipe = a -> Maybe a forall a. a -> Maybe a Just a "logical-or operator" d LexemeClass PctPlus = a -> Maybe a forall a. a -> Maybe a Just a "addition operator" d LexemeClass PctPlusEq = a -> Maybe a forall a. a -> Maybe a Just a "add-assign operator" d LexemeClass PctPlusPlus = a -> Maybe a forall a. a -> Maybe a Just a "increment operator" d LexemeClass PctQMark = a -> Maybe a forall a. a -> Maybe a Just a "ternary operator" d LexemeClass PctRBrace = a -> Maybe a forall a. a -> Maybe a Just a "right brace" d LexemeClass PctRBrack = a -> Maybe a forall a. a -> Maybe a Just a "right square bracket" d LexemeClass PctRParen = a -> Maybe a forall a. a -> Maybe a Just a "right parenthesis" d LexemeClass PctSemicolon = a -> Maybe a forall a. a -> Maybe a Just a "end of statement semicolon" d LexemeClass PctSlash = a -> Maybe a forall a. a -> Maybe a Just a "division operator" d LexemeClass PctSlashEq = a -> Maybe a forall a. a -> Maybe a Just a "divide-assign operator" d LexemeClass PctTilde = a -> Maybe a forall a. a -> Maybe a Just a "bitwise-not operator" d LexemeClass PpDefine = a -> Maybe a forall a. a -> Maybe a Just a "preprocessor define" d LexemeClass PpDefined = a -> Maybe a forall a. a -> Maybe a Just a "preprocessor defined" d LexemeClass PpElif = a -> Maybe a forall a. a -> Maybe a Just a "preprocessor elif" d LexemeClass PpElse = a -> Maybe a forall a. a -> Maybe a Just a "preprocessor else" d LexemeClass PpEndif = a -> Maybe a forall a. a -> Maybe a Just a "preprocessor endif" d LexemeClass PpIf = a -> Maybe a forall a. a -> Maybe a Just a "preprocessor if" d LexemeClass PpIfdef = a -> Maybe a forall a. a -> Maybe a Just a "preprocessor ifdef" d LexemeClass PpIfndef = a -> Maybe a forall a. a -> Maybe a Just a "preprocessor ifndef" d LexemeClass PpInclude = a -> Maybe a forall a. a -> Maybe a Just a "preprocessor include" d LexemeClass PpNewline = a -> Maybe a forall a. a -> Maybe a Just a "newline" d LexemeClass PpUndef = a -> Maybe a forall a. a -> Maybe a Just a "preprocessor undef" d LexemeClass CmtBlock = a -> Maybe a forall a. a -> Maybe a Just a "block comment" d LexemeClass CmtCommand = a -> Maybe a forall a. a -> Maybe a Just a "doxygen command" d LexemeClass CmtAttr = a -> Maybe a forall a. a -> Maybe a Just a "parameter attribute" d LexemeClass CmtEndDocSection = a -> Maybe a forall a. a -> Maybe a Just a "doxygen end-of-section" d LexemeClass CmtSpace = a -> Maybe a forall a. a -> Maybe a Just a "space in comment" d LexemeClass CmtStart = a -> Maybe a forall a. a -> Maybe a Just a "start of comment" d LexemeClass CmtStartCode = a -> Maybe a forall a. a -> Maybe a Just a "escaped comment" d LexemeClass CmtStartBlock = a -> Maybe a forall a. a -> Maybe a Just a "block comment" d LexemeClass CmtStartDoc = a -> Maybe a forall a. a -> Maybe a Just a "doxygen comment" d LexemeClass CmtStartDocSection = a -> Maybe a forall a. a -> Maybe a Just a "doxygen start-of-section" d LexemeClass CmtSpdxCopyright = a -> Maybe a forall a. a -> Maybe a Just a "SPDX Copyright" d LexemeClass CmtSpdxLicense = a -> Maybe a forall a. a -> Maybe a Just a "SPDX License" d LexemeClass CmtCode = a -> Maybe a forall a. a -> Maybe a Just a "code comment" d LexemeClass CmtWord = a -> Maybe a forall a. a -> Maybe a Just a "comment word" d LexemeClass CmtRef = a -> Maybe a forall a. a -> Maybe a Just a "comment reference" d LexemeClass CmtEnd = a -> Maybe a forall a. a -> Maybe a Just a "end of comment" d LexemeClass IgnStart = a -> Maybe a forall a. a -> Maybe a Just a "tokstyle ignore start" d LexemeClass IgnBody = a -> Maybe a forall a. a -> Maybe a Just a "tokstyle ignored code" d LexemeClass IgnEnd = a -> Maybe a forall a. a -> Maybe a Just a "tokstyle ignore end" d LexemeClass ErrorToken = a -> Maybe a forall a. a -> Maybe a Just a "lexical error" d LexemeClass Eof = a -> Maybe a forall a. a -> Maybe a Just a "end-of-file" d LexemeClass _ = Maybe a forall a. Maybe a Nothing describeLexeme :: Show a => Lexeme a -> String describeLexeme :: Lexeme a -> FilePath describeLexeme (L AlexPosn _ LexemeClass c a s) = FilePath -> (FilePath -> FilePath) -> Maybe FilePath -> FilePath forall b a. b -> (a -> b) -> Maybe a -> b maybe FilePath "" (FilePath -> FilePath -> FilePath forall a. Semigroup a => a -> a -> a <> FilePath ": ") (LexemeClass -> Maybe FilePath describeLexemeClass LexemeClass c) FilePath -> FilePath -> FilePath forall a. Semigroup a => a -> a -> a <> a -> FilePath forall a. Show a => a -> FilePath show a s