-- Haskel data types for the abstract syntax. -- Generated by the BNF converter. {-# LANGUAGE DeriveTraversable #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE PatternSynonyms #-} -- | The abstract syntax of language C4. module AbsC4 where import qualified Prelude as T (Char, Double, Integer, String) import qualified Prelude as C ( Eq , Ord , Show , Read , Functor , Foldable , Traversable , Int, Maybe(..) ) import Data.String type Progr = Progr' BNFC'Position data Progr' a = Program a [Dec' a] [Stm' a] -- ^ Progr ::= "int" "main" "(" ")" "{" Dec Stm "}" deriving (C.Eq, C.Ord, C.Show, C.Read, C.Functor, C.Foldable, C.Traversable) type Dec = Dec' BNFC'Position data Dec' a = Decl a (Typ' a) [Ident] -- ^ Dec ::= Typ Ident deriving (C.Eq, C.Ord, C.Show, C.Read, C.Functor, C.Foldable, C.Traversable) type Stm = Stm' BNFC'Position data Stm' a = SAss a Ident (Exp' a) -- ^ Stm ::= Ident "=" Exp ";" | SAssT a (Typ' a) Ident (Exp' a) -- ^ Stm ::= Typ Ident Exp | SBlock a [Dec' a] [Stm' a] -- ^ Stm ::= "{" Dec Stm "}" | SDec a (Dec' a) -- ^ Stm ::= Dec | SDecr a Ident -- ^ Stm ::= Ident "--" ";" | SIf a (Exp' a) (Stm' a) (Stm' a) -- ^ Stm ::= "if" "(" Exp ")" Stm "else" Stm | SIncr a Ident -- ^ Stm ::= Ident "++" ";" | SPrint a (Exp' a) -- ^ Stm ::= "printInt" "(" Exp ")" ";" | SReturn a (Exp' a) -- ^ Stm ::= "return" Exp ";" | SReturnT a (Typ' a) (Exp' a) -- ^ Stm ::= Typ Exp | SWhile a (Exp' a) (Stm' a) -- ^ Stm ::= "while" "(" Exp ")" Stm deriving (C.Eq, C.Ord, C.Show, C.Read, C.Functor, C.Foldable, C.Traversable) type Exp = Exp' BNFC'Position data Exp' a = EChar a T.Char -- ^ Exp ::= Char | EDouble a T.Double -- ^ Exp ::= Double | EInt a T.Integer -- ^ Exp ::= Integer | EOpA a (Exp' a) (Op' a) (Exp' a) -- ^ Exp ::= Exp0 Op Exp0 | EOpB a (Exp' a) (Op' a) (Exp' a) -- ^ Exp ::= Exp1 Op0 Exp1 | EOpC a (Exp' a) (Op' a) (Exp' a) -- ^ Exp ::= Exp1 Op1 Exp2 | EOpD a (Exp' a) (Op' a) (Exp' a) -- ^ Exp ::= Exp2 Op2 Exp3 | EOpE a (Exp' a) (Op' a) (Exp' a) -- ^ Exp ::= Exp1 Op Exp1 | EString a T.String -- ^ Exp ::= String | EVar a Ident -- ^ Exp ::= Ident deriving (C.Eq, C.Ord, C.Show, C.Read, C.Functor, C.Foldable, C.Traversable) type Op = Op' BNFC'Position data Op' a = OAnd a -- ^ Op ::= "&&" | OEq a -- ^ Op ::= "==" | OGt a -- ^ Op ::= ">" | OLt a -- ^ Op ::= "<" | OMinus a -- ^ Op ::= "-" | OOr a -- ^ Op ::= "||" | OPlus a -- ^ Op ::= "+" | OTimes a -- ^ Op ::= "*" deriving (C.Eq, C.Ord, C.Show, C.Read, C.Functor, C.Foldable, C.Traversable) type Typ = Typ' BNFC'Position data Typ' a = TDouble a -- ^ Typ ::= "double" | TInt a -- ^ Typ ::= "int" deriving (C.Eq, C.Ord, C.Show, C.Read, C.Functor, C.Foldable, C.Traversable) newtype Ident = Ident T.String deriving (C.Eq, C.Ord, C.Show, C.Read, Data.String.IsString) -- | Start position (line, column) of something. type BNFC'Position = C.Maybe (C.Int, C.Int) pattern BNFC'NoPosition :: BNFC'Position pattern BNFC'NoPosition = C.Nothing pattern BNFC'Position :: C.Int -> C.Int -> BNFC'Position pattern BNFC'Position line col = C.Just (line, col) -- | Get the start position of something. class HasPosition a where hasPosition :: a -> BNFC'Position instance HasPosition Progr where hasPosition = \case Program p _ _ -> p instance HasPosition Dec where hasPosition = \case Decl p _ _ -> p instance HasPosition Stm where hasPosition = \case SAss p _ _ -> p SAssT p _ _ _ -> p SBlock p _ _ -> p SDec p _ -> p SDecr p _ -> p SIf p _ _ _ -> p SIncr p _ -> p SPrint p _ -> p SReturn p _ -> p SReturnT p _ _ -> p SWhile p _ _ -> p instance HasPosition Exp where hasPosition = \case EChar p _ -> p EDouble p _ -> p EInt p _ -> p EOpA p _ _ _ -> p EOpB p _ _ _ -> p EOpC p _ _ _ -> p EOpD p _ _ _ -> p EOpE p _ _ _ -> p EString p _ -> p EVar p _ -> p instance HasPosition Op where hasPosition = \case OAnd p -> p OEq p -> p OGt p -> p OLt p -> p OMinus p -> p OOr p -> p OPlus p -> p OTimes p -> p instance HasPosition Typ where hasPosition = \case TDouble p -> p TInt p -> p