language-oberon-0.2.1: src/Language/Oberon/AST.hs
{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, MultiParamTypeClasses, UndecidableInstances,
StandaloneDeriving, TemplateHaskell #-}
{-# OPTIONS_GHC -Wno-simplifiable-class-constraints #-}
-- | Oberon Abstract Syntax Tree definitions
module Language.Oberon.AST where
import Data.Data (Data, Typeable)
import Data.Functor.Identity (Identity)
import Data.List.NonEmpty
import Data.Text (Text)
import Transformation.Deep (Product)
import qualified Transformation.Deep.TH
import qualified Rank2.TH
data Module f' f = Module Ident [Import] ([f (Declaration f' f')]) (Maybe (f (StatementSequence f' f'))) Ident
deriving instance (Typeable f, Typeable f',
Data (f (Declaration f' f')), Data (f (StatementSequence f' f'))) => Data (Module f' f)
deriving instance (Show (f (Declaration f' f')), Show (f (StatementSequence f' f'))) => Show (Module f' f)
type Ident = Text
type Import = (Maybe Ident, Ident)
data Declaration f' f = ConstantDeclaration IdentDef (f (ConstExpression f' f'))
| TypeDeclaration IdentDef (f (Type f' f'))
| VariableDeclaration IdentList (f (Type f' f'))
| ProcedureDeclaration (ProcedureHeading f' f) (ProcedureBody f' f) Ident
| ForwardDeclaration IdentDef (Maybe (f (FormalParameters f' f')))
deriving instance (Typeable f, Typeable f',
Data (f (Type f' f')), Data (f (ConstExpression f' f')), Data (f (FormalParameters f' f')),
Data (ProcedureHeading f' f), Data (ProcedureBody f' f)) => Data (Declaration f' f)
deriving instance (Show (f (Type f' f')), Show (f (ConstExpression f' f')), Show (f (FormalParameters f' f')),
Show (ProcedureHeading f' f), Show (ProcedureBody f' f)) => Show (Declaration f' f)
data IdentDef = IdentDef Ident AccessMode
deriving (Data, Eq, Ord, Show)
data AccessMode = Exported | ReadOnly | PrivateOnly
deriving (Data, Eq, Ord, Show)
type ConstExpression = Expression
data Expression f' f = Relation RelOp (f (Expression f' f')) (f (Expression f' f'))
| Positive (f (Expression f' f'))
| Negative (f (Expression f' f'))
| Add (f (Expression f' f')) (f (Expression f' f'))
| Subtract (f (Expression f' f')) (f (Expression f' f'))
| Or (f (Expression f' f')) (f (Expression f' f'))
| Multiply (f (Expression f' f')) (f (Expression f' f'))
| Divide (f (Expression f' f')) (f (Expression f' f'))
| IntegerDivide (f (Expression f' f')) (f (Expression f' f'))
| Modulo (f (Expression f' f')) (f (Expression f' f'))
| And (f (Expression f' f')) (f (Expression f' f'))
| Integer Text
| Real Text
| CharConstant Char
| CharCode Int
| String Text
| Nil
| Set [f (Element f' f')]
| Read (f (Designator f' f'))
| FunctionCall (f (Designator f' f')) [f (Expression f' f')]
| Not (f (Expression f' f'))
deriving instance (Typeable f, Typeable f', Data (f (Designator f' f')),
Data (f (Element f' f')), Data (f (Expression f' f'))) => Data (Expression f' f)
deriving instance (Show (f (Designator f' f')),
Show (f (Element f' f')), Show (f (Expression f' f'))) => Show (Expression f' f)
data RelOp = Equal | Unequal | Less | LessOrEqual | Greater | GreaterOrEqual | In | Is
deriving (Data, Show)
data Element f' f = Element (f (Expression f' f'))
| Range (f (Expression f' f')) (f (Expression f' f'))
deriving instance (Typeable f, Typeable f', Data (f (Expression f' f'))) => Data (Element f' f)
deriving instance Show (f (Expression f' f')) => Show (Element f' f)
data Designator f' f = Variable QualIdent
| Field (f (Designator f' f')) Ident
| Index (f (Designator f' f')) (NonEmpty (f (Expression f' f')))
| TypeGuard (f (Designator f' f')) QualIdent
| Dereference (f (Designator f' f'))
deriving instance (Typeable f, Typeable f', Data (f (Designator f' f')), Data (f (Expression f' f'))) =>
Data (Designator f' f)
deriving instance (Show (f (Designator f' f')), Show (f (Expression f' f'))) => Show (Designator f' f)
data Type f' f = TypeReference QualIdent
| ArrayType [f (ConstExpression f' f')] (f (Type f' f'))
| RecordType (Maybe BaseType) (NonEmpty (f (FieldList f' f')))
| PointerType (f (Type f' f'))
| ProcedureType (Maybe (f (FormalParameters f' f')))
deriving instance (Typeable f, Typeable f', Data (f (Type f' f')), Data (f (ConstExpression f' f')),
Data (f (FormalParameters f' f')), Data (f (FieldList f' f'))) => Data (Type f' f)
deriving instance (Show (f (Type f' f')), Show (f (ConstExpression f' f')),
Show (f (FormalParameters f' f')), Show (f (FieldList f' f'))) => Show (Type f' f)
data QualIdent = QualIdent Ident Ident
| NonQualIdent Ident
deriving (Data, Eq, Ord, Show)
type BaseType = QualIdent
data FieldList f' f = FieldList IdentList (f (Type f' f'))
| EmptyFieldList
deriving instance (Typeable f, Typeable f', Data (f (Type f' f')), Data (f (Expression f' f'))) => Data (FieldList f' f)
deriving instance (Show (f (Type f' f')), Show (f (Expression f' f'))) => Show (FieldList f' f)
type IdentList = NonEmpty IdentDef
data ProcedureHeading f' f =
ProcedureHeading (Maybe (Bool, Ident, Ident)) Bool IdentDef (Maybe (f (FormalParameters f' f')))
data FormalParameters f' f = FormalParameters [f (FPSection f' f')] (Maybe QualIdent)
data FPSection f' f = FPSection Bool (NonEmpty Ident) (f (Type f' f'))
deriving instance (Typeable f, Typeable f', Data (f (FormalParameters f' f'))) => Data (ProcedureHeading f' f)
deriving instance (Show (f (FormalParameters f' f'))) => Show (ProcedureHeading f' f)
deriving instance (Typeable f, Typeable f', Data (f (FPSection f' f')), Data (f (Expression f' f'))) =>
Data (FormalParameters f' f)
deriving instance (Show (f (FPSection f' f')), Show (f (Expression f' f'))) => Show (FormalParameters f' f)
deriving instance (Typeable f, Typeable f', Data (f (Type f' f')), Data (f (Expression f' f'))) =>
Data (FPSection f' f)
deriving instance (Show (f (Type f' f')), Show (f (Expression f' f'))) => Show (FPSection f' f)
data ProcedureBody f' f = ProcedureBody [f (Declaration f' f')] (Maybe (f (StatementSequence f' f')))
deriving instance (Typeable f, Typeable f', Data (f (Declaration f' f')), Data (f (Designator f' f')),
Data (f (Expression f' f')), Data (f (StatementSequence f' f'))) =>
Data (ProcedureBody f' f)
deriving instance (Show (f (Declaration f' f')), Show (f (Designator f' f')),
Show (f (Expression f' f')), Show (f (StatementSequence f' f'))) => Show (ProcedureBody f' f)
newtype StatementSequence f' f = StatementSequence (NonEmpty (f (Statement f' f')))
deriving instance (Typeable f, Typeable f', Data (f (Statement f' f'))) => Data (StatementSequence f' f)
deriving instance Show (f (Statement f' f')) => Show (StatementSequence f' f)
data Statement f' f = EmptyStatement
| Assignment (f (Designator f' f')) (f (Expression f' f'))
| ProcedureCall (f (Designator f' f')) (Maybe [f (Expression f' f')])
| If (NonEmpty (f (Product Expression StatementSequence f' f')))
(Maybe (f (StatementSequence f' f')))
| CaseStatement (f (Expression f' f'))
(NonEmpty (f (Case f' f')))
(Maybe (f (StatementSequence f' f')))
| While (f (Expression f' f')) (f (StatementSequence f' f'))
| Repeat (f (StatementSequence f' f')) (f (Expression f' f'))
| For Ident (f (Expression f' f')) (f (Expression f' f'))
(Maybe (f (Expression f' f'))) (f (StatementSequence f' f')) -- Oberon2
| Loop (f (StatementSequence f' f'))
| With (NonEmpty (f (WithAlternative f' f'))) (Maybe (f (StatementSequence f' f')))
| Exit
| Return (Maybe (f (Expression f' f')))
deriving instance (Typeable f, Typeable f', Data (f (Designator f' f')), Data (f (Expression f' f')),
Data (f (Product Expression StatementSequence f' f')),
Data (f (Case f' f')), Data (f (WithAlternative f' f')),
Data (f (Statement f' f')), Data (f (StatementSequence f' f'))) => Data (Statement f' f)
deriving instance (Show (f (Designator f' f')), Show (f (Expression f' f')),
Show (f (Product Expression StatementSequence f' f')),
Show (f (Case f' f')), Show (f (WithAlternative f' f')),
Show (f (Statement f' f')), Show (f (StatementSequence f' f'))) => Show (Statement f' f)
data WithAlternative f' f = WithAlternative QualIdent QualIdent (f (StatementSequence f' f'))
data Case f' f = Case (NonEmpty (f (CaseLabels f' f'))) (f (StatementSequence f' f'))
| EmptyCase
data CaseLabels f' f = SingleLabel (f (ConstExpression f' f'))
| LabelRange (f (ConstExpression f' f')) (f (ConstExpression f' f'))
deriving instance (Typeable f, Typeable f', Data (f (Designator f' f')), Data (f (StatementSequence f' f'))) =>
Data (WithAlternative f' f)
deriving instance (Show (f (StatementSequence f' f'))) => Show (WithAlternative f' f)
deriving instance (Typeable f, Typeable f', Data (f (CaseLabels f' f')), Data (f (StatementSequence f' f'))) =>
Data (Case f' f)
deriving instance (Show (f (CaseLabels f' f')), Show (f (StatementSequence f' f'))) => Show (Case f' f)
deriving instance (Typeable f, Typeable f', Data (f (ConstExpression f' f'))) => Data (CaseLabels f' f)
deriving instance Show (f (ConstExpression f' f')) => Show (CaseLabels f' f)
$(mconcat <$> mapM Transformation.Deep.TH.deriveAll
[''Module, ''Declaration, ''Type, ''Expression,
''Element, ''Designator, ''FieldList,
''ProcedureHeading, ''FormalParameters, ''FPSection, ''ProcedureBody,
''Statement, ''StatementSequence, ''WithAlternative, ''Case, ''CaseLabels])