language-oberon-0.3: src/Language/Oberon/AST.hs
{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, MultiParamTypeClasses, UndecidableInstances,
OverloadedStrings, StandaloneDeriving, TemplateHaskell, TypeFamilies #-}
{-# OPTIONS_GHC -Wno-simplifiable-class-constraints #-}
-- | Concrete data types for Oberon constructs that make up its Abstract Syntax Tree. Every data type from this module
-- is an instance of a type family declared in "Language.Oberon.Abstract". This way it can be replaced by another data
-- type for another language while leaving other types to be reused.
module Language.Oberon.AST (module Language.Oberon.AST, RelOp(..)) where
import Control.Applicative (ZipList(ZipList, getZipList))
import Control.Monad (forM, mapM)
import Data.Data (Data, Typeable)
import Data.List.NonEmpty (NonEmpty((:|)))
import Data.Text (Text)
import qualified Transformation
import qualified Transformation.Shallow as Shallow
import qualified Transformation.Shallow.TH
import qualified Transformation.Deep.TH
import qualified Transformation.AG as AG
import qualified Rank2.TH
import qualified Language.Oberon.Abstract as Abstract
import Language.Oberon.Abstract (RelOp(..))
-- | Data type representing the Oberon language, both versions of it.
data Language = Language deriving (Data, Typeable)
instance Abstract.Wirthy Language where
type Module Language = Module Language
type Declaration Language = Declaration Language
type Type Language = Type Language
type Statement Language = Statement Language
type Expression Language = Expression Language
type Designator Language = Designator Language
type Value Language = Value Language
type Import Language = Import Language
type FieldList Language = FieldList Language
type ProcedureHeading Language = ProcedureHeading Language
type FormalParameters Language = FormalParameters Language
type FPSection Language = FPSection Language
type Block Language = Block Language
type StatementSequence Language = StatementSequence Language
type Case Language = Case Language
type CaseLabels Language = CaseLabels Language
type ConditionalBranch Language = ConditionalBranch Language
type Element Language = Element Language
type IdentDef Language = IdentDef Language
type QualIdent Language = QualIdent Language
-- Declaration
constantDeclaration = ConstantDeclaration
typeDeclaration = TypeDeclaration
variableDeclaration = VariableDeclaration
procedureDeclaration = ProcedureDeclaration
formalParameters = FormalParameters . ZipList
fpSection = FPSection
block = Block . ZipList
fieldList = FieldList
-- Type
pointerType = PointerType
procedureType = ProcedureType
typeReference = TypeReference
-- Statement
assignment = Assignment
caseStatement scrutinee cases = CaseStatement scrutinee (ZipList cases)
emptyStatement = EmptyStatement
exitStatement = Exit
ifStatement (branch :| branches) = If branch (ZipList branches)
loopStatement = Loop
procedureCall proc args = ProcedureCall proc (ZipList <$> args)
repeatStatement = Repeat
returnStatement = Return
whileStatement = While
conditionalBranch = ConditionalBranch
caseAlternative (c :| cs) = Case c (ZipList cs)
labelRange = LabelRange
singleLabel = SingleLabel
statementSequence = StatementSequence . ZipList
-- Expression
add = Add
and = And
divide = Divide
functionCall fun args = FunctionCall fun (ZipList args)
integerDivide = IntegerDivide
literal = Literal
modulo = Modulo
multiply = Multiply
negative = Negative
not = Not
or = Or
positive = Positive
read = Read
relation = Relation
subtract = Subtract
element = Element
range = Range
-- Value
builtin = Builtin
charCode = CharCode
false = Boolean False
integer = Integer
nil = Nil
real = Real
string = String
true = Boolean True
-- Designator
variable = Variable
field = Field
index array (i :| is) = Index array i (ZipList is)
dereference = Dereference
-- Identifier
identDef = flip IdentDef PrivateOnly
nonQualIdent = NonQualIdent
instance Abstract.CoWirthy Language where
type TargetClass Language = Abstract.Oberon2
coDeclaration (ConstantDeclaration name value) = Abstract.constantDeclaration name value
coDeclaration (TypeDeclaration name ty) = Abstract.typeDeclaration name ty
coDeclaration (VariableDeclaration name ty) = Abstract.variableDeclaration name ty
coDeclaration (ProcedureDeclaration heading body) = Abstract.procedureDeclaration heading body
coDeclaration (ForwardDeclaration name params) = Abstract.forwardDeclaration name params
coType (TypeReference q) = Abstract.typeReference q
coType (ProcedureType params) = Abstract.procedureType params
coType (PointerType destination) = Abstract.pointerType destination
coType (ArrayType dimensions itemType) = Abstract.arrayType (getZipList dimensions) itemType
coType (RecordType baseType fields) = Abstract.recordType baseType (getZipList fields)
coStatement EmptyStatement = Abstract.emptyStatement
coStatement (Assignment destination expression) = Abstract.assignment destination expression
coStatement (ProcedureCall procedure parameters) = Abstract.procedureCall procedure $ getZipList <$> parameters
coStatement (If branch elsifs fallback) = Abstract.ifStatement (branch :| getZipList elsifs) fallback
coStatement (CaseStatement scrutinee cases fallback) = Abstract.caseStatement scrutinee (getZipList cases) fallback
coStatement (While condition body) = Abstract.whileStatement condition body
coStatement (Repeat body condition) = Abstract.repeatStatement body condition
coStatement (For index from to by body) = Abstract.forStatement index from to by body
coStatement (Loop body) = Abstract.loopStatement body
coStatement (With alternative alternatives fallback) =
Abstract.variantWithStatement (alternative :| getZipList alternatives) fallback
coStatement Exit = Abstract.exitStatement
coStatement (Return result) = Abstract.returnStatement result
coExpression (Relation op left right) = Abstract.relation op left right
coExpression (IsA scrutinee typeName) = Abstract.is scrutinee typeName
coExpression (Positive e) = Abstract.positive e
coExpression (Negative e) = Abstract.negative e
coExpression (Add left right) = Abstract.add left right
coExpression (Subtract left right) = Abstract.subtract left right
coExpression (Or left right) = Abstract.or left right
coExpression (Multiply left right) = Abstract.multiply left right
coExpression (Divide left right) = Abstract.divide left right
coExpression (IntegerDivide left right) = Abstract.integerDivide left right
coExpression (Modulo left right) = Abstract.modulo left right
coExpression (And left right) = Abstract.and left right
coExpression (Set elements) = Abstract.set (getZipList elements)
coExpression (Read var) = Abstract.read var
coExpression (FunctionCall function parameters) = Abstract.functionCall function $ getZipList parameters
coExpression (Not e) = Abstract.not e
coValue Nil = Abstract.nil
coValue (Boolean False) = Abstract.false
coValue (Boolean True) = Abstract.true
coValue (Builtin name) = Abstract.builtin name
coValue (Integer n) = Abstract.integer n
coValue (Real r) = Abstract.real r
coValue (String s) = Abstract.string s
coValue (CharCode c) = Abstract.charCode c
coDesignator (Variable q) = Abstract.variable q
coDesignator (Field record name) = Abstract.field record name
coDesignator (Index array index indexes) = Abstract.index array (index :| getZipList indexes)
coDesignator (TypeGuard scrutinee typeName) = Abstract.typeGuard scrutinee typeName
coDesignator (Dereference pointer) = Abstract.dereference pointer
instance Abstract.Nameable Language where
getProcedureName (ProcedureHeading _ iddef _) = Abstract.getIdentDefName iddef
getProcedureName (TypeBoundHeading _ _ _ _ iddef _) = Abstract.getIdentDefName iddef
getIdentDefName (IdentDef name _) = name
getNonQualIdentName (NonQualIdent name) = Just name
getNonQualIdentName _ = Nothing
isNamedVar :: Abstract.Nameable l => Ident -> Maybe (Designator Language l f f) -> Bool
isNamedVar name (Just (Variable q)) | Abstract.getNonQualIdentName q == Just name = True
isNamedVar _ _ = False
instance Abstract.Oberon Language where
type WithAlternative Language = WithAlternative Language
moduleUnit = Module
moduleImport = (,)
exported = flip IdentDef Exported
qualIdent = QualIdent
getQualIdentNames (QualIdent moduleName name) = Just (moduleName, name)
getQualIdentNames _ = Nothing
arrayType = ArrayType . ZipList
recordType base fields = RecordType base (ZipList fields)
procedureHeading = ProcedureHeading
forwardDeclaration = ForwardDeclaration
withStatement alt = With alt (ZipList []) Nothing
withAlternative = WithAlternative
is = IsA
set = Set . ZipList
typeGuard = TypeGuard
instance Abstract.Oberon2 Language where
readOnly = flip IdentDef ReadOnly
typeBoundHeading = TypeBoundHeading
forStatement = For
variantWithStatement (variant :| variants) = With variant (ZipList variants)
data Module λ l f' f = Module Ident [Import l] (f (Abstract.Block l l f' f'))
deriving instance (Typeable λ, Typeable l, Typeable f, Typeable f', Data (Abstract.Import l),
Data (f (Abstract.Block l l f' f'))) =>
Data (Module λ l f' f)
deriving instance (Show (Abstract.Import l), Show (f (Abstract.Block l l f' f'))) => Show (Module λ l f' f)
type Ident = Text
type Import l = (Maybe Ident, Ident)
data Declaration λ l f' f = ConstantDeclaration (Abstract.IdentDef l) (f (Abstract.ConstExpression l l f' f'))
| TypeDeclaration (Abstract.IdentDef l) (f (Abstract.Type l l f' f'))
| VariableDeclaration (Abstract.IdentList l) (f (Abstract.Type l l f' f'))
| ProcedureDeclaration (f (Abstract.ProcedureHeading l l f' f'))
(f (Abstract.Block l l f' f'))
| ForwardDeclaration (Abstract.IdentDef l) (Maybe (f (Abstract.FormalParameters l l f' f')))
deriving instance (Typeable λ, Typeable l, Typeable f, Typeable f',
Data (f (Abstract.Type l l f' f')), Data (f (Abstract.ConstExpression l l f' f')),
Data (f (Abstract.FormalParameters l l f' f')), Data (f (Abstract.ProcedureHeading l l f' f')),
Data (f (Abstract.Block l l f' f')), Data (Abstract.IdentDef l)) => Data (Declaration λ l f' f)
deriving instance (Show (f (Abstract.Type l l f' f')), Show (f (Abstract.ConstExpression l l f' f')),
Show (f (Abstract.FormalParameters l l f' f')), Show (f (Abstract.ProcedureHeading l l f' f')),
Show (f (Abstract.Block l l f' f')), Show (Abstract.IdentDef l)) => Show (Declaration λ l f' f)
data QualIdent l = QualIdent Ident Ident
| NonQualIdent Ident
deriving (Data, Eq, Ord, Show)
data IdentDef l = IdentDef Ident AccessMode
deriving (Data, Eq, Ord, Show)
data AccessMode = Exported | ReadOnly | PrivateOnly
deriving (Data, Eq, Ord, Show)
data Expression λ l f' f = Relation RelOp (f (Abstract.Expression l l f' f')) (f (Abstract.Expression l l f' f'))
| IsA (f (Abstract.Expression l l f' f')) (Abstract.QualIdent l)
| Positive (f (Abstract.Expression l l f' f'))
| Negative (f (Abstract.Expression l l f' f'))
| Add (f (Abstract.Expression l l f' f')) (f (Abstract.Expression l l f' f'))
| Subtract (f (Abstract.Expression l l f' f')) (f (Abstract.Expression l l f' f'))
| Or (f (Abstract.Expression l l f' f')) (f (Abstract.Expression l l f' f'))
| Multiply (f (Abstract.Expression l l f' f')) (f (Abstract.Expression l l f' f'))
| Divide (f (Abstract.Expression l l f' f')) (f (Abstract.Expression l l f' f'))
| IntegerDivide (f (Abstract.Expression l l f' f')) (f (Abstract.Expression l l f' f'))
| Modulo (f (Abstract.Expression l l f' f')) (f (Abstract.Expression l l f' f'))
| And (f (Abstract.Expression l l f' f')) (f (Abstract.Expression l l f' f'))
| Set (ZipList (f (Abstract.Element l l f' f')))
| Read (f (Abstract.Designator l l f' f'))
| FunctionCall (f (Abstract.Designator l l f' f')) (ZipList (f (Abstract.Expression l l f' f')))
| Not (f (Abstract.Expression l l f' f'))
| Literal (f (Abstract.Value l l f' f'))
deriving instance (Typeable λ, Typeable l, Typeable f, Typeable f',
Data (Abstract.QualIdent l), Data (f (Abstract.Value l l f' f')),
Data (f (Abstract.Designator l l f' f')), Data (f (Abstract.Element l l f' f')),
Data (f (Abstract.Expression l l f' f'))) =>
Data (Expression λ l f' f)
deriving instance (Show (Abstract.QualIdent l), Show (f (Abstract.Value l l f' f')), Show (f (Abstract.Designator l l f' f')),
Show (f (Abstract.Element l l f' f')), Show (f (Abstract.Expression l l f' f'))) =>
Show (Expression λ l f' f)
deriving instance (Eq (Abstract.QualIdent l), Eq (f (Abstract.Value l l f' f')),
Eq (f (Abstract.Designator l l f' f')), Eq (f (Abstract.Element l l f' f')),
Eq (f (Abstract.Expression l l f' f'))) => Eq (Expression λ l f' f)
data Element λ l f' f = Element (f (Abstract.Expression l l f' f'))
| Range (f (Abstract.Expression l l f' f')) (f (Abstract.Expression l l f' f'))
deriving instance (Typeable λ, Typeable l, Typeable f, Typeable f', Data (f (Abstract.Expression l l f' f'))) =>
Data (Element λ l f' f)
deriving instance Show (f (Abstract.Expression l l f' f')) => Show (Element λ l f' f)
deriving instance Eq (f (Abstract.Expression l l f' f')) => Eq (Element λ l f' f)
data Value λ l (f' :: * -> *) (f :: * -> *) = Boolean Bool
| Builtin Text
| CharCode Int
| Integer Integer
| Nil
| Real Double
| String Text
deriving (Eq, Show)
deriving instance (Typeable λ, Typeable l, Typeable f, Typeable f') => Data (Value λ l f' f)
data Designator λ l f' f = Variable (Abstract.QualIdent l)
| Field (f (Abstract.Designator l l f' f')) Ident
| Index (f (Abstract.Designator l l f' f'))
(f (Abstract.Expression l l f' f')) (ZipList (f (Abstract.Expression l l f' f')))
| TypeGuard (f (Abstract.Designator l l f' f')) (Abstract.QualIdent l)
| Dereference (f (Abstract.Designator l l f' f'))
deriving instance (Typeable λ, Typeable l, Typeable f, Typeable f', Data (Abstract.QualIdent l),
Data (f (Abstract.Designator l l f' f')), Data (f (Abstract.Expression l l f' f'))) =>
Data (Designator λ l f' f)
deriving instance (Show (Abstract.QualIdent l), Show (f (Abstract.Designator l l f' f')),
Show (f (Abstract.Expression l l f' f'))) => Show (Designator λ l f' f)
deriving instance (Eq (Abstract.QualIdent l), Eq (f (Abstract.Designator l l f' f')),
Eq (f (Abstract.Expression l l f' f'))) => Eq (Designator λ l f' f)
data Type λ l f' f = TypeReference (Abstract.QualIdent l)
| ArrayType (ZipList (f (Abstract.ConstExpression l l f' f'))) (f (Abstract.Type l l f' f'))
| RecordType (Maybe (Abstract.BaseType l)) (ZipList (f (Abstract.FieldList l l f' f')))
| PointerType (f (Abstract.Type l l f' f'))
| ProcedureType (Maybe (f (Abstract.FormalParameters l l f' f')))
deriving instance (Typeable λ, Typeable l, Typeable f, Typeable f', Data (Abstract.QualIdent l), Data (f (Abstract.Type l l f' f')),
Data (f (Abstract.ConstExpression l l f' f')), Data (f (Abstract.FormalParameters l l f' f')),
Data (f (Abstract.FieldList l l f' f'))) =>
Data (Type λ l f' f)
deriving instance (Show (Abstract.QualIdent l), Show (f (Abstract.Type l l f' f')),
Show (f (Abstract.ConstExpression l l f' f')), Show (f (Abstract.FormalParameters l l f' f')),
Show (f (Abstract.FieldList l l f' f'))) =>
Show (Type λ l f' f)
data FieldList λ l f' f = FieldList (Abstract.IdentList l) (f (Abstract.Type l l f' f'))
deriving instance (Typeable λ, Typeable l, Typeable f, Typeable f', Data (Abstract.IdentDef l), Data (f (Abstract.Type l l f' f')),
Data (f (Abstract.Expression l l f' f'))) => Data (FieldList λ l f' f)
deriving instance (Show (Abstract.IdentDef l), Show (f (Abstract.Type l l f' f')), Show (f (Abstract.Expression l l f' f'))) =>
Show (FieldList λ l f' f)
data ProcedureHeading λ l f' f =
ProcedureHeading Bool (Abstract.IdentDef l) (Maybe (f (Abstract.FormalParameters l l f' f')))
| TypeBoundHeading Bool Ident Ident Bool (Abstract.IdentDef l) (Maybe (f (Abstract.FormalParameters l l f' f')))
data FormalParameters λ l f' f = FormalParameters (ZipList (f (Abstract.FPSection l l f' f'))) (Maybe (Abstract.ReturnType l))
data FPSection λ l f' f = FPSection Bool [Ident] (f (Abstract.Type l l f' f'))
deriving instance (Typeable λ, Typeable l, Typeable f, Typeable f', Data (Abstract.IdentDef l),
Data (f (Abstract.FormalParameters l l f' f'))) => Data (ProcedureHeading λ l f' f)
deriving instance (Show (Abstract.IdentDef l), Show (f (Abstract.FormalParameters l l f' f'))) =>
Show (ProcedureHeading λ l f' f)
deriving instance (Typeable λ, Typeable l, Typeable f, Typeable f', Data (Abstract.ReturnType l),
Data (f (Abstract.FPSection l l f' f')), Data (f (Abstract.Expression l l f' f'))) =>
Data (FormalParameters λ l f' f)
deriving instance (Show (f (Abstract.FPSection l l f' f')), Show (Abstract.ReturnType l),
Show (f (Abstract.Expression l l f' f'))) => Show (FormalParameters λ l f' f)
deriving instance (Typeable λ, Typeable l, Typeable f, Typeable f', Data (f (Abstract.Type l l f' f')),
Data (f (Abstract.Expression l l f' f'))) => Data (FPSection λ l f' f)
deriving instance (Show (f (Abstract.Type l l f' f')), Show (f (Abstract.Expression l l f' f'))) => Show (FPSection λ l f' f)
data Block λ l f' f = Block (ZipList (f (Abstract.Declaration l l f' f'))) (Maybe (f (Abstract.StatementSequence l l f' f')))
deriving instance (Typeable λ, Typeable l, Typeable f, Typeable f', Data (f (Abstract.Declaration l l f' f')),
Data (f (Abstract.Designator l l f' f')), Data (f (Abstract.Expression l l f' f')),
Data (f (Abstract.StatementSequence l l f' f'))) =>
Data (Block λ l f' f)
deriving instance (Show (f (Abstract.Declaration l l f' f')), Show (f (Abstract.Designator l l f' f')),
Show (f (Abstract.Expression l l f' f')), Show (f (Abstract.StatementSequence l l f' f'))) =>
Show (Block λ l f' f)
newtype StatementSequence λ l f' f = StatementSequence (ZipList (f (Abstract.Statement l l f' f')))
deriving instance (Typeable λ, Typeable l, Typeable f, Typeable f', Data (f (Abstract.Statement l l f' f'))) =>
Data (StatementSequence λ l f' f)
deriving instance Show (f (Abstract.Statement l l f' f')) => Show (StatementSequence λ l f' f)
data Statement λ l f' f = EmptyStatement
| Assignment (f (Abstract.Designator l l f' f')) (f (Abstract.Expression l l f' f'))
| ProcedureCall (f (Abstract.Designator l l f' f')) (Maybe (ZipList (f (Abstract.Expression l l f' f'))))
| If (f (Abstract.ConditionalBranch l l f' f'))
(ZipList (f (Abstract.ConditionalBranch l l f' f')))
(Maybe (f (Abstract.StatementSequence l l f' f')))
| CaseStatement (f (Abstract.Expression l l f' f'))
(ZipList (f (Abstract.Case l l f' f')))
(Maybe (f (Abstract.StatementSequence l l f' f')))
| While (f (Abstract.Expression l l f' f')) (f (Abstract.StatementSequence l l f' f'))
| Repeat (f (Abstract.StatementSequence l l f' f')) (f (Abstract.Expression l l f' f'))
| For Ident (f (Abstract.Expression l l f' f')) (f (Abstract.Expression l l f' f'))
(Maybe (f (Abstract.Expression l l f' f'))) (f (Abstract.StatementSequence l l f' f')) -- Oberon2
| Loop (f (Abstract.StatementSequence l l f' f'))
| With (f (Abstract.WithAlternative l l f' f'))
(ZipList (f (Abstract.WithAlternative l l f' f')))
(Maybe (f (Abstract.StatementSequence l l f' f')))
| Exit
| Return (Maybe (f (Abstract.Expression l l f' f')))
deriving instance (Typeable λ, Typeable l, Typeable f, Typeable f',
Data (f (Abstract.Designator l l f' f')), Data (f (Abstract.Expression l l f' f')),
Data (f (Abstract.Case l l f' f')), Data (f (Abstract.WithAlternative l l f' f')),
Data (f (Abstract.ConditionalBranch l l f' f')),
Data (f (Abstract.StatementSequence l l f' f'))) => Data (Statement λ l f' f)
deriving instance (Show (f (Abstract.Designator l l f' f')), Show (f (Abstract.Expression l l f' f')),
Show (f (Abstract.Case l l f' f')), Show (f (Abstract.WithAlternative l l f' f')),
Show (f (Abstract.ConditionalBranch l l f' f')),
Show (f (Abstract.StatementSequence l l f' f'))) => Show (Statement λ l f' f)
data WithAlternative λ l f' f = WithAlternative (Abstract.QualIdent l) (Abstract.QualIdent l)
(f (Abstract.StatementSequence l l f' f'))
data Case λ l f' f = Case (f (Abstract.CaseLabels l l f' f')) (ZipList (f (Abstract.CaseLabels l l f' f')))
(f (Abstract.StatementSequence l l f' f'))
data CaseLabels λ l f' f = SingleLabel (f (Abstract.ConstExpression l l f' f'))
| LabelRange (f (Abstract.ConstExpression l l f' f')) (f (Abstract.ConstExpression l l f' f'))
data ConditionalBranch λ l f' f =
ConditionalBranch (f (Abstract.Expression l l f' f')) (f (Abstract.StatementSequence l l f' f'))
deriving instance (Typeable λ, Typeable l, Typeable f, Typeable f', Data (Abstract.QualIdent l),
Data (f (Abstract.Designator l l f' f')), Data (f (Abstract.StatementSequence l l f' f'))) =>
Data (WithAlternative λ l f' f)
deriving instance (Show (Abstract.QualIdent l), Show (f (Abstract.StatementSequence l l f' f'))) =>
Show (WithAlternative λ l f' f)
deriving instance (Typeable λ, Typeable l, Typeable f, Typeable f',
Data (f (Abstract.CaseLabels l l f' f')), Data (f (Abstract.StatementSequence l l f' f'))) =>
Data (Case λ l f' f)
deriving instance (Show (f (Abstract.CaseLabels l l f' f')), Show (f (Abstract.StatementSequence l l f' f'))) =>
Show (Case λ l f' f)
deriving instance (Typeable λ, Typeable l, Typeable f, Typeable f',
Data (f (Abstract.Expression l l f' f')), Data (f (Abstract.StatementSequence l l f' f'))) =>
Data (ConditionalBranch λ l f' f)
deriving instance (Show (f (Abstract.Expression l l f' f')), Show (f (Abstract.StatementSequence l l f' f'))) =>
Show (ConditionalBranch λ l f' f)
deriving instance (Typeable λ, Typeable l, Typeable f, Typeable f', Data (f (Abstract.ConstExpression l l f' f'))) =>
Data (CaseLabels λ l f' f)
deriving instance Show (f (Abstract.ConstExpression l l f' f')) => Show (CaseLabels λ l f' f)
$(concat <$>
(forM [Rank2.TH.deriveFunctor, Rank2.TH.deriveFoldable, Rank2.TH.deriveTraversable,
Transformation.Shallow.TH.deriveAll, Transformation.Deep.TH.deriveAll] $
\derive-> mconcat <$> mapM derive
[''Module, ''Declaration, ''Type, ''Expression, ''Value,
''Element, ''Designator, ''FieldList,
''ProcedureHeading, ''FormalParameters, ''FPSection, ''Block,
''Statement, ''StatementSequence,
''Case, ''CaseLabels, ''ConditionalBranch, ''WithAlternative]))
$(mconcat <$> mapM Rank2.TH.unsafeDeriveApply
[''Declaration, ''Type, ''Expression, ''Value,
''Element, ''Designator, ''FieldList,
''ProcedureHeading, ''FormalParameters, ''FPSection, ''Block,
''Statement, ''StatementSequence,
''Case, ''CaseLabels, ''ConditionalBranch, ''WithAlternative])