{------------------------------------------------------------------------} {--- Generic stuff for all architectures. Generics.hs ---} {------------------------------------------------------------------------} {- This file is part of Cacheprof, a profiling tool for finding sources of cache misses in programs. Copyright (C) 1999 Julian Seward (jseward@acm.org) Home page: http://www.cacheprof.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. The GNU General Public License is contained in the file LICENSE. -} module Generics where internal msg = error ("\ncacheann: Internal error: " ++ msg ++ "\n") incomplete msg = error ("\ncacheann: Unhandled instruction set artefact:\n " ++ msg ++ "\n") inputerr msg = error ("\ncacheann: Bad input: " ++ msg ++ "\n") {-----------------------------------------------------------} {--- A data type for lexemes ---} {-----------------------------------------------------------} {- In here, LReg, LLiteral and LName are arch/syntax specific, but I don't think this matters, so long as the arch-specific lexer produces the Right Things. Note that lexers themselves are arch/syntax specific. -} data Lex = LReg String -- a register name eg "%eax" | LNum String -- a number "456" | LLiteral String -- a literal value "$12" | LName String -- a name "fprintf" | LLabel String -- a label ".L3345" | LComma | LLParen | LRParen | LPlus | LMinus | LStar | LDollar deriving (Show, Eq) unLReg (LReg s) = s isLReg lx = case lx of { LReg _ -> True; _ -> False } unLNum (LNum s) = s isLNum lx = case lx of { LNum _ -> True; _ -> False } unLLiteral (LLiteral s) = s isLLiteral lx = case lx of { LLiteral _ -> True; _ -> False } unLName (LName s) = s isLName lx = case lx of { LName _ -> True; _ -> False } unLLabel (LLabel s) = s isLLabel lx = case lx of { LLabel _ -> True; _ -> False } {-----------------------------------------------------------} {--- Combinator parser generics -- building blocks for ---} {--- parsers ---} {-----------------------------------------------------------} data PResult a = PFail | POk a [Lex] deriving Show type Parser a = [Lex] -> PResult a pEmpty :: a -> Parser a pEmpty x ts = POk x ts pSat :: (Lex -> Bool) -> Parser Lex pSat p [] = PFail pSat p (t:ts) = if p t then POk t ts else PFail pApply :: (a -> b) -> Parser a -> Parser b pApply f p ts = case p ts of PFail -> PFail POk x uu -> POk (f x) uu pName :: String -> a -> Parser a pName w x ((LName w2):lxs) = if w == w2 then POk x lxs else PFail pName w x _ = PFail p2 :: (a -> b -> c) -> Parser a -> Parser b -> Parser c p2 f p1 p2 ts1 = case p1 ts1 of { PFail -> PFail ; POk x1 uu1 -> case p2 uu1 of { PFail -> PFail ; POk x2 uu2 -> POk (f x1 x2) uu2 }} p3 :: (a -> b -> c -> d) -> Parser a -> Parser b -> Parser c -> Parser d p3 f p1 p2 p3 ts1 = case p1 ts1 of { PFail -> PFail ; POk x1 uu1 -> case p2 uu1 of { PFail -> PFail ; POk x2 uu2 -> case p3 uu2 of { PFail -> PFail ; POk x3 uu3 -> POk (f x1 x2 x3) uu3 }}} pStar :: Parser a -> Parser [a] pStar p ts = case p ts of PFail -> POk [] ts POk x uu1 -> case pStar p uu1 of POk xs uu2 -> POk (x:xs) uu2 PFail -> internal "pStar failed" pPlus :: Parser a -> Parser [a] pPlus p = p2 (:) p (pStar p) pAlt2 :: Parser a -> Parser a -> Parser a pAlt2 p1 p2 ts = case p1 ts of POk x1 uu -> POk x1 uu PFail -> p2 ts pAlts :: [Parser a] -> Parser a pAlts = foldl1 pAlt2 pOpt :: Parser a -> Parser (Maybe a) pOpt p ts = case p ts of PFail -> POk Nothing ts POk x uu -> POk (Just x) uu pStarComma p = pAlts [ p2 (\xs y -> xs++[y]) (pPlus (p2 (\x y -> x) p pLComma)) p, pApply (\x -> [x]) p, pEmpty [] ] pLComma = pSat (== LComma) pLMinus = pSat (== LMinus) pLPlus = pSat (== LPlus) pLLParen = pSat (== LLParen) pLRParen = pSat (== LRParen) pLStar = pSat (== LStar) pLDollar = pSat (== LDollar) pInParens p = p3 (\_ r _ -> r) pLLParen p pLRParen pPreComma p = p2 (\_ r -> r) pLComma p pPreCommaOpt p = p2 (\_ r -> r) (pOpt pLComma) p {------------------------------------------------------------------------} {--- end Generics.hs ---} {------------------------------------------------------------------------}