module Language.CIL.Types
  ( Name
  , Type  (..)
  , Expr  (..)
  , Init  (..)
  , Apply (..)
  ) where
import Language.C hiding (Name)
type Name = String
data Type
  = Void
  | Array Int Type
  | Ptr Type
  | Volatile Type                
  | Typedef Type
  | Struct [(Name, Type)]
  | Union  [(Name, Type)]
  | Enum   [(Name, Int)]
  | BitField Type [(Name, Int)]
  | StructRef  Name              
  | UnionRef   Name              
  | EnumRef    Name              
  | TypedefRef Name              
  | Function Type [Type]
  | Int8
  | Int16
  | Int32
  | Word8
  | Word16
  | Word32
  | Float
  | Double
  deriving (Show, Eq)
data Expr
  = ConstInt    Int    Position
  | ConstFloat  Double Position
  | ConstChar   Char   Position
  | ConstString String Position
  | Var    Name      Position  
  | Mul    Expr Expr Position  
  | Div    Expr Expr Position  
  | Rmd    Expr Expr Position  
  | Add    Expr Expr Position  
  | Sub    Expr Expr Position  
  | Shl    Expr Expr Position  
  | Shr    Expr Expr Position  
  | Lt     Expr Expr Position  
  | Gt     Expr Expr Position  
  | Le     Expr Expr Position  
  | Ge     Expr Expr Position  
  | Eq     Expr Expr Position  
  | Neq    Expr Expr Position  
  | And    Expr Expr Position  
  | Xor    Expr Expr Position  
  | Or     Expr Expr Position  
  | Adr    Expr      Position  
  | Ind    Expr      Position  
  | Minus  Expr      Position  
  | Comp   Expr      Position  
  | Neg    Expr      Position  
  | Cast   Type Expr Position  
  | Index  Expr Expr Position  
  | Mem    Expr Name Position  
  | MemInd Expr Name Position  
  | SizeT  Type      Position  
  | SizeE  Expr      Position  
  deriving (Show, Eq)
data Init
  = Init Expr
  | InitList [Init]
  deriving (Show, Eq)
data Apply = Apply Expr [Expr] deriving (Show, Eq)
instance Pos Expr where
  posOf a = case a of
    ConstInt   _ p -> p
    ConstFloat _ p -> p
    ConstChar  _ p -> p
    ConstString _ p -> p
    Var    _   p -> p
    Mul    _ _ p -> p 
    Div    _ _ p -> p 
    Rmd    _ _ p -> p 
    Add    _ _ p -> p 
    Sub    _ _ p -> p 
    Shl    _ _ p -> p 
    Shr    _ _ p -> p 
    Lt     _ _ p -> p 
    Gt     _ _ p -> p 
    Le     _ _ p -> p 
    Ge     _ _ p -> p 
    Eq     _ _ p -> p 
    Neq    _ _ p -> p 
    And    _ _ p -> p 
    Xor    _ _ p -> p 
    Or     _ _ p -> p 
    Adr    _   p -> p
    Ind    _   p -> p
    Minus  _   p -> p
    Comp   _   p -> p
    Neg    _   p -> p
    Cast   _ _ p -> p
    Index  _ _ p -> p
    Mem    _ _ p -> p
    MemInd _ _ p -> p
    SizeT  _   p -> p
    SizeE  _   p -> p