{-# LANGUAGE DeriveAnyClass, DeriveGeneric, DeriveDataTypeable #-}
module Language.Floorplan.Syntax where
import Data.Maybe (maybeToList)
type LayerID = String
type FormalID = String
type FlagID = String
type FieldID = String
data Primitive = Page | Word | Byte | Bit
deriving (Eq, Ord, Show)
lexeme2prim "page" = Just Page
lexeme2prim "pages" = Just Page
lexeme2prim "word" = Just Word
lexeme2prim "words" = Just Word
lexeme2prim "byte" = Just Byte
lexeme2prim "bytes" = Just Byte
lexeme2prim "bit" = Just Bit
lexeme2prim "bits" = Just Bit
lexeme2prim _ = Nothing
instance Read Primitive where
readsPrec _ input = case lexeme2prim input of
Just x -> [(x,"")]
Nothing -> []
data Demarc =
Enum [FlagID]
| Bits [(FieldID, SizeArith)]
| Union [Demarc]
| Seq [Demarc]
| PtrF FieldID
| PtrL LayerID
| Blob SizeArith
| Graft (LayerID, [Arg])
| Field FieldID Demarc
| Pound Demarc
| Repetition FormalID Demarc
| Layer
{ name :: LayerID
, formals :: [FormalID]
, magnitude :: Maybe SizeArith
, alignment :: Maybe SizeArith
, magAlign :: Maybe SizeArith
, contains :: [LayerID]
, rhs :: Demarc
}
deriving (Eq, Ord, Show)
free_vars :: Demarc -> [FormalID]
free_vars d@(Enum{}) = []
free_vars d@(Bits{}) = []
free_vars d@(Union ds) = concatMap free_vars ds
free_vars d@(Seq ds) = concatMap free_vars ds
free_vars d@(PtrF{}) = []
free_vars d@(PtrL{}) = []
free_vars d@(Blob{}) = []
free_vars d@(Graft{}) = []
free_vars f@(Field _ d) = free_vars d
free_vars p@(Pound d) = free_vars d
free_vars r@(Repetition f d) = f : free_vars d
free_vars d@(Layer{}) =
[ fv
| fv <- free_vars (rhs d)
, fv `notElem` formals d
]
accum :: (Demarc -> Maybe a) -> Demarc -> [a]
accum fn d@(Enum{}) = maybeToList (fn d)
accum fn d@(Bits{}) = maybeToList (fn d)
accum fn d@(Union ds) = maybeToList (fn d) ++ concatMap (accum fn) ds
accum fn d@(Seq ds) = maybeToList (fn d) ++ concatMap (accum fn) ds
accum fn d@(PtrF{}) = maybeToList (fn d)
accum fn d@(PtrL{}) = maybeToList (fn d)
accum fn d@(Blob{}) = maybeToList (fn d)
accum fn d@(Graft{}) = maybeToList (fn d)
accum fn f@(Field _ d) = maybeToList (fn f) ++ accum fn d
accum fn p@(Pound d) = maybeToList (fn p) ++ accum fn d
accum fn r@(Repetition _ d) = maybeToList (fn r) ++ accum fn d
accum fn d@(Layer{}) = maybeToList (fn d) ++ accum fn (rhs d)
countMatches :: (Demarc -> Bool) -> Demarc -> Int
countMatches fn demarc = length $ (flip accum) demarc $ \d -> if fn d then Just 1 else Nothing
fmapD :: (Demarc -> (Demarc, Bool)) -> Demarc -> (Demarc, Bool)
fmapD fncn d@(Enum{}) = fncn d
fmapD fncn d@(Bits{}) = fncn d
fmapD fncn d@(Union ds) = let ds' = map (fmapD fncn) ds
(d', b) = fncn (Union $ map fst ds')
in (d', or (b : map snd ds'))
fmapD fncn d@(Seq ds) = let ds' = map (fmapD fncn) ds
(d', b) = fncn (Seq $ map fst ds')
in (d', or (b : map snd ds'))
fmapD fncn d@(PtrF{}) = fncn d
fmapD fncn d@(PtrL{}) = fncn d
fmapD fncn d@(Blob{}) = fncn d
fmapD fncn d@(Graft{}) = fncn d
fmapD fncn (Field f d) = let (d', b') = fmapD fncn d
(d'', b'') = fncn (Field f d')
in (d'', b' || b'')
fmapD fncn (Pound d) = let (d', b') = fmapD fncn d
(d'', b'') = fncn (Pound d')
in (d'', b' || b'')
fmapD fncn (Repetition f d) = let (d', b') = fmapD fncn d
(d'', b'') = fncn (Repetition f d')
in (d'', b' || b'')
fmapD fncn d@(Layer{}) = let (rhs', b') = fmapD fncn $ rhs d
(d'', b'') = fncn (d { rhs = rhs' })
in (d'', b' || b'')
data Arg =
ArgL Literal
| ArgF FormalID
deriving (Eq, Ord, Show)
type Literal = Int
bin2int :: String -> Int
bin2int ('0':'b':xs) = let
b2i [] = 0
b2i (b:bs) = (read [b]) + (2 * b2i bs)
in b2i $ reverse xs
data LitArith =
Plus LitArith LitArith
| Minus LitArith LitArith
| Times LitArith LitArith
| Div LitArith LitArith
| Exponent LitArith LitArith
| Lit Literal
deriving (Eq, Ord, Show)
data SizeArith =
SizePlus SizeArith SizeArith
| SizeMinus SizeArith SizeArith
| SizeLit (Maybe LitArith) Primitive
deriving (Eq, Ord, Show)