> {-# OPTIONS_GHC -Wall -fno-warn-unused-matches -fno-warn-name-shadowing #-} Token types: representation passed from the scanner to the parser > module SystemVerilogTokens(SV_Token(..), SV_Bit(..), SV_Number(..), > SV_Numeric_Base(..), svNumericBaseValue, > svTokenToString) where > import Position > import Error(internalError, ErrMsg) > import SystemVerilogKeywords > import Util(quote) > import PPrint > import Eval Tokens output by the lexical scanner > data SV_Token > -- reserved keyword (e.g., "begin", "function") > = SV_Token_Keyword { start_position :: Position, > end_position :: Position, > keyword :: SV_Keyword } > -- identifier (e.g., "foo", "\-=foo=-") > | SV_Token_Id { start_position :: Position, > end_position :: Position, > name :: String } > -- system identifier (e.g., "$display", "$foobar"); name including $ > | SV_Token_System_Id { start_position :: Position, > end_position :: Position, > name :: String } > -- reserved operator (e.g., "==", "&&") > | SV_Token_Symbol { start_position :: Position, > end_position :: Position, > symbol :: SV_Symbol } > -- compiler directive, e.g., `timescale; name including ` > | SV_Token_Directive { start_position :: Position, > end_position :: Position, > name :: String } > | SV_Token_Number { start_position :: Position, > end_position :: Position, > value :: SV_Number, -- numeric value > bitwidth :: Maybe Integer, -- if specified > base :: Maybe SV_Numeric_Base, -- if specified > signed :: Bool, -- 's or 'S (signed) > originalText :: String } -- from source > -- string, not including quotation marks > | SV_Token_String { start_position :: Position, > end_position :: Position, > contents :: String } > -- comment, not including // or /* .. */ > | SV_Token_Comment { start_position :: Position, > end_position :: Position, > isBlock :: Bool, > contents :: String } > | SV_Token_Error { start_position :: Position, > end_position :: Position, > errMessage :: ErrMsg } > deriving (Show) > instance PPrint SV_Token where > pPrint d p = text . show > instance Hyper SV_Token where > hyper svt b = hyper (show svt) b Bit representation for number parsing > data SV_Bit = SV_BIT_0 | SV_BIT_1 | > SV_BIT_X | SV_BIT_Z | SV_BIT_DontCare > deriving (Show) Possible bases used in number parsing > data SV_Numeric_Base > = SV_NUM_BASE_Bin > | SV_NUM_BASE_Oct > | SV_NUM_BASE_Dec > | SV_NUM_BASE_Hex > deriving (Show) > {-# SPECIALIZE svNumericBaseValue :: SV_Numeric_Base -> Integer #-} > {-# SPECIALIZE svNumericBaseValue :: SV_Numeric_Base -> Int #-} > svNumericBaseValue :: (Num num) => SV_Numeric_Base -> num > svNumericBaseValue SV_NUM_BASE_Bin = 2 > svNumericBaseValue SV_NUM_BASE_Oct = 8 > svNumericBaseValue SV_NUM_BASE_Dec = 10 > svNumericBaseValue SV_NUM_BASE_Hex = 16 Various forms of values that can be specified as literals: > data SV_Number > -- non-negative whole numbers > = SV_NUM_Integer Integer > -- non-negative real numbers > | SV_NUM_Real Double > -- repeated bit (e.g., '0 or 'x) > | SV_NUM_Repeated SV_Bit > -- value/pattern with some bits set to x or z (e.g., 'h00x0) > -- grouped into values along with the number of digits, starting > -- with the most significant bit > | SV_NUM_Mixed [(Integer, Either Integer SV_Bit)] > deriving (Show) Pretty print SV tokens, e.g., keyword "end", symbol "&" > svTokenToString :: SV_Token -> String > svTokenToString (SV_Token_Keyword { keyword = kw }) = > let (desc, ver) = (lookupDescAndVer kw svKeywordTable) > verdesc = case ver of > Verilog2001 -> "V2K" > SystemVerilog30 -> "SV 3.0" > SystemVerilog31 -> "SV 3.1" > SystemVerilog31a -> "SV 3.1a" > Bluespec38 -> "BSV 3.8" > -- _ -> "internal" > in verdesc ++ " keyword " ++ quote desc > svTokenToString (SV_Token_Id { name = nm }) = > "identifier " ++ quote nm > svTokenToString (SV_Token_System_Id { name = nm }) = > "identifier " ++ quote nm > svTokenToString (SV_Token_Symbol { symbol = sym }) = > quote (lookupDesc sym svSymbolTable) > svTokenToString (SV_Token_Directive { name = dir }) = > "directive " ++ quote dir > svTokenToString (SV_Token_Number { originalText = num }) = > "number " ++ quote num > svTokenToString (SV_Token_String { contents = str }) = > "string " ++ quote str > svTokenToString (SV_Token_Comment { isBlock = False, contents = txt }) = > "comment //" ++ txt > svTokenToString (SV_Token_Comment { isBlock = True, contents = txt }) = > "comment /*" ++ txt ++ "*/" > svTokenToString (SV_Token_Error { start_position = pos, errMessage = emsg }) = > "error" -- unsafeMessageExit serror [(pos, emsg)] Find a description of a symbol or a keyword in a table from SystemVerilogKeywords.lhs > lookupDesc :: Eq key => key -> [(key, String, anything)] -> String > lookupDesc key table = > case [s | (k, s, _) <- table, k == key] of > [desc] -> desc > [] -> internalError "SystemVerilogTokens.lookupDesc: no description" > _ -> internalError > "SystemVerilogTokens.lookupDesc: multiple descriptions" > lookupDescAndVer :: Eq key => key -> [(key, String, SV_Version)] > -> (String, SV_Version) > lookupDescAndVer key table = > case [(s, v) | (k, s, v) <- table, k == key] of > [desc] -> desc > [] -> internalError "SystemVerilogTokens.lookupDesc: no description" > _ -> internalError > "SystemVerilogTokens.lookupDesc: multiple descriptions"