diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2015, Markus Aronsson
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Markus Aronsson nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,2 @@
+# language-vhdl
+Haskell representation of VHDL
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/language-vhdl.cabal b/language-vhdl.cabal
new file mode 100644
--- /dev/null
+++ b/language-vhdl.cabal
@@ -0,0 +1,31 @@
+-- Initial language-vhdl.cabal generated by cabal init.  For further 
+-- documentation, see http://haskell.org/cabal/users-guide/
+
+name:                language-vhdl
+version:             0.1.0.0
+synopsis:            VHDL AST and pretty printer in Haskell
+-- description:         
+license:             BSD3
+license-file:        LICENSE
+author:              Markus Aronsson <mararon@chalmers.se>
+maintainer:          mararon@chalmers.se
+-- copyright:
+homepage:            https://github.com/markus-git/language-vhdl
+description:         VHDL AST and pretty printer according to the VHDL language reference manual (2000 Edition).
+                     Working on code generator.
+category:            Language
+build-type:          Simple
+extra-source-files:  README.md
+cabal-version:       >=1.10
+
+library
+  exposed-modules:     Language.VHDL,
+                       Language.VHDL.Pretty,
+                       Language.VHDL.Syntax
+  -- other-modules:       
+  other-extensions:    StandaloneDeriving,
+                       FlexibleInstances
+  build-depends:       base   >=4 && <5,
+                       pretty >=1 && <2
+  hs-source-dirs:      src
+  default-language:    Haskell2010
diff --git a/src/Language/VHDL.hs b/src/Language/VHDL.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/VHDL.hs
@@ -0,0 +1,9 @@
+module Language.VHDL
+  ( module Language.VHDL.Syntax
+  , module Language.VHDL.Pretty
+  ) where
+
+import Language.VHDL.Syntax
+import Language.VHDL.Pretty
+
+--------------------------------------------------------------------------------
diff --git a/src/Language/VHDL/Pretty.hs b/src/Language/VHDL/Pretty.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/VHDL/Pretty.hs
@@ -0,0 +1,1126 @@
+{-# LANGUAGE StandaloneDeriving #-}
+{-# LANGUAGE FlexibleInstances  #-}
+
+module Language.VHDL.Pretty (Pretty (..)) where
+
+import Language.VHDL.Syntax
+import Text.PrettyPrint     hiding (Mode)
+
+--------------------------------------------------------------------------------
+-- * Pretty printing class
+--------------------------------------------------------------------------------
+
+class Pretty a
+  where
+    pp :: a -> Doc
+
+instance Pretty a => Pretty [a]
+  where
+    pp = hsep . map pp
+
+--------------------------------------------------------------------------------
+-- ** Pretty printing instances
+
+instance Pretty AbstractLiteral where pp = error "missing: AbstractLiteral" -- todo
+
+instance Pretty AccessTypeDefinition where
+  pp (AccessTypeDefinition s) = text "ACCESS" <+> pp s
+
+instance Pretty ActualDesignator where
+  pp (ADExpression e) = pp e
+  pp (ADSignal n)     = pp n
+  pp (ADVariable n)   = pp n
+  pp (ADFile n)       = pp n
+  pp (ADOpen)         = text "OPEN"
+
+--instance Pretty ActualParameterPart where pp = undefined
+
+instance Pretty ActualPart where
+  pp (APDesignator a) = pp a
+  pp (APFunction f a) = pp f <+> parens (pp a)
+  pp (APType t a)     = pp t <+> parens (pp a)
+
+instance Pretty AddingOperator where
+  pp (Plus)   = char '+'
+  pp (Minus)  = char '-'
+  pp (Concat) = char '&'
+
+instance Pretty Aggregate where
+  pp (Aggregate es) = parens (commaSep $ map pp es)
+
+instance Pretty AliasDeclaration where
+  pp (AliasDeclaration a sub n sig) =
+        text "ALIAS" <+> pp a
+    <+> cond (colon <+>) sub
+    <+> text "IS" <+> pp n
+    <+> cond id sig <+> semi
+
+instance Pretty AliasDesignator where
+  pp (ADIdentifier i) = pp i
+  pp (ADCharacter c)  = pp c
+  pp (ADOperator o)   = pp o
+
+instance Pretty Allocator where
+  pp (AllocSub s)  = text "NEW" <+> pp s
+  pp (AllocQual q) = text "NEW" <+> pp q
+
+instance Pretty ArchitectureBody where
+  pp (ArchitectureBody i n d s) =
+      vcat [header, indent (pp d), text "BEGIN", indent (pp s), footer]
+    where
+      header = text "ARCHITECTURE" <+> pp i
+           <+> text "OF" <+> pp n
+           <+> text "IS"
+      footer = text "END ARCITECTURE" <+> pp n <+> semi
+
+--instance Pretty ArchitectureDeclarativePart where pp = undefined
+
+--instance Pretty ArchitectureStatementPart where pp = undefined
+
+instance Pretty ArrayTypeDefinition where
+  pp (ArrU u) = pp u
+  pp (ArrC c) = pp c
+
+instance Pretty Assertion where
+  pp (Assertion c r s) = vcat [text "ASSERT" <+> pp c, report, severity]
+    where
+      report   = indent $ cond (text "REPORT" <+>) r
+      severity = indent $ cond (text "SEVERITY" <+>) s
+
+instance Pretty AssertionStatement where
+  pp (AssertionStatement l a) = label l <+> pp a <+> semi
+
+instance Pretty AssociationElement where
+  pp (AssociationElement f a) = condR (text "=>") f <+> pp a
+
+instance Pretty AssociationList where
+  pp (AssociationList as) = commaSep $ map pp as
+
+instance Pretty AttributeDeclaration where
+  pp (AttributeDeclaration i t) = text "ATTRIBUTE" <+> pp i <+> colon <+> pp t <+> semi
+
+--instance Pretty AttributeDesignator where pp = undefined
+
+instance Pretty AttributeName where
+  pp (AttributeName p s d e) = pp p <+> cond id s <+> char '\'' <+> pp d <+> cond parens e
+
+instance Pretty AttributeSpecification where
+  pp (AttributeSpecification d s e) =
+        text "ATTRIBUTE" <+> pp d
+    <+> text "OF" <+> pp s
+    <+> text "IS" <+> pp e <+> semi
+
+instance Pretty Base where pp = error "missing: Base" -- todo
+
+instance Pretty BaseSpecifier where pp = error "missing: BaseSpecifier" -- todo
+
+instance Pretty BaseUnitDeclaration where pp = error "missing: BaseUnitDeclaration" -- todo
+
+instance Pretty BasedInteger where pp = error "missing: BasedInteger" -- todo
+
+instance Pretty BasedLiteral where pp = error "missing: BasedLiteral" -- todo
+
+instance Pretty BasicCharacter where pp = error "missing: BasicCharacter" -- todo
+
+instance Pretty BasicGraphicCharacter where pp = error "missing: BasicGraphicCharacter" -- todo
+
+instance Pretty BasicIdentifier where pp = error "missing: BasicIdentifier" -- todo
+
+instance Pretty BindingIndication where
+  pp (BindingIndication e g p) =
+    vcat [condR (text "USE") e, cond id g, cond id p]
+
+instance Pretty BitStringLiteral where pp = error "missing: BitStringLiteral" -- todo
+
+instance Pretty BitValue where pp = error "missing: BitValue" -- todo
+
+instance Pretty BlockConfiguration where
+  pp (BlockConfiguration s u c) =
+    vcat [ text "FOR" <+> pp s
+         , indent (pp u)
+         , indent (pp c)
+         , text "END FOR" <+> semi]
+
+instance Pretty BlockDeclarativeItem where
+  pp (BDISubprogDecl d)  = pp d
+  pp (BDISubprogBody b)  = pp b
+  pp (BDITypeDecl t)     = pp t
+  pp (BDISubtypeDecl s)  = pp s
+  pp (BDIConstantDecl c) = pp c
+  pp (BDISignalDecl s)   = pp s
+  pp (BDISharedDecl v)   = pp v
+  pp (BDIFileDecl f)     = pp f
+  pp (BDIAliasDecl a)    = pp a
+  pp (BDICompDecl c)     = pp c
+  pp (BDIAttrDecl a)     = pp a
+  pp (BDIAttrSepc a)     = pp a
+  pp (BDIConfigSepc c)   = pp c
+  pp (BDIDisconSpec d)   = pp d
+  pp (BDIUseClause u)    = pp u
+  pp (BDIGroupTemp g)    = pp g
+  pp (BDIGroupDecl g)    = pp g
+
+--instance Pretty BlockDeclarativePart where pp = undefined
+
+instance Pretty BlockHeader where
+  pp (BlockHeader p g) =
+      vcat [go p, go g]
+    where
+      go :: (Pretty a, Pretty b) => Maybe (a, Maybe b) -> Doc
+      go (Nothing)      = empty
+      go (Just (a, mb)) = pp a $+$ cond indent mb
+
+instance Pretty BlockSpecification where
+  pp (BSArch n)  = pp n
+  pp (BSBlock l) = pp l
+  pp (BSGen l)   = pp l
+
+instance Pretty BlockStatement where
+  pp (BlockStatement l g h d s) =
+      pp l <+> colon `hangs` vcat [header, body, footer]
+    where
+      header = text "BLOCK" <+> cond parens g <+> text "IS" `hangs` (pp h $$ pp d)
+      body   = text "BEGIN" `hangs` (pp s)
+      footer = text "END BLOCK" <+> pp l
+
+--instance Pretty BlockStatementPart where pp = undefined
+
+instance Pretty CaseStatement where
+  pp (CaseStatement l e cs) =
+      cond id l <+> colon `hangs` vcat [header, body, footer]
+    where
+      header = text "CASE" <+> pp e <+> text "IS"
+      body   = indent $ vcat $ map pp cs
+      footer = text "END CASE" <+> cond id l
+
+instance Pretty CaseStatementAlternative where
+  pp (CaseStatementAlternative c ss) =
+    text "WHEN" <+> pp c <+> text "=>" `hangs` pp ss
+
+instance Pretty CharacterLiteral where
+  pp (CLit c) = char c
+
+instance Pretty Choice where
+  pp (ChoiceSimple s) = pp s
+  pp (ChoiceRange r)  = pp r
+  pp (ChoiceName n)   = pp n
+  pp (ChoiceOthers)   = text "OTHERS"
+
+instance Pretty Choices where
+  pp (Choices cs) = pipeSep $ map pp cs
+
+instance Pretty ComponentConfiguration where
+  pp (ComponentConfiguration s i c) =
+    vcat [ text "FOR" <+> pp s
+         , indent $ vcat
+           [ condR semi i
+           , cond  id c
+           ]
+         , text "END FOR" <+> semi
+         ]
+
+instance Pretty ComponentDeclaration where
+  pp (ComponentDeclaration i g p s) =
+    vcat [ text "COMPONENT" <+> pp i <+> text "IS"
+         , indent $ vcat
+           [ cond id g
+           , cond id p
+           ]
+         , text "END COMPONENT" <+> cond id s <+> semi
+         ]
+
+instance Pretty ComponentInstantiationStatement where
+  pp (ComponentInstantiationStatement l u g p) =
+    pp l <+> colon `hangs` (pp u `hangs` vcat [cond id g, cond id p])
+
+instance Pretty ComponentSpecification where
+  pp (ComponentSpecification ls n) = pp ls <+> colon <+> pp n
+
+instance Pretty CompositeTypeDefinition where
+  pp (CTDArray at)  = pp at
+  pp (CTDRecord rt) = pp rt
+
+instance Pretty ConcurrentAssertionStatement where
+  pp (ConcurrentAssertionStatement l p a) = postponed l p a
+
+instance Pretty ConcurrentProcedureCallStatement where
+  pp (ConcurrentProcedureCallStatement l p a) = postponed l p a
+
+instance Pretty ConcurrentSignalAssignmentStatement where
+  pp (CSASCond l p a)   = postponed l p a
+  pp (CSASSelect l p a) = postponed l p a
+
+instance Pretty ConcurrentStatement where
+  pp (ConBlock b)     = pp b
+  pp (ConProcess p)   = pp p
+  pp (ConProcCall c)  = pp c
+  pp (ConAssertion a) = pp a
+  pp (ConSignalAss s) = pp s
+  pp (ConComponent c) = pp c
+  pp (ConGenerate g)  = pp g
+
+--instance Pretty Condition where pp = undefined
+
+instance Pretty ConditionClause where
+  pp (ConditionClause e) = text "UNTIL" <+> pp e
+
+instance Pretty ConditionalSignalAssignment where
+  pp (ConditionalSignalAssignment t o w) = pp t <+> text "<=" <+> pp o <+> pp w <+> semi
+
+instance Pretty ConditionalWaveforms where
+  pp (ConditionalWaveforms ws (w, c)) =
+      vcat ws' $$ pp w <+> condL (text "WHEN") c
+    where
+      ws' = map (\(w, c) -> pp w <+> text "WHEN" <+> pp c <+> text "ELSE") ws
+  
+instance Pretty ConfigurationDeclaration where
+  pp (ConfigurationDeclaration i n d b) =
+    vcat [ text "CONFIGURATION" <+> pp i <+> text "OF" <+> pp n <+> text "IS"
+         , indent $ vcat
+           [ pp d
+           , pp b
+           ]
+         , text "END CONFIGURATION" <+> pp i
+         ]
+
+instance Pretty ConfigurationDeclarativeItem where
+  pp (CDIUse u)   = pp u
+  pp (CDIAttr a)  = pp a
+  pp (CDIGroup g) = pp g
+
+--instance Pretty ConfigurationDeclarativePart where pp = undefined
+
+instance Pretty ConfigurationItem where
+  pp (CIBlock b) = pp b
+  pp (CIComp c)  = pp c
+
+instance Pretty ConfigurationSpecification where
+  pp (ConfigurationSpecification s i) = text "FOR" <+> pp s <+> pp i <+> semi
+
+instance Pretty ConstantDeclaration where
+  pp (ConstantDeclaration is s e) =
+    text "CONSTANT" <+> pp is <+> colon <+> pp s <+> condL (text ":=") e
+
+instance Pretty ConstrainedArrayDefinition where
+  pp (ConstrainedArrayDefinition i s) = text "ARRAY" <+> pp i <+> text "OF" <+> pp s
+
+instance Pretty Constraint where
+  pp (CRange r) = pp r
+  pp (CIndex i) = pp i
+
+instance Pretty ContextClause where pp = error "missing: ContextClause" -- todo
+
+instance Pretty ContextItem where pp = error "missing: ContextItem" -- todo
+
+instance Pretty DecimalLiteral where pp = error "missing: DecimalLiteral" -- todo
+
+instance Pretty Declaration where
+  pp (DType t)          = pp t
+  pp (DSubtype s)       = pp s
+  pp (DObject o)        = pp o
+  pp (DAlias a)         = pp a
+  pp (DComponent c)     = pp c
+  pp (DAttribute a)     = pp a
+  pp (DGroupTemplate g) = pp g
+  pp (DGroup g)         = pp g
+  pp (DEntity e)        = pp e
+  pp (DConfiguration c) = pp c
+  pp (DSubprogram s)    = pp s
+  pp (DPackage p)       = pp p
+
+instance Pretty DelayMechanism where
+  pp (DMechTransport)  = text "TRANSPORT"
+  pp (DMechInertial e) = condL (text "REJECT") e <+> text "INERTIAL"
+
+instance Pretty DesignFile where pp = error "missing: DesignFile" -- todo
+
+instance Pretty DesignUnit where pp = error "missing: DesignUnit" -- todo
+
+instance Pretty Designator where
+  pp (DId i) = pp i
+  pp (DOp o) = pp o
+
+instance Pretty Direction where
+  pp (To)     = text "TO"
+  pp (DownTo) = text "DOWNTO"
+
+instance Pretty DisconnectionSpecification where
+  pp (DisconnectionSpecification g e) =
+    text "DISCONNECT" <+> pp g <+> text "AFTER" <+> pp e <+> semi
+
+instance Pretty DiscreteRange where
+  pp (DRSub s)   = pp s
+  pp (DRRange r) = pp r
+
+instance Pretty ElementAssociation where
+  pp (ElementAssociation c e) = condR (text "=>") c <+> pp e
+
+instance Pretty ElementDeclaration where
+  pp (ElementDeclaration is s) = pp is <+> colon <+> pp s <+> semi
+
+--instance Pretty ElementSubtypeDefinition where pp = undefined
+
+instance Pretty EntityAspect where
+  pp (EAEntity n i) = text "ENTITY" <+> pp n <+> cond parens i
+  pp (EAConfig n)   = text "CONFIGURATION" <+> pp n
+  pp (EAOpen)       = text "OPEN"
+
+instance Pretty EntityClass where
+  pp ENTITY        = text "ENTITY"
+  pp ARCHITECTURE  = text "ARCHITECTURE"
+  pp CONFIGURATION = text "CONFIGURATION"
+  pp PROCEDURE     = text "PROCEDURE"
+  pp FUNCTION      = text "FUNCTION"
+  pp PACKAGE       = text "PACKAGE"
+  pp TYPE          = text "TYPE"
+  pp SUBTYPE       = text "SUBTYPE"
+  pp CONSTANT      = text "CONSTANT"
+  pp SIGNAL        = text "SIGNAL"
+  pp VARIABLE      = text "VARIABLE"
+  pp COMPONENT     = text "COMPONENT"
+  pp LABEL         = text "LABEL"
+  pp LITERAL       = text "LITERAL"
+  pp UNITS         = text "UNITS"
+  pp GROUP         = text "GROUP"
+  pp FILE          = text "FILE"
+
+instance Pretty EntityClassEntry where
+  pp (EntityClassEntry c m) = pp c <+> when m (text "<>")
+
+--instance Pretty EntityClassEntryList where pp = undefined
+
+instance Pretty EntityDeclaration where
+  pp (EntityDeclaration i h d s) =
+    vcat [ text "ENTITY" <+> pp i <+> text "IS"
+         , indent $ vcat
+           [ pp h
+           , pp d
+           ]
+         , cond (flip hangs (text "BEGIN")) s
+         , text "END ENTITY" <+> pp i <+> semi
+         ]
+
+instance Pretty EntityDeclarativeItem where
+  pp (EDISubprogDecl s)  = pp s
+  pp (EDISubprogBody b)  = pp b
+  pp (EDITypeDecl t)     = pp t
+  pp (EDISubtypeDecl s)  = pp s
+  pp (EDIConstantDecl c) = pp c
+  pp (EDISignalDecl s)   = pp s
+  pp (EDISharedDecl s)   = pp s
+  pp (EDIFileDecl f)     = pp f
+  pp (EDIAliasDecl a)    = pp a
+  pp (EDIAttrDecl a)     = pp a
+  pp (EDIAttrSpec a)     = pp a
+  pp (EDIDiscSpec d)     = pp d
+  pp (EDIUseClause u)    = pp u
+  pp (EDIGroupTemp g)    = pp g
+  pp (EDIGroupDecl g)    = pp g
+
+--instance Pretty EntityDeclarativePart where pp = undefined
+
+instance Pretty EntityDesignator where
+  pp (EntityDesignator t s) = pp t <+> cond id s
+
+instance Pretty EntityHeader where
+  pp (EntityHeader g p) = vcat [cond indent g, cond indent p]
+
+instance Pretty EntityNameList where
+  pp (ENLDesignators es) = commaSep $ fmap pp es
+
+instance Pretty EntitySpecification where
+  pp (EntitySpecification ns c) = pp ns <+> colon <+> pp c
+
+instance Pretty EntityStatement where
+  pp (ESConcAssert a)  = pp a
+  pp (ESPassiveConc p) = pp p
+  pp (ESPassiveProc p) = pp p
+
+--instance Pretty EntityStatementPart where pp = undefined
+
+instance Pretty EntityTag where
+  pp (ETName n) = pp n
+  pp (ETChar c) = pp c
+  pp (ETOp o)   = pp o
+
+instance Pretty EnumerationLiteral where
+  pp (EId i)   = pp i
+  pp (EChar c) = pp c
+
+instance Pretty EnumerationTypeDefinition where
+  pp (EnumerationTypeDefinition es) = commaSep $ fmap pp es
+
+instance Pretty ExitStatement where
+  pp (ExitStatement l b c) =
+        condR colon l
+    <+> text "NEXT" <+> cond id b
+    <+> cond ((<+>) (text "WHEN")) c <+> semi
+
+instance Pretty Exponent where pp = error "missing: Exponent" -- todo
+
+instance Pretty Expression where
+  pp (EAnd rs)    = textSep "AND"  $ map pp rs
+  pp (EOr rs)     = textSep "OR"   $ map pp rs
+  pp (EXor rs)    = textSep "XOR"  $ map pp rs
+  pp (ENand r rs) = pp r <+> condL (text "NAND") rs
+  pp (ENor r rs)  = pp r <+> condL (text "NOR")  rs
+  pp (EXnor rs)   = textSep "XNOR" $ map pp rs
+
+instance Pretty ExtendedDigit where pp = error "missing: ExtendedDigit" -- todo
+
+instance Pretty ExtendedIdentifier where pp = error "missing: ExtendedIdentifier" -- todo
+
+instance Pretty Factor where
+  pp (FacPrim p mp) = pp p <+> condL (text "**") mp
+  pp (FacAbs p)     = text "ABS" <+> pp p
+  pp (FacNot p)     = text "NOT" <+> pp p
+
+instance Pretty FileDeclaration where
+  pp (FileDeclaration is s o) = text "FILE" <+> pp is <+> colon <+> pp s <+> cond id o <+> semi
+
+--instance Pretty FileLogicalName where pp = undefined
+
+instance Pretty FileOpenInformation where
+  pp (FileOpenInformation e n) = condL (text "OPEN") e <+> text "IS" <+> pp n
+
+instance Pretty FileTypeDefinition where
+  pp (FileTypeDefinition t) = text "FILE OF" <+> pp t
+
+--instance Pretty FloatingTypeDefinition where pp = undefined
+
+instance Pretty FormalDesignator where
+  pp (FDGeneric n)   = pp n
+  pp (FDPort n)      = pp n
+  pp (FDParameter n) = pp n
+
+--instance Pretty FormalParameterList where pp = undefined
+
+instance Pretty FormalPart where
+  pp (FPDesignator d) = pp d
+  pp (FPFunction n d) = pp n <+> parens (pp d)
+  pp (FPType t d)     = pp t <+> parens (pp d)
+
+instance Pretty FullTypeDeclaration where
+  pp (FullTypeDeclaration i t) = text "TYPE" <+> pp i <+> text "IS" <+> pp t <+> semi
+
+instance Pretty FunctionCall where
+  pp (FunctionCall n p) = pp n <+> cond parens p
+
+instance Pretty GenerateStatement where
+  pp (GenerateStatement l g d s) =
+    pp l <+> colon `hangs` vcat
+      [ pp g <+> text "GENERATE"
+      , cond indent d
+      , cond (const $ text "BEGIN") d
+      , indent $ vcat $ fmap pp s
+      , text "END GENERATE" <+> pp l <+> semi
+      ]
+
+instance Pretty GenerationScheme where
+  pp (GSFor p) = pp p
+  pp (GSIf c)  = pp c
+
+instance Pretty GenericClause where
+  pp (GenericClause ls) = text "GENERIC" <+> parens (pp ls)
+
+--instance Pretty GenericList where pp = undefined
+
+instance Pretty GenericMapAspect where
+  pp (GenericMapAspect as) = text "GENERIC MAP" <+> parens (pp as)
+
+instance Pretty GraphicCharacter where pp = error "missing: GraphicCharacter" -- todo
+
+instance Pretty GroupConstituent where
+  pp (GCName n) = pp n
+  pp (GCChar c) = pp c
+
+--instance Pretty GroupConstituentList where pp = undefined
+
+instance Pretty GroupTemplateDeclaration where
+  pp (GroupTemplateDeclaration i cs) = text "GROUP" <+> pp i <+> text "IS" <+> parens (pp cs) <+> semi
+
+instance Pretty GroupDeclaration where
+  pp (GroupDeclaration i n cs) = text "GROUP" <+> pp i <+> colon <+> pp n <+> parens (pp cs) <+> semi
+
+instance Pretty GuardedSignalSpecification where
+  pp (GuardedSignalSpecification ss t) = pp ss <+> colon <+> pp t
+
+instance Pretty Identifier where
+  pp (Ident i) = text i
+
+--instance Pretty IdentifierList where pp = undefined
+
+instance Pretty IfStatement where
+  pp (IfStatement l (tc, ts) a e) =
+    condR colon l `hangs` vcat
+      [ text "IF" <+> pp tc <+> text "THEN"
+      , vcat $ fmap (\(c, s) -> text "ELSEIF" <+> pp c <+> text "THEN" `hangs` pp s) a
+      , cond (hangs (text "ELSE")) e
+      , text "END IF" <+> cond id l <+> semi
+      ]
+
+instance Pretty IncompleteTypeDeclaration where
+  pp (IncompleteTypeDeclaration i) = text "TYPE" <+> pp i <+> semi
+
+instance Pretty IndexConstraint where
+  pp (IndexConstraint rs) = parens (commaSep $ map pp rs)
+
+instance Pretty IndexSpecification where
+  pp (ISRange r) = pp r
+  pp (ISExp e)   = pp e
+
+instance Pretty IndexSubtypeDefinition where
+  pp (IndexSubtypeDefinition t) = pp t <+> text "RANGE" <+> semi
+
+instance Pretty IndexedName where
+  pp (IndexedName p es) = pp p <+> parens (commaSep $ map pp es)
+
+instance Pretty InstantiatedUnit where
+  pp (IUComponent n) = text "COMPONENT" <+> pp n
+  pp (IUEntity n i)  = text "ENTITY" <+> pp n <+> cond parens i
+  pp (IUConfig n)    = text "CONFIGURATION" <+> pp n
+
+instance Pretty InstantiationList where
+  pp (ILLabels ls) = commaSep $ map pp ls
+  pp (ILOthers)    = text "OTHERS"
+  pp (ILAll)       = text "ALL"
+
+instance Pretty Integer where pp = integer
+
+--instance Pretty IntegerTypeDefinition where pp = undefined
+
+instance Pretty InterfaceDeclaration where
+  pp (InterfaceConstantDeclaration is s e) =
+    text "CONSTANT" <+> pp is <+> colon <+> text "IN" <+> pp s <+> condL (text ":=") e
+  pp (InterfaceSignalDeclaration is m s b e) =
+    text "SIGNAL" <+> pp is <+> colon <+> cond id m <+> pp s <+> when b (text "BUS") <+> condL (text ":=") e
+  pp (InterfaceVariableDeclaration is m s e) =
+    text "VARIABLE" <+> pp is <+> colon <+> cond id m <+> pp s <+> condL (text ":=") e
+  pp (InterfaceFileDeclaration is s) =
+    text "FILE" <+> pp is <+> colon <+> pp s
+
+--instance Pretty InterfaceElement where pp = undefined
+
+instance Pretty InterfaceList where
+  pp (InterfaceList es) = semiSep $ map pp es
+
+instance Pretty IterationScheme where
+  pp (IterWhile c) = text "WHILE" <+> pp c
+  pp (IterFor p)   = text "FOR" <+> pp p
+
+--instance Pretty Label where pp = undefined
+
+instance Pretty Letter where pp = error "missing: Letter" -- todo
+
+instance Pretty LetterOrDigit where pp = error "missing: LetterOrDigit" -- todo
+
+instance Pretty LibraryClause where pp = error "missing: LibraryClause" -- todo
+
+instance Pretty LibraryUnit where pp = error "missing: LibraryUnit" -- todo
+
+instance Pretty Literal where
+  pp (LitNum n)       = pp n
+  pp (LitEnum e)      = pp e
+  pp (LitString s)    = pp s
+  pp (LitBitString b) = pp b
+  pp (LitNull)        = text "NULL"
+
+instance Pretty LogicalName where pp = error "missing: LogicalName" -- todo
+
+instance Pretty LogicalNameList where pp = error "missing: LogicalNameList" -- todo
+
+instance Pretty LogicalOperator where
+  pp (And)  = text "AND"
+  pp (Or)   = text "OR"
+  pp (Nand) = text "NAND"
+  pp (Nor)  = text "NOR"
+  pp (Xor)  = text "XOR"
+  pp (Xnor) = text "XNOR"
+
+instance Pretty LoopStatement where
+  pp (LoopStatement l i ss) =
+    condR colon l `hangs` vcat
+      [ cond id i <+> text "LOOP"
+      , indent $ pp ss
+      , text "END LOOP" <+> cond id l <+> semi
+      ]
+
+instance Pretty MiscellaneousOperator where
+  pp (Exp) = text "**"
+  pp (Abs) = text "ABS"
+  pp (Not) = text "NOT"
+
+instance Pretty Mode where
+  pp (In)      = text "IN"
+  pp (Out)     = text "OUT"
+  pp (InOut)   = text "INOUT"
+  pp (Buffer)  = text "BUFFER"
+  pp (Linkage) = text "LINKAGE"
+
+instance Pretty MultiplyingOperator where
+  pp (Times) = char '*'
+  pp (Div)   = char '/'
+  pp (Mod)   = text "MOD"
+  pp (Rem)   = text "REM"
+
+instance Pretty Name where
+  pp (NSimple n) = pp n
+  pp (NOp o)     = pp o
+  pp (NSelect s) = pp s
+  pp (NIndex i)  = pp i
+  pp (NSlice s)  = pp s
+  pp (NAttr a)   = pp a
+
+instance Pretty NextStatement where
+  pp (NextStatement l b c) = condR colon l <+> text "NEXT" <+> cond id b <+> condL (text "WHEN") c <+> semi
+
+instance Pretty NullStatement where
+  pp (NullStatement l) = condR colon l <+> text "NULL"
+
+instance Pretty NumericLiteral where
+  pp (NLitAbstract a) = pp a
+  pp (NLitPhysical p) = pp p
+
+instance Pretty ObjectDeclaration where
+  pp (ObjConst c) = pp c
+  pp (ObjSig s)   = pp s
+  pp (ObjVar v)   = pp v
+  pp (ObjFile f)  = pp f
+
+--instance Pretty OperatorSymbol where pp = undefined
+
+instance Pretty Options where
+  pp (Options g d) = when g (text "GUARDED") <+> cond id d
+
+instance Pretty PackageBody where
+  pp (PackageBody n d) =
+    vcat [ text "PACKAGE BODY" <+> pp n <+> text "IS"
+         , indent $ pp d
+         , text "END PACKAGE BODY" <+> pp n <+> semi
+         ]
+
+instance Pretty PackageBodyDeclarativeItem where
+  pp (PBDISubprogDecl s)  = pp s
+  pp (PBDISubprogBody b)  = pp b
+  pp (PBDITypeDecl t)     = pp t
+  pp (PBDISubtypeDecl s)  = pp s
+  pp (PBDIConstantDecl c) = pp c
+  pp (PBDISharedDecl s)   = pp s
+  pp (PBDIFileDecl f)     = pp f
+  pp (PBDIAliasDecl a)    = pp a
+  pp (PBDIUseClause u)    = pp u
+  pp (PBDIGroupTemp g)    = pp g
+  pp (PBDIGroupDecl g)    = pp g
+
+--Instance Pretty PackageBodyDeclarativePart where pp = undefined
+
+instance Pretty PackageDeclaration where
+  pp (PackageDeclaration i d) =
+    vcat [ text "PACKAGE" <+> pp i <+> text "IS"
+         , indent $ pp d
+         , text "END PACKAGE" <+> pp i <+> semi
+         ]
+
+instance Pretty PackageDeclarativeItem where
+  pp (PDISubprogDecl s)  = pp s
+  pp (PDISubprogBody b)  = pp b
+  pp (PDITypeDecl t)     = pp t
+  pp (PDISubtypeDecl s)  = pp s
+  pp (PDIConstantDecl c) = pp c
+  pp (PDISignalDecl s)   = pp s
+  pp (PDISharedDecl v)   = pp v
+  pp (PDIFileDecl f)     = pp f
+  pp (PDIAliasDecl a)    = pp a
+  pp (PDICompDecl c)     = pp c
+  pp (PDIAttrDecl a)     = pp a
+  pp (PDIAttrSpec a)     = pp a
+  pp (PDIDiscSpec d)     = pp d
+  pp (PDIUseClause u)    = pp u
+  pp (PDIGroupTemp g)    = pp g
+  pp (PDIGroupDecl g)    = pp g
+  
+--instance Pretty PackageDeclarativePart where pp = undefined
+
+instance Pretty ParameterSpecification where
+  pp (ParameterSpecification i r) = pp i <+> text "IN" <+> pp r
+
+instance Pretty PhysicalLiteral where
+  pp (PhysicalLiteral a n) = cond id a <+> pp n
+
+instance Pretty PhysicalTypeDefinition where
+  pp (PhysicalTypeDefinition c p s n) =
+    pp c `hangs` vcat
+      [ text "UNITS"
+      , indent $ vcat
+        [ pp p
+        , vcat $ map pp s
+        ]
+      , text "END UNITS" <+> cond id n
+      ]
+
+instance Pretty PortClause where
+  pp (PortClause ls) = text "PORT" <+> parens (pp ls)
+
+--instance Pretty PortList where pp = undefined
+
+instance Pretty PortMapAspect where
+  pp (PortMapAspect as) = text "PORT MAP" <+> parens (pp as)
+
+instance Pretty Prefix where
+  pp (PName n) = pp n
+  pp (PFun f)  = pp f
+
+instance Pretty Primary where
+  pp (PrimName n)  = pp n
+  pp (PrimLit l)   = pp l
+  pp (PrimAgg a)   = pp a
+  pp (PrimFun f)   = pp f
+  pp (PrimQual q)  = pp q
+  pp (PrimTCon t)  = pp t
+  pp (PrimAlloc a) = pp a
+  pp (PrimExp e)   = parens (pp e)
+
+instance Pretty PrimaryUnit where pp = error "missing: PrimaryUnit" -- todo
+
+instance Pretty ProcedureCall where
+  pp (ProcedureCall n ap) = pp n <+> cond parens ap
+
+instance Pretty ProcedureCallStatement where
+  pp (ProcedureCallStatement l p) = condR colon l <+> pp p <+> semi
+
+instance Pretty ProcessDeclarativeItem where
+  pp (ProcDISubprogDecl s) = pp s
+  pp (ProcDISubprogBody b) = pp b
+  pp (ProcDIType t)        = pp t
+  pp (ProcDISubtype s)     = pp s
+  pp (ProcDIConstant c)    = pp c
+  pp (ProcDIVariable v)    = pp v
+  pp (ProcDIFile f)        = pp f
+  pp (ProcDIAlias a)       = pp a
+  pp (ProcDIAttrDecl a)    = pp a
+  pp (ProcDIAttrSpec a)    = pp a
+  pp (ProcDIUseClause u)   = pp u
+
+--instance Pretty ProcessDeclarativePart where pp = undefined
+
+instance Pretty ProcessStatement where
+  pp (ProcessStatement l p ss d s) =
+    condR colon l `hangs` vcat
+      [ post <+> cond parens ss <+> text "IS"
+        `hangs` pp d
+      , text "BEGIN"
+        `hangs` pp s
+      , text "END" <+> post <+> cond id l <+> semi
+      ]
+    where
+      post = when p (text "POSTPONED") <+> text "PROCESS"
+
+--instance Pretty ProcessStatementPart where pp = undefined
+
+instance Pretty QualifiedExpression where
+  pp (QualExp t e) = pp t <+> char '\'' <+> parens (pp e)
+  pp (QualAgg t a) = pp t <+> char '\'' <+> pp a
+
+instance Pretty Range where
+  pp (RAttr a)       = pp a
+  pp (RSimple l d u) = pp l <+> pp d <+> pp u
+
+instance Pretty RangeConstraint where
+  pp (RangeConstraint r) = text "RANGE" <+> pp r
+
+instance Pretty RecordTypeDefinition where
+  pp (RecordTypeDefinition es n) =
+    vcat [ text "RECORD"
+         , vcat $ map pp es
+         , text "END RECORD" <+> cond id n
+         ]
+
+instance Pretty Relation where
+  pp (Relation e (Nothing))     = pp e
+  pp (Relation e (Just (r, s))) = pp e <+> pp r <+> pp s
+
+instance Pretty RelationalOperator where
+  pp (Eq)  = equals
+  pp (Neq) = text "/="
+  pp (Lt)  = char '<'
+  pp (Lte) = text "<="
+  pp (Gt)  = char '>'
+  pp (Gte) = text ">="
+
+instance Pretty ReportStatement where
+  pp (ReportStatement l e s) =
+    condR colon l `hangs` (text "REPORT" <+> pp e `hangs` condL (text "SEVERITY") s)
+
+instance Pretty ReturnStatement where
+  pp (ReturnStatement l e) = condR colon l <+> text "RETURN" <+> condR semi e
+
+instance Pretty ScalarTypeDefinition where
+  pp (ScalarEnum e)  = pp e
+  pp (ScalarInt i)   = pp i
+  pp (ScalarFloat f) = pp f
+  pp (ScalarPhys p)  = pp p
+
+instance Pretty SecondaryUnit where pp = error "missing: SecondaryUnit" -- todo
+
+instance Pretty SecondaryUnitDeclaration where
+  pp (SecondaryUnitDeclaration i p) = pp i <+> equals <+> pp p
+
+instance Pretty SelectedName where
+  pp (SelectedName p s) = pp p <+> char '.' <+> pp s
+
+instance Pretty SelectedSignalAssignment where
+  pp (SelectedSignalAssignment e t o w) =
+    text "WITH" <+> pp e <+> text "SELECT"
+      `hangs`
+    pp t <+> text "<=" <+> pp o <+> pp w <+> semi
+
+instance Pretty SelectedWaveforms where
+  pp (SelectedWaveforms ws (w, c)) = vcat $ optional ++ [last]
+    where
+      optional = maybe [] (map f) ws
+      last     = pp w <+> text "WHEN" <+> pp c
+      f (w, c) = pp w <+> text "WHEN" <+> pp c <+> comma
+
+instance Pretty SensitivityClause where
+  pp (SensitivityClause ss) = text "ON" <+> pp ss
+
+instance Pretty SensitivityList where
+  pp (SensitivityList ns) = commaSep $ map pp ns
+
+--instance Pretty SequenceOfStatements where pp = undefined
+
+instance Pretty SequentialStatement where
+  pp (SWait w)      = pp w
+  pp (SAssert a)    = pp a
+  pp (SReport r)    = pp r
+  pp (SSignalAss s) = pp s
+  pp (SVarAss v)    = pp v
+  pp (SProc p)      = pp p
+  pp (SIf i)        = pp i
+  pp (SCase c)      = pp c
+  pp (SLoop l)      = pp l
+  pp (SNext n)      = pp n
+  pp (SExit e)      = pp e
+  pp (SReturn r)    = pp r
+  pp (SNull n)      = pp n
+
+instance Pretty ShiftExpression where
+  pp (ShiftExpression e (Nothing))     = pp e
+  pp (ShiftExpression e (Just (r, s))) = pp e <+> pp r <+> pp s
+
+instance Pretty ShiftOperator where
+  pp Sll = text "SLL"
+  pp Srl = text "SRL"
+  pp Sla = text "SLA"
+  pp Sra = text "SRA"
+  pp Rol = text "ROL"
+  pp Ror = text "ROR"
+
+instance Pretty Sign where
+  pp Identity = char '+'
+  pp Negation = char '-'
+
+instance Pretty SignalAssignmentStatement where
+  pp (SignalAssignmentStatement l t d w) =
+        condR colon l <+> pp t <+> text "<="
+    <+> cond  id    d <+> pp w <+> semi
+
+instance Pretty SignalDeclaration where
+  pp (SignalDeclaration is s k e) =
+        text "SIGNAL" <+> pp is <+> colon <+> pp s
+    <+> cond id k <+> condL (text ":=") e <+> semi
+
+instance Pretty SignalKind where
+  pp Register = text "REGISTER"
+  pp Bus      = text "BUS"
+
+instance Pretty SignalList where
+  pp (SLName ns) = commaSep $ map pp ns
+  pp (SLOthers)  = text "OTHERS"
+  pp (SLAll)     = text "ALL"
+
+instance Pretty Signature where
+  pp (Signature (Nothing))      = empty
+  pp (Signature (Just (ts, t))) = init <+> condL (text "RETURN") t
+    where
+      init = commaSep $ maybe [] (map pp) ts
+
+instance Pretty SimpleExpression where
+  pp (SimpleExpression s t as) = cond id s <+> pp t <+> adds
+    where
+      adds = hsep $ map (\(a, t) -> pp a <+> pp t) as
+
+--instance Pretty SimpleName where pp = undefined
+
+instance Pretty SliceName where
+  pp (SliceName p r) = pp p <+> parens (pp r)
+
+instance Pretty StringLiteral where
+  pp (SLit s) = text s
+
+instance Pretty SubprogramBody where
+  pp (SubprogramBody s d st k de) =
+    vcat [ pp s <+> text "IS"
+         , indent $ pp d
+         , text "BEGIN"
+         , indent $ pp st
+         , text "END" <+> pp' k <+> pp' de <+> semi
+         ]
+
+--instance Pretty SubprogramDeclaration where pp = undefined
+
+instance Pretty SubprogramDeclarativeItem where
+  pp (SDISubprogDecl d)  = pp d
+  pp (SDISubprogBody b)  = pp b
+  pp (SDITypeDecl t)     = pp t
+  pp (SDISubtypeDecl s)  = pp s
+  pp (SDIConstantDecl c) = pp c
+  pp (SDIVariableDecl v) = pp v
+  pp (SDIFileDecl f)     = pp f
+  pp (SDIAliasDecl a)    = pp a
+  pp (SDIAttrDecl a)     = pp a
+  pp (SDIAttrSepc a)     = pp a
+  pp (SDIUseClause u)    = pp u
+  pp (SDIGroupTemp g)    = pp g
+  pp (SDIGroupDecl g)    = pp g
+
+--instance Pretty SubprogramDeclarativePart where pp = undefined
+
+instance Pretty SubprogramKind where
+  pp Procedure = text "PROCEDURE"
+  pp Function  = text "FUNCTION"
+
+instance Pretty SubprogramSpecification where
+  pp (SubprogramProcedure d fs)    = text "PROCEDURE" <+> pp d <+> cond parens fs
+  pp (SubprogramFunction p d fs t) =
+      purity <+> vcat
+        [ text "FUNCTION" <+> pp d <+> cond parens fs
+        , text "RETURN"   <+> pp t
+        ]
+    where
+      purity = case p of
+        Nothing    -> empty
+        Just True  -> text "PURE"
+        Just False -> text "IMPURE"
+
+--instance Pretty SubprogramStatementPart where pp = undefined
+
+instance Pretty SubtypeDeclaration where
+  pp (SubtypeDeclaration i s) = text "SUBTYPE" <+> pp i <+> text "IS" <+> pp s <+> semi
+
+instance Pretty SubtypeIndication where
+  pp (SubtypeIndication n t c) = pp' n <+> pp t <+> pp' c
+
+instance Pretty Suffix where
+  pp (SSimple n) = pp n
+  pp (SChar c)   = pp c
+  pp (SOp o)     = pp o
+  pp (SAll)      = text "ALL"
+
+instance Pretty Target where
+  pp (TargetName n) = pp n
+  pp (TargetAgg a)  = pp a
+
+instance Pretty Term where
+  pp (Term f ms) = pp f <+> muls
+    where
+      muls = hsep $ map (\(m, t) -> pp m <+> pp t) ms
+
+instance Pretty TimeoutClause where
+  pp (TimeoutClause e) = text "FOR" <+> pp e
+
+instance Pretty TypeConversion where
+  pp (TypeConversion t e) = pp t <+> parens (pp e)
+
+instance Pretty TypeDeclaration where
+  pp (TDFull ft)    = pp ft
+  pp (TDPartial pt) = pp pt
+
+instance Pretty TypeDefinition where
+  pp (TDScalar s)    = pp s
+  pp (TDComposite c) = pp c
+  pp (TDAccess a)    = pp a
+  pp (TDFile f)      = pp f
+
+instance Pretty TypeMark where
+  pp (TMType n)    = pp n
+  pp (TMSubtype n) = pp n
+
+instance Pretty UnconstrainedArrayDefinition where
+  pp (UnconstrainedArrayDefinition is s) =
+    text "ARRAY" <+> parens (commaSep $ map pp is) <+> text "OF" <+> pp s
+
+instance Pretty UseClause where
+  pp (UseClause ns) = text "USE" <+> commaSep (map pp ns) <+> semi
+
+instance Pretty VariableAssignmentStatement where
+  pp (VariableAssignmentStatement l t e) = condR colon l <+> pp t <+> text ":=" <+> pp e <+> semi
+
+instance Pretty VariableDeclaration where
+  pp (VariableDeclaration s is sub e) =
+    when s (text "SHARED") <+> text "VARIABLE" <+> pp is <+> colon <+> pp sub <+> condL (text ":=") e <+> semi
+
+instance Pretty WaitStatement where
+  pp (WaitStatement l sc cc tc) =
+    condR colon l <+> text "WAIT" <+> pp' sc <+> pp' cc <+> pp' tc <+> semi
+
+instance Pretty Waveform where
+  pp (WaveElem es)    = commaSep $ map pp es
+  pp (WaveUnaffected) = text "UNAFFECTED"
+
+instance Pretty WaveformElement where
+  pp (WaveEExp e te) = pp e <+> condL (text "AFTER") te
+
+--------------------------------------------------------------------------------
+-- * Some helpers
+--------------------------------------------------------------------------------
+
+commaSep  :: [Doc] -> Doc
+commaSep  = hsep . punctuate comma
+
+semiSep   :: [Doc] -> Doc
+semiSep   = hsep . punctuate semi
+
+pipeSep   :: [Doc] -> Doc
+pipeSep   = hsep . punctuate (char '|')
+
+textSep   :: String -> [Doc] -> Doc
+textSep s = hsep . punctuate (space <> text s)
+
+--------------------------------------------------------------------------------
+
+when :: Bool -> Doc -> Doc
+when b a = if b then a else empty
+
+cond :: Pretty a => (Doc -> Doc) -> Maybe a -> Doc
+cond f = maybe empty (f . pp)
+
+condR :: Pretty a => Doc -> Maybe a -> Doc
+condR s m = cond (flip (<+>) s) m
+
+condL :: Pretty a => Doc -> Maybe a -> Doc
+condL s m = cond ((<+>) s) m
+
+label :: Pretty a => Maybe a -> Doc
+label = cond (flip (<+>) colon)
+
+indent :: Doc -> Doc
+indent = nest 4
+
+hangs  :: Doc -> Doc -> Doc
+hangs  = flip hang 4
+
+--------------------------------------------------------------------------------
+
+pp' :: Pretty a => Maybe a -> Doc
+pp' = cond id
+
+parens' :: Pretty a => Maybe a -> Doc
+parens' = cond parens
+
+--------------------------------------------------------------------------------
+
+postponed :: Pretty a =>  Maybe Label -> Bool -> a -> Doc
+postponed l b a = condR colon l <+> when b (text "POSTPONED") <+> pp a
+
+--------------------------------------------------------------------------------
diff --git a/src/Language/VHDL/Syntax.hs b/src/Language/VHDL/Syntax.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/VHDL/Syntax.hs
@@ -0,0 +1,2488 @@
+module Language.VHDL.Syntax where
+
+--------------------------------------------------------------------------------
+--
+--                                   -- 1 --
+--
+--                      Design entities and configurations
+--
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+-- * 1.1 Entiity Declarations
+--------------------------------------------------------------------------------
+{-
+    entity_declaration ::=
+      ENTITY identifier IS
+        entity_header
+        entity_declarative_part
+      [ BEGIN
+        entity_statement_part ]
+      END [ ENTITY ] [ entity_simple_name ] ;
+-}
+
+data EntityDeclaration = EntityDeclaration {
+    entity_identifier         :: Identifier
+  , entity_header             :: EntityHeader
+  , entity_declarative_part   :: EntityDeclarativePart
+  , entity_statement_part     :: Maybe EntityStatementPart
+  }
+
+--------------------------------------------------------------------------------
+-- ** 1.1.1 Entity haeder
+{-
+    entity_header ::=
+      [ formal_generic_clause ]
+      [ formal_port_clause ]
+
+    generic_clause ::= GENERIC ( generic_list ) ;
+    port_clause    ::= PORT ( port_list ) ;
+-}
+
+data EntityHeader = EntityHeader {
+    formal_generic_clause     :: Maybe GenericClause
+  , formal_port_clause        :: Maybe PortClause
+  }
+
+data GenericClause = GenericClause GenericList
+data PortClause    = PortClause    PortList
+
+--------------------------------------------------------------------------------
+-- *** 1.1.1.1 Generics
+{-
+    generic_list ::= generic_interface_list
+-}
+
+type GenericList = InterfaceList
+
+--------------------------------------------------------------------------------
+-- *** 1.1.1.2 Ports
+{-
+    port_list ::= port_interface_list
+-}
+
+type PortList = InterfaceList
+
+--------------------------------------------------------------------------------
+-- ** 1.1.2 Entity declarative part
+{-
+    entity_declarative_part ::=
+      { entity_declarative_item }
+
+    entity_declarative_item ::=
+        subprogram_declaration
+      | subprogram_body
+      | type_declaration
+      | subtype_declaration
+      | constant_declaration
+      | signal_declaration
+      | shared_variable_declaration
+      | file_declaration
+      | alias_declaration
+      | attribute_declaration
+      | attribute_specification
+      | disconnection_specification
+      | use_clause
+      | group_template_declaration
+      | group_declaration
+-}
+
+type EntityDeclarativePart = [EntityDeclarativeItem]
+
+data EntityDeclarativeItem =
+    EDISubprogDecl  SubprogramDeclaration
+  | EDISubprogBody  SubprogramBody
+  | EDITypeDecl     TypeDeclaration
+  | EDISubtypeDecl  SubtypeDeclaration
+  | EDIConstantDecl ConstantDeclaration
+  | EDISignalDecl   SignalDeclaration
+  | EDISharedDecl   VariableDeclaration
+  | EDIFileDecl     FileDeclaration
+  | EDIAliasDecl    AliasDeclaration
+  | EDIAttrDecl     AttributeDeclaration
+  | EDIAttrSpec     AttributeSpecification
+  | EDIDiscSpec     DisconnectionSpecification
+  | EDIUseClause    UseClause
+  | EDIGroupTemp    GroupTemplateDeclaration
+  | EDIGroupDecl    GroupDeclaration
+
+--------------------------------------------------------------------------------
+-- ** 1.1.3 Entity statement part
+{-
+    entity_statement_part ::=
+      { entity_statement }
+
+    entity_statement ::=
+        concurrent_assertion_statement
+      | passive_concurrent_procedure_call_statement
+      | passive_process_statement
+-}
+
+type EntityStatementPart = [EntityStatement]
+
+data EntityStatement =
+    ESConcAssert   ConcurrentAssertionStatement
+  | ESPassiveConc  ConcurrentProcedureCallStatement
+  | ESPassiveProc  ProcessStatement
+
+--------------------------------------------------------------------------------
+-- * 1.2 Arcitecture bodies
+--------------------------------------------------------------------------------
+{-
+    architecture_body ::=
+      ARCHITECTURE identifier OF entity_name IS
+        architecture_declarative_part
+      BEGIN
+	architecture_statement_part
+      END [ ARCHITECTURE ] [ architecture_simple_name ] ;
+-}
+
+data ArchitectureBody = ArchitectureBody {
+    archi_identifier       :: Identifier
+  , archi_entity_name      :: Name
+  , archi_declarative_part :: ArchitectureDeclarativePart
+  , archi_statement_part   :: ArchitectureStatementPart
+  }
+
+--------------------------------------------------------------------------------
+-- ** 1.2.1 Architecture declarative part
+{-
+    architecture_declarative_part ::=
+      { block_declarative_item }
+
+    block_declarative_item ::=
+        subprogram_declaration
+      | subprogram_body
+      | type_declaration
+      | subtype_declaration
+      | constant_declaration
+      | signal_declaration
+      | shared_variable_declaration
+      | file_declaration
+      | alias_declaration
+      | component_declaration
+      | attribute_declaration
+      | attribute_specification
+      | configuration_specification
+      | disconnection_specification
+      | use_clause
+      | group_template_declaration
+      | group_declaration
+-}
+
+type ArchitectureDeclarativePart = [BlockDeclarativeItem]
+
+data BlockDeclarativeItem =
+    BDISubprogDecl  SubprogramDeclaration
+  | BDISubprogBody  SubprogramBody
+  | BDITypeDecl     TypeDeclaration
+  | BDISubtypeDecl  SubtypeDeclaration
+  | BDIConstantDecl ConstantDeclaration
+  | BDISignalDecl   SignalDeclaration
+  | BDISharedDecl   VariableDeclaration
+  | BDIFileDecl     FileDeclaration
+  | BDIAliasDecl    AliasDeclaration
+  | BDICompDecl     ComponentDeclaration
+  | BDIAttrDecl     AttributeDeclaration
+  | BDIAttrSepc     AttributeSpecification
+  | BDIConfigSepc   ConfigurationSpecification
+  | BDIDisconSpec   DisconnectionSpecification
+  | BDIUseClause    UseClause
+  | BDIGroupTemp    GroupTemplateDeclaration
+  | BDIGroupDecl    GroupDeclaration
+
+--------------------------------------------------------------------------------
+-- ** 1.2.2 Architecture statement part
+{-
+    architecture_statement_part ::=
+      { concurrent_statement }
+-}
+
+type ArchitectureStatementPart = [ConcurrentStatement]
+
+--------------------------------------------------------------------------------
+-- * 1.3 Configuration declarations
+--------------------------------------------------------------------------------
+{-
+    configuration_declaration ::=
+      CONFIGURATION identifier OF entity_name IS
+        configuration_declarative_part
+	block_configuration
+      END [ CONFIGURATION ] [ configuration_simple_name ] ;
+
+    configuration_declarative_part ::=
+      { configuration_declarative_item }
+
+    configuration_declarative_item ::=
+	use_clause
+      | attribute_specification
+      | group_declaration
+-}
+
+data ConfigurationDeclaration = ConfigurationDeclaration {
+    config_identifier          :: Identifier
+  , config_entity_name         :: Name
+  , config_declarative_part    :: ConfigurationDeclarativePart
+  , config_block_configuration :: BlockConfiguration
+  }
+
+type ConfigurationDeclarativePart = [ConfigurationDeclarativeItem]
+
+data ConfigurationDeclarativeItem =
+    CDIUse   UseClause
+  | CDIAttr  AttributeSpecification
+  | CDIGroup GroupDeclaration
+
+--------------------------------------------------------------------------------
+-- ** 1.3.1 Block configuration
+{-
+    block_configuration ::=
+      FOR block_specification
+        { use_clause }
+	{ configuration_item }
+      END FOR ;
+
+    block_specification ::=
+        architecture_name
+      | block_statement_label
+      | generate_statement_label [ ( index_specification ) ]
+
+    index_specification ::=
+        discrete_range
+      | static_expression
+
+    configuration_item ::=
+        block_configuration
+      | component_configuration
+-}
+
+data BlockConfiguration = BlockConfiguration {
+    block_specification      :: BlockSpecification
+  , block_use_clause         :: [UseClause]
+  , block_configuration_item :: [ConfigurationItem]
+  }
+
+data BlockSpecification =
+    BSArch  Name
+  | BSBlock Label
+  | BSGen   Label
+
+data IndexSpecification =
+    ISRange DiscreteRange
+  | ISExp   Expression
+
+data ConfigurationItem  =
+    CIBlock BlockConfiguration
+  | CIComp  ComponentConfiguration
+
+--------------------------------------------------------------------------------
+-- ** 1.3.2 Component configuration
+
+{-
+    component_configuration ::=
+      FOR component_specification
+        [ binding_indication ; ]
+	[ block_configuration ]
+      END FOR ;
+-}
+
+data ComponentConfiguration = ComponentConfiguration {
+    comp_specification       :: ComponentSpecification
+  , comp_binding_indication  :: Maybe BindingIndication
+  , comp_block_configuration :: Maybe BlockConfiguration
+  }
+
+--------------------------------------------------------------------------------
+--
+--                                   -- 2 --
+--
+--                           Subprograms and packages
+-- 
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+-- * 2.1 Subprogram declarations
+--------------------------------------------------------------------------------
+{-
+    subprogram_declaration ::=
+      subprogram_specification ;
+
+    subprogram_specification ::=
+      PROCEDURE designator [ ( formal_parameter_list ) ]
+      | [ PURE | IMPURE ] FUNCTION designator [ ( formal_parameter_list ) ]
+        RETURN type_mark
+
+    designator ::= identifier | operator_symbol
+
+    operator_symbol ::= string_literal
+-}
+
+type SubprogramDeclaration   = SubprogramSpecification
+
+data SubprogramSpecification =
+    SubprogramProcedure {
+      subproc_designator            :: Designator
+    , subproc_formal_parameter_list :: Maybe FormalParameterList
+    }
+  | SubprogramFunction {
+      subfun_purity                 :: Maybe Bool
+    , subfun_designator             :: Designator
+    , subfun_formal_parameter_list  :: Maybe FormalParameterList
+    , subfun_type_mark              :: TypeMark
+    }
+
+data Designator =
+    DId Identifier
+  | DOp OperatorSymbol
+
+type OperatorSymbol = StringLiteral
+
+--------------------------------------------------------------------------------
+-- ** 2.1.1 Formal parameters
+{-
+    formal_parameter_list ::= parameter_interface_list
+-}
+
+type FormalParameterList = InterfaceList
+
+--------------------------------------------------------------------------------
+-- *** 2.1.1.1 Constant and variable parameters
+
+-- properties ... todo
+
+--------------------------------------------------------------------------------
+-- *** 2.1.1.2 Signal parameter
+
+-- properties ... todo
+
+--------------------------------------------------------------------------------
+-- *** 2.1.1.3 File parameter
+
+-- properties ... todo
+
+--------------------------------------------------------------------------------
+-- * 2.2 Subprogram bodies
+--------------------------------------------------------------------------------
+{-
+    subprogram_body ::=
+      subprogram_specification IS
+        subprogram_declarative_part
+      BEGIN
+	subprogram_statement_part
+      END [ subprogram_kind ] [ designator ] ;
+
+    subprogram_declarative_part ::=
+      { subprogram_declarative_item }
+
+    subprogram_declarative_item ::=
+        subprogram_declaration
+      | subprogram_body
+      | type_declaration
+      | subtype_declaration
+      | constant_declaration
+      | variable_declaration
+      | file_declaration
+      | alias_declaration
+      | attribute_declaration
+      | attribute_specification
+      | use_clause
+      | group_template_declaration
+      | group_declaration
+
+
+    subprogram_statement_part ::=
+      { sequential_statement }
+
+    subprogram_kind ::= PROCEDURE | FUNCTION
+-}
+
+data SubprogramBody = SubprogramBody {
+    subprog_specification    :: SubprogramSpecification
+  , subprog_declarative_part :: SubprogramDeclarativePart
+  , subprog_statement_part   :: SubprogramStatementPart
+  , subprog_kind             :: Maybe SubprogramKind
+  , subprog_designator       :: Maybe Designator
+  }
+
+type SubprogramDeclarativePart = [SubprogramDeclarativeItem]
+
+data SubprogramDeclarativeItem =
+    SDISubprogDecl  SubprogramDeclaration
+  | SDISubprogBody  SubprogramBody
+  | SDITypeDecl     TypeDeclaration
+  | SDISubtypeDecl  SubtypeDeclaration
+  | SDIConstantDecl ConstantDeclaration
+  | SDIVariableDecl VariableDeclaration
+  | SDIFileDecl     FileDeclaration
+  | SDIAliasDecl    AliasDeclaration
+  | SDIAttrDecl     AttributeDeclaration
+  | SDIAttrSepc     AttributeSpecification
+  | SDIUseClause    UseClause
+  | SDIGroupTemp    GroupTemplateDeclaration
+  | SDIGroupDecl    GroupDeclaration
+    
+type SubprogramStatementPart   = [SequentialStatement]
+
+data SubprogramKind            = Procedure | Function
+
+--------------------------------------------------------------------------------
+-- * 2.3 Subprogram overloading
+
+-- properties ... todo
+
+--------------------------------------------------------------------------------
+-- ** 2.3.1 Operator overloading
+
+-- properties ... todo
+
+--------------------------------------------------------------------------------
+-- ** 2.3.2 Signatures
+{-
+    signature ::= [ [ type_mark { , type_mark } ] [ RETURN type_mark ] ]
+-}
+
+data Signature = Signature (Maybe (Maybe [TypeMark], Maybe TypeMark))
+
+--------------------------------------------------------------------------------
+-- * 2.4 Resolution functions
+
+-- properties ... todo
+
+--------------------------------------------------------------------------------
+-- * 2.5 Package declarations
+{- 
+    package_declaration ::=
+      PACKAGE identifier IS
+        package_declarative_part
+      END [ PACKAGE ] [ package_simple_name ] ;
+
+    package_declarative_part ::=
+      { package_declarative_item }
+
+    package_declarative_item ::=
+        subprogram_declaration
+      | type_declaration
+      | subtype_declaration
+      | constant_declaration
+      | signal_declaration
+      | shared_variable_declaration
+      | file_declaration
+      | alias_declaration
+      | component_declaration
+      | attribute_declaration
+      | attribute_specification
+      | disconnection_specification
+      | use_clause
+      | group_template_declaration
+      | group_declaration
+-}
+
+data PackageDeclaration = PackageDeclaration {
+    packd_identifier       :: Identifier
+  , packd_declarative_part :: PackageDeclarativePart
+  }
+
+type PackageDeclarativePart = [PackageDeclarativeItem]
+
+data PackageDeclarativeItem =
+    PDISubprogDecl  SubprogramDeclaration
+  | PDISubprogBody  SubprogramBody
+  | PDITypeDecl     TypeDeclaration
+  | PDISubtypeDecl  SubtypeDeclaration
+  | PDIConstantDecl ConstantDeclaration
+  | PDISignalDecl   SignalDeclaration
+  | PDISharedDecl   VariableDeclaration
+  | PDIFileDecl     FileDeclaration
+  | PDIAliasDecl    AliasDeclaration
+  | PDICompDecl     ComponentDeclaration
+  | PDIAttrDecl     AttributeDeclaration
+  | PDIAttrSpec     AttributeSpecification
+  | PDIDiscSpec     DisconnectionSpecification
+  | PDIUseClause    UseClause
+  | PDIGroupTemp    GroupTemplateDeclaration
+  | PDIGroupDecl    GroupDeclaration
+
+--------------------------------------------------------------------------------
+-- * 2.6 Package bodies
+{-
+    package_body ::=
+      PACKAGE  package_simple_name IS
+        package_body_declarative_part
+      END [ PACKAGE BODY ] [ package_simple_name ] ;
+
+    package_body_declarative_part ::=
+      { package_body_declarative_item }
+
+    package_body_declarative_item ::=
+        subprogram_declaration
+      | subprogram_body
+      | type_declaration
+      | subtype_declaration
+      | constant_declaration
+      | shared_variable_declaration
+      | file_declaration
+      | alias_declaration
+      | use_clause
+      | group_template_declaration
+      | group_declaration
+-}
+
+data PackageBody = PackageBody {
+    packb_simple_name           :: SimpleName
+  , packb_body_declarative_part :: PackageBodyDeclarativePart
+  }
+
+type PackageBodyDeclarativePart = [PackageBodyDeclarativeItem]
+
+data PackageBodyDeclarativeItem = 
+    PBDISubprogDecl  SubprogramDeclaration
+  | PBDISubprogBody  SubprogramBody
+  | PBDITypeDecl     TypeDeclaration
+  | PBDISubtypeDecl  SubtypeDeclaration
+  | PBDIConstantDecl ConstantDeclaration
+  | PBDISharedDecl   VariableDeclaration
+  | PBDIFileDecl     FileDeclaration
+  | PBDIAliasDecl    AliasDeclaration
+  | PBDIUseClause    UseClause
+  | PBDIGroupTemp    GroupTemplateDeclaration
+  | PBDIGroupDecl    GroupDeclaration
+
+--------------------------------------------------------------------------------
+-- * 2.7 Conformance rules
+
+-- properties ... todo
+
+
+--------------------------------------------------------------------------------
+--
+--                                   -- 3 --
+--
+--                                    Types
+-- 
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+-- * 3.1 Scalar types
+{-
+    scalar_type_definition ::=
+	enumeration_type_definition
+      | integer_type_definition
+      | floating_type_definition
+      | physical_type_definition
+
+    range_constraint ::= RANGE range
+
+    range ::=
+        range_attribute_name
+      | simple_expression direction simple_expression
+
+    direction ::= TO | DOWNTO
+-}
+
+data ScalarTypeDefinition =
+    ScalarEnum  EnumerationTypeDefinition
+  | ScalarInt   IntegerTypeDefinition
+  | ScalarFloat FloatingTypeDefinition
+  | ScalarPhys  PhysicalTypeDefinition
+
+data RangeConstraint = RangeConstraint Range
+
+data Range =
+    RAttr   AttributeName
+  | RSimple {
+      range_lower :: SimpleExpression
+    , range_dir   :: Direction
+    , range_upper :: SimpleExpression
+    }
+
+data Direction = To | DownTo
+
+--------------------------------------------------------------------------------
+-- ** 3.1.1 Enumeration types
+{-
+    enumeration_type_definition ::=
+      ( enumeration_literal { , enumeration_literal } )
+
+    enumeration_literal ::= identifier | character_literal
+-}
+
+data EnumerationTypeDefinition = EnumerationTypeDefinition [EnumerationLiteral]
+
+data EnumerationLiteral =
+    EId   Identifier
+  | EChar CharacterLiteral
+
+--------------------------------------------------------------------------------
+-- *** 3.1.1.1 Predefined enumeration types
+
+-- predefined ... todo
+
+--------------------------------------------------------------------------------
+-- ** 3.1.2 Integer types
+{-
+    integer_type_definition ::= range_constraint
+-}
+
+type IntegerTypeDefinition = RangeConstraint
+
+--------------------------------------------------------------------------------
+-- *** 3.1.2.1 Predefined integer types
+
+-- predefined ... todo
+
+--------------------------------------------------------------------------------
+-- ** 3.1.3 Physical types
+{-
+    physical_type_definition ::=
+      range_constraint
+        UNITS
+	  primary_unit_declaration
+	  { secondary_unit_declaration }
+	END UNITS [ physical_type_simple_name ]
+
+    primary_unit_declaration ::= identifier ;
+
+    secondary_unit_declaration ::= identifier = physical_literal ;
+
+    physical_literal ::= [ abstract_literal ] unit_name
+-}
+
+data PhysicalTypeDefinition = PhysicalTypeDefinition {
+    physd_range_constraint           :: RangeConstraint
+  , physd_primary_unit_declaration   :: PrimaryUnitDeclaration
+  , physd_secondary_unit_declaration :: [SecondaryUnitDeclaration]
+  , physd_simple_name                :: Maybe SimpleName
+  }
+
+type PrimaryUnitDeclaration   = Identifier
+
+data SecondaryUnitDeclaration = SecondaryUnitDeclaration Identifier PhysicalLiteral
+
+data PhysicalLiteral = PhysicalLiteral {
+    physl_abstract_literal :: Maybe Literal
+  , physl_unit_name        :: Name
+  }
+
+--------------------------------------------------------------------------------
+-- *** 3.1.3.1 Predefined physical types
+
+-- predefined ... todo
+
+--------------------------------------------------------------------------------
+-- ** 3.1.4 Floating point types
+{-
+    floating_type_definition ::= range_constraint
+-}
+
+type FloatingTypeDefinition = RangeConstraint
+
+--------------------------------------------------------------------------------
+-- *** 3.1.4.1 Predefined floating point types
+
+-- predefined ... todo
+
+--------------------------------------------------------------------------------
+-- * 3.2 Composite types
+{-
+    composite_type_definition ::=
+        array_type_definition
+      | record_type_definition
+-}
+
+data CompositeTypeDefinition =
+    CTDArray  ArrayTypeDefinition
+  | CTDRecord RecordTypeDefinition
+
+--------------------------------------------------------------------------------
+-- ** 3.2.1 Array types
+{-
+    array_type_definition ::=
+	unconstrained_array_definition
+      | constrained_array_definition
+
+    unconstrained_array_definition ::=
+      ARRAY ( index_subtype_definition { , index_subtype_definition } )
+        OF element_subtype_indication
+
+    constrained_array_definition ::=
+      ARRAY index_constraint OF element_subtype_indication
+
+    index_subtype_definition ::= type_mark RANGE <>
+
+    index_constraint ::= ( discrete_range { , discrete_range } )
+
+    discrete_range ::= discrete_subtype_indication | range
+-}
+
+data ArrayTypeDefinition =
+    ArrU UnconstrainedArrayDefinition
+  | ArrC ConstrainedArrayDefinition
+
+data UnconstrainedArrayDefinition = UnconstrainedArrayDefinition {
+    arru_index_subtype_definition   :: [IndexSubtypeDefinition]
+  , arru_element_subtype_indication :: (SubtypeIndication)
+  }
+
+data ConstrainedArrayDefinition = ConstrainedArrayDefinition {
+    arrc_index_constraint   :: IndexConstraint
+  , arrc_subtype_indication :: SubtypeIndication
+  }
+
+data IndexSubtypeDefinition = IndexSubtypeDefinition TypeMark
+
+data IndexConstraint = IndexConstraint [DiscreteRange]
+
+data DiscreteRange =
+    DRSub   SubtypeIndication
+  | DRRange Range
+
+--------------------------------------------------------------------------------
+-- *** 3.2.1.1 Index constraints and discrete ranges
+
+-- constraints ... todo
+
+--------------------------------------------------------------------------------
+-- *** 3.2.1.2 Predefined array types
+
+-- predefined ... todo
+
+--------------------------------------------------------------------------------
+-- ** 3.2.2 Record types
+{-
+    record_type_definition ::=
+      RECORD
+        element_declaration
+	{ element_declaration }
+      END RECORD [ record_type_simple_name ]
+
+    element_declaration ::=
+      identifier_list : element_subtype_definition ;
+
+    identifier_list ::= identifier { , identifier }
+
+    element_subtype_definition ::= subtype_indication
+-}
+
+data RecordTypeDefinition = RecordTypeDefinition {
+    rectd_element_declaration :: [ElementDeclaration]
+  , rectd_type_simple_name    :: Maybe SimpleName
+  }
+
+data ElementDeclaration = ElementDeclaration {
+    elemd_identifier_list    :: IdentifierList
+  , elemd_subtype_definition :: ElementSubtypeDefinition
+  }
+
+type IdentifierList           = [Identifier]
+
+type ElementSubtypeDefinition = SubtypeIndication
+
+--------------------------------------------------------------------------------
+-- * 3.3 Access types
+{-
+    access_type_definition ::= ACCESS subtype_indication
+-}
+
+data AccessTypeDefinition = AccessTypeDefinition SubtypeIndication
+
+--------------------------------------------------------------------------------
+-- ** 3.3.1 Incomplete type declarations
+{-
+    incomplete_type_declaration ::= TYPE identifier ;
+-}
+
+data IncompleteTypeDeclaration = IncompleteTypeDeclaration Identifier
+
+--------------------------------------------------------------------------------
+-- *** 3.3.2 Allocation and deallocation of objects
+
+-- ?
+
+--------------------------------------------------------------------------------
+-- * 3.4 File types
+{-
+    file_type_definition ::= FILE OF type_mark
+-}
+
+data FileTypeDefinition = FileTypeDefinition TypeMark
+
+--------------------------------------------------------------------------------
+-- ** 3.4.1 File operations
+
+-- ?
+
+--------------------------------------------------------------------------------
+-- * 3.5 Protected types
+
+-- I'll skip these for now..
+
+--------------------------------------------------------------------------------
+--
+--                                   -- 4 --
+--
+--                                Declarations
+--
+--------------------------------------------------------------------------------
+{-
+    declaration ::=
+        type_declaration
+      | subtype_declaration
+      | object_declaration
+      | interface_declaration
+      | alias_declaration
+      | attribute_declaration
+      | component_declaration
+      | group_template_declaration
+      | group_declaration
+      | entity_declaration
+      | configuration_declaration
+      | subprogram_declaration
+      | package_declaration
+-}
+
+data Declaration = 
+    DType          TypeDeclaration
+  | DSubtype       SubtypeDeclaration
+  | DObject        ObjectDeclaration
+  | DAlias         AliasDeclaration
+  | DComponent     ComponentDeclaration
+  | DAttribute     AttributeDeclaration
+  | DGroupTemplate GroupTemplateDeclaration
+  | DGroup         GroupDeclaration
+  | DEntity        EntityDeclaration
+  | DConfiguration ConfigurationDeclaration
+  | DSubprogram    SubprogramDeclaration
+  | DPackage       PackageDeclaration
+
+--------------------------------------------------------------------------------
+-- * 4.1 Type declarations
+{-
+    type_declaration ::=
+        full_type_declaration
+      | incomplete_type_declaration
+
+    full_type_declaration ::=
+      TYPE identifier IS type_definition ;
+
+    type_definition ::=
+        scalar_type_definition
+      | composite_type_definition
+      | access_type_definition
+      | file_type_definition
+      | protected_type_definition  -- missing from ref. manual
+-}
+
+data TypeDeclaration = TDFull FullTypeDeclaration | TDPartial IncompleteTypeDeclaration
+
+data FullTypeDeclaration = FullTypeDeclaration {
+    ftd_identifier      :: Identifier
+  , ftd_type_definition :: TypeDefinition
+  }
+
+data TypeDefinition =
+    TDScalar       ScalarTypeDefinition
+  | TDComposite CompositeTypeDefinition
+  | TDAccess       AccessTypeDefinition
+  | TDFile           FileTypeDefinition
+--  | TDProt      ProtectedTypeDefinition
+
+--------------------------------------------------------------------------------
+-- * 4.2 Subtype declarations
+{-
+    subtype_declaration ::=
+      SUBTYPE identifier IS subtype_indication ;
+
+    subtype_indication ::=
+      [ resolution_function_name ] type_mark [ constraint ]
+
+    type_mark ::=
+        type_name
+      | subtype_name
+
+    constraint ::=
+        range_constraint
+      | index_constraint
+-}
+
+data SubtypeDeclaration = SubtypeDeclaration {
+    sd_identifier               :: Identifier
+  , sd_indication               :: SubtypeIndication
+  }
+
+data SubtypeIndication = SubtypeIndication {
+    si_resolution_function_name :: Maybe Name
+  , si_type_mark                :: TypeMark
+  , si_constraint               :: Maybe Constraint
+  }
+
+data TypeMark   = TMType Name | TMSubtype Name
+
+data Constraint = CRange RangeConstraint | CIndex IndexConstraint
+
+--------------------------------------------------------------------------------
+-- * 4.3 Objects
+
+--------------------------------------------------------------------------------
+-- ** 4.3.1 Object declarations
+{-
+    object_declaration ::=
+        constant_declaration
+      | signal_declaration
+      | variable_declaration
+      | file_declaration
+-}
+
+data ObjectDeclaration =
+    ObjConst ConstantDeclaration
+  | ObjSig     SignalDeclaration
+  | ObjVar   VariableDeclaration
+  | ObjFile      FileDeclaration
+
+--------------------------------------------------------------------------------
+-- *** 4.3.1.1 Constant declarations
+{-
+    constant_declaration ::=
+      CONSTANT identifier_list : subtype_indication [ := expression ] ;
+-}
+
+data ConstantDeclaration = ConstantDeclaration {
+    const_identifier_list    :: IdentifierList
+  , const_subtype_indication :: SubtypeIndication
+  , const_expression         :: Maybe Expression
+  }
+
+--------------------------------------------------------------------------------
+-- *** 4.3.1.2 Signal declarations
+{-
+    signal_declaration ::=
+      SIGNAL identifier_list : subtype_indication [ signal_kind ] [ := expression ] ;
+
+    signal_kind ::= REGISTER | BUS
+-}
+
+data SignalDeclaration = SignalDeclaration {
+    signal_identifier_list    :: IdentifierList
+  , signal_subtype_indication :: SubtypeIndication
+  , signal_kind               :: Maybe SignalKind
+  , signal_expression         :: Maybe Expression
+  }
+
+data SignalKind = Register | Bus
+
+--------------------------------------------------------------------------------
+-- *** 4.3.1.3 Variable declarations
+{-
+    variable_declaration ::=
+      [ SHARED ] VARIABLE identifier_list : subtype_indication [ := expression ] ;
+-}
+
+data VariableDeclaration = VariableDeclaration {
+    var_shared             :: Bool
+  , var_identifier_list    :: IdentifierList
+  , var_subtype_indication :: SubtypeIndication
+  , var_expression         :: Maybe Expression
+  }
+
+--------------------------------------------------------------------------------
+-- *** 4.3.1.4 File declarations
+{-
+    file_declaration ::=
+      FILE identifier_list : subtype_indication [ file_open_information ] ;
+
+    file_open_information ::=
+      [ OPEN file_open_kind_expression ] IS file_logical_name
+
+    file_logical_name ::= string_expression
+-}
+
+data FileDeclaration = FileDeclaration {
+    fd_identifier_list      :: IdentifierList
+  , fd_subtype_indication   :: SubtypeIndication
+  , fd_open_information     :: Maybe FileOpenInformation
+  }
+
+data FileOpenInformation = FileOpenInformation {
+    foi_open_kind_expression :: Maybe Expression
+  , foi_logical_name         :: FileLogicalName
+  }
+
+type FileLogicalName = Expression
+
+--------------------------------------------------------------------------------
+-- ** 4.3.2 Interface declarations
+{-
+    interface_declaration ::=
+        interface_constant_declaration
+      | interface_signal_declaration
+      | interface_variable_declaration
+      | interface_file_declaration
+
+    interface_constant_declaration ::=
+      [ CONSTANT ] identifier_list : [ IN ] subtype_indication [ := static_expression ]
+
+    interface_signal_declaration ::=
+      [ SIGNAL ] identifier_list : [ mode ] subtype_indication [ BUS ] [ := static_expression ]
+
+    interface_variable_declaration ::=
+      [ VARIABLE ] identifier_list : [ mode ] subtype_indication [ := static_expression ]
+
+    interface_file_declaration ::=
+	FILE identifier_list : subtype_indication
+
+    mode ::= IN | OUT | INOUT | BUFFER | LINKAGE
+-}
+
+data InterfaceDeclaration
+  = InterfaceConstantDeclaration {
+        idecl_identifier_list     :: IdentifierList
+      , iconst_subtype_indication :: SubtypeIndication
+      , iconst_static_expression  :: Maybe Expression
+    }
+  | InterfaceSignalDeclaration {
+        idecl_identifier_list     :: IdentifierList
+      , isig_mode                 :: Maybe Mode
+      , isig_subtype_indication   :: SubtypeIndication
+      , isig_bus                  :: Bool
+      , isig_static_expression    :: Maybe Expression
+    }
+  | InterfaceVariableDeclaration {
+        idecl_identifier_list     :: IdentifierList
+      , ivar_mode                 :: Maybe Mode
+      , ivar_subtype_indication   :: SubtypeIndication
+      , ivar_static_expression    :: Maybe Expression
+    }
+  | InterfaceFileDeclaration {
+        idecl_identifier_list     :: IdentifierList
+      , ifile_subtype_indication  :: SubtypeIndication
+    }
+
+data Mode = In | Out | InOut | Buffer | Linkage
+
+--------------------------------------------------------------------------------
+-- *** 4.3.2.1 Interface lists
+{-
+    interface_list ::= interface_element { ; interface_element }
+
+    interface_element ::= interface_declaration
+-}
+
+data InterfaceList    = InterfaceList [InterfaceElement]
+
+type InterfaceElement = InterfaceDeclaration
+
+--------------------------------------------------------------------------------
+-- *** 4.3.2.2 Association lists
+{-
+    association_element ::=
+      [ formal_part => ] actual_part
+
+    association_list ::=
+      association_element { , association_element }
+
+    formal_designator ::=
+        generic_name
+      | port_name
+      | parameter_name
+
+    formal_part ::=
+        formal_designator
+      | function_name ( formal_designator )
+      | type_mark ( formal_designator )
+
+    actual_designator ::=
+	expression
+      | signal_name
+      | variable_name
+      | file_name
+      | OPEN
+
+    actual_part ::=
+        actual_designator
+      | function_name ( actual_designator )
+      | type_mark ( actual_designator )
+-}
+
+data AssociationElement = AssociationElement {
+    assoc_formal_part :: Maybe FormalPart
+  , assoc_actual_part :: ActualPart
+  }
+
+data AssociationList = AssociationList [AssociationElement]
+
+data FormalDesignator =
+    FDGeneric   Name
+  | FDPort      Name
+  | FDParameter Name
+
+data FormalPart =
+    FPDesignator          FormalDesignator
+  | FPFunction   Name     FormalDesignator
+  | FPType       TypeMark FormalDesignator
+
+data ActualDesignator =
+    ADExpression  Expression
+  | ADSignal      Name
+  | ADVariable    Name
+  | ADFile        Name
+  | ADOpen
+
+data ActualPart =
+    APDesignator          ActualDesignator
+  | APFunction   Name     ActualDesignator
+  | APType       TypeMark ActualDesignator
+
+--------------------------------------------------------------------------------
+-- ** 4.3.3 Alias declarations
+{-
+    alias_declaration ::=
+      ALIAS alias_designator [ : subtype_indication ] IS name [ signature ] ;
+
+    alias_designator ::= identifier | character_literal | operator_symbol
+-}
+
+data AliasDeclaration = AliasDeclaration {
+    alias_designator         :: AliasDesignator
+  , alias_subtype_indication :: Maybe SubtypeIndication
+  , alias_name               :: Name
+  , alias_signature          :: Maybe Signature
+  }
+
+data AliasDesignator =
+    ADIdentifier Identifier
+  | ADCharacter  CharacterLiteral
+  | ADOperator   OperatorSymbol
+
+--------------------------------------------------------------------------------
+-- *** 4.3.3.1 Object aliases
+
+--------------------------------------------------------------------------------
+-- *** 4.3.3.2 Nonobject aliases
+
+--------------------------------------------------------------------------------
+-- * 4.4 Attribute declarations
+{-
+    attribute_declaration ::=
+      ATTRIBUTE identifier : type_mark ;
+-}
+
+data AttributeDeclaration = AttributeDeclaration {
+    attr_identifier :: Identifier
+  , attr_type_marke :: TypeMark
+  }
+
+--------------------------------------------------------------------------------
+-- * 4.5 Component declarations
+{-
+    component_declaration ::=
+      COMPONENT identifier [ IS ]
+        [ local_generic_clause ]
+	[ local_port_clause ]
+      END COMPONENT [ component_simple_name ] ;
+-}
+
+data ComponentDeclaration = ComponentDeclaration {
+    comp_identifier           :: Identifier
+  , comp_local_generic_clause :: Maybe GenericClause
+  , comp_local_port_clause    :: Maybe PortClause
+  , comp_simple_name          :: Maybe SimpleName
+  }
+
+--------------------------------------------------------------------------------
+-- * 4.6 Group template declarations
+{-
+    group_template_declaration ::=
+      GROUP identifier IS ( entity_class_entry_list ) ;
+
+    entity_class_entry_list ::=
+      entity_class_entry { , entity_class_entry }
+
+    entity_class_entry ::= entity_class [ <> ]
+-}
+
+data GroupTemplateDeclaration = GroupTemplateDeclaration {
+    gtd_identifier              :: Identifier
+  , gtd_entity_class_entry_list :: EntityClassEntryList
+  }
+
+type EntityClassEntryList = [EntityClassEntry]
+
+data EntityClassEntry = EntityClassEntry {
+    entc_entity_class :: EntityClass
+  , entc_multiple     :: Bool
+  }
+
+--------------------------------------------------------------------------------
+-- * 4.7 Group declarations
+{-
+    group_declaration ::=
+      GROUP identifier : group_template_name ( group_constituent_list ) ;
+
+    group_constituent_list ::= group_constituent { , group_constituent }
+
+    group_constituent ::= name | character_literal
+-}
+
+data GroupDeclaration = GroupDeclaration {
+    group_identifier       :: Identifier
+  , group_template_name    :: Name
+  , group_constituent_list :: GroupConstituentList
+  }
+
+type GroupConstituentList = [GroupConstituent]
+
+data GroupConstituent =
+    GCName Name
+  | GCChar CharacterLiteral
+
+--------------------------------------------------------------------------------
+--
+--                                   -- 5 --
+--
+--                               Specifications
+--
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+-- * 5.1 Attribute specification
+{-
+    attribute_specification ::=
+      ATTRIBUTE attribute_designator OF entity_specification IS expression ;
+
+    entity_specification ::=
+      entity_name_list : entity_class
+
+    entity_class ::=
+        ENTITY     | ARCHITECTURE  | CONFIGURATION
+      | PROCEDURE  | FUNCTION	   | PACKAGE
+      | TYPE       | SUBTYPE	   | CONSTANT
+      | SIGNAL     | VARIABLE      | COMPONENT
+      | LABEL	   | LITERAL       | UNITS
+      | GROUP	   | FILE
+
+    entity_name_list ::=
+	entity_designator { , entity_designator }
+      | OTHERS
+      | ALL
+
+    entity_designator ::= entity_tag [ signature ]
+
+    entity_tag ::= simple_name | character_literal | operator_symbol
+-}
+
+data AttributeSpecification = AttributeSpecification {
+    as_attribute_designator :: AttributeDesignator
+  , as_entity_specification :: EntitySpecification
+  , as_expression           :: Expression
+  }
+
+data EntitySpecification = EntitySpecification {
+    es_entity_name_list     :: EntityNameList
+  , es_entity_class         :: EntityClass
+  }
+
+data EntityClass =
+    ENTITY     | ARCHITECTURE  | CONFIGURATION
+  | PROCEDURE  | FUNCTION      | PACKAGE
+  | TYPE       | SUBTYPE       | CONSTANT
+  | SIGNAL     | VARIABLE      | COMPONENT
+  | LABEL      | LITERAL       | UNITS
+  | GROUP      | FILE
+
+data EntityNameList =
+    ENLDesignators [EntityDesignator]
+  | ENLOthers
+  | ENLAll
+
+data EntityDesignator = EntityDesignator {
+    ed_entity_tag :: EntityTag
+  , ed_signature  :: Maybe Signature
+  }
+
+data EntityTag =
+    ETName SimpleName
+  | ETChar CharacterLiteral
+  | ETOp   OperatorSymbol
+
+--------------------------------------------------------------------------------
+-- * 5.2 Configuration specification
+{-
+    configuration_specification ::=
+      FOR component_specification binding_indication ;
+
+    component_specification ::=
+      instantiation_list : component_name
+
+    instantiation_list ::=
+	instantiation_label { , instantiation_label }
+      | OTHERS
+      | ALL
+
+-}
+
+data ConfigurationSpecification = ConfigurationSpecification {
+    cs_component_specification :: ComponentSpecification
+  , cs_binding_indication      :: BindingIndication
+  }
+
+data ComponentSpecification = ComponentSpecification {
+    cs_instantiation_list      :: InstantiationList
+  , cs_component_name          :: Name
+  }
+
+data InstantiationList =
+    ILLabels [Label]
+  | ILOthers
+  | ILAll
+
+--------------------------------------------------------------------------------
+-- ** 5.2.1 Binding indication
+{-
+    binding_indication ::=
+      [ USE entity_aspect ]
+      [ generic_map_aspect ]
+      [ port_map_aspect ]
+-}
+
+data BindingIndication = BindingIndication {
+    bi_entity_aspect      :: Maybe EntityAspect
+  , bi_generic_map_aspect :: Maybe GenericMapAspect
+  , bi_port_map_aspect    :: Maybe PortMapAspect
+  }
+
+--------------------------------------------------------------------------------
+-- *** 5.2.1.1 Entity aspect
+{-
+    entity_aspect ::=
+        ENTITY entity_name [ ( architecture_identifier) ]
+      | CONFIGURATION configuration_name
+      | OPEN
+-}
+
+data EntityAspect =
+    EAEntity Name (Maybe Identifier)
+  | EAConfig Name
+  | EAOpen
+
+--------------------------------------------------------------------------------
+-- *** 5.2.1.2 Generic map and port map aspects
+{-
+    generic_map_aspect ::=
+      GENERIC MAP ( generic_association_list )
+
+    port_map_aspect ::=
+      PORT MAP ( port_association_list )
+-}
+
+data GenericMapAspect = GenericMapAspect AssociationList
+
+data PortMapAspect    = PortMapAspect    AssociationList
+
+--------------------------------------------------------------------------------
+-- ** 5.2.2 Default binding indication
+
+-- defaults ... todo?
+
+--------------------------------------------------------------------------------
+-- * 5.3 Disconnection specification
+{-
+    disconnection_specification ::=
+      DISCONNECT guarded_signal_specification AFTER time_expression ;
+
+    guarded_signal_specification ::=
+      guarded_signal_list : type_mark
+
+    signal_list ::=
+	signal_name { , signal_name }
+      | OTHERS
+      | ALL
+-}
+
+data DisconnectionSpecification = DisconnectionSpecification {
+    ds_guarded_signal_specification :: GuardedSignalSpecification
+  , ds_time_expression              :: Expression
+  }
+
+data GuardedSignalSpecification = GuardedSignalSpecification {
+    gs_guarded_signal_list          :: SignalList
+  , gs_type_mark                    :: TypeMark
+  }
+
+data SignalList =
+    SLName   [Name]
+  | SLOthers
+  | SLAll
+
+--------------------------------------------------------------------------------
+--
+--                                   -- 6 --
+--
+--                                    Names
+--
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+-- * 6.1 Names
+{-
+    name ::=
+	simple_name
+      | operator_symbol
+      | selected_name
+      | indexed_name
+      | slice_name
+      | attribute_name
+
+    prefix ::=
+        name
+      | function_call
+-}
+
+data Name =
+    NSimple SimpleName
+  | NOp     OperatorSymbol
+  | NSelect SelectedName
+  | NIndex  IndexedName
+  | NSlice  SliceName
+  | NAttr   AttributeName
+
+data Prefix =
+    PName Name
+  | PFun  FunctionCall
+
+--------------------------------------------------------------------------------
+-- * 6.2 Simple names
+{-
+    simple_name ::= identifier
+-}
+
+type SimpleName = Identifier
+
+--------------------------------------------------------------------------------
+-- * 6.3 Selected names
+{-
+    selected_name ::= prefix . suffix
+
+    suffix ::=
+        simple_name
+      | character_literal
+      | operator_symbol
+      | ALL
+-}
+
+data SelectedName = SelectedName {
+    sname_prefix :: Prefix
+  , sname_suffix :: Suffix
+  }
+
+data Suffix =
+    SSimple SimpleName
+  | SChar   CharacterLiteral
+  | SOp     OperatorSymbol
+  | SAll
+
+--------------------------------------------------------------------------------
+-- * 6.4 Indexed names
+{-
+    indexed_name ::= prefix ( expression { , expression } )
+-}
+
+data IndexedName = IndexedName {
+    iname_prefix     :: Prefix
+  , iname_expression :: [Expression]
+  }
+
+--------------------------------------------------------------------------------
+-- * 6.5 Slice names
+{-
+    slice_name ::= prefix ( discrete_range )
+-}
+
+data SliceName = SliceName {
+    slice_prefix         :: Prefix
+  , slice_discrete_range :: DiscreteRange
+  }
+
+--------------------------------------------------------------------------------
+-- * 6.6 Attribute names
+{-
+    attribute_name ::=
+      prefix [ signature ] ' attribute_designator [ ( expression ) ]
+
+    attribute_designator ::= attribute_simple_name
+-}
+
+data AttributeName = AttributeName {
+    aname_prefix               :: Prefix
+  , aname_signature            :: Maybe Signature
+  , aname_attribute_designator :: AttributeDesignator
+  , aname_expression           :: Maybe Expression
+  }
+
+type AttributeDesignator = SimpleName
+
+--------------------------------------------------------------------------------
+--
+--                                   -- 7 --
+--
+--                                 Expression
+--
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+-- * 7.1 Rules for expressions
+{-
+    expression ::=
+	relation { AND relation }
+      | relation { OR relation }
+      | relation { XOR relation }
+      | relation [ NAND relation ]
+      | relation [ NOR relation ]
+      | relation { XNOR relation }
+
+    relation ::=
+      shift_expression [ relational_operator shift_expression ]
+
+    shift_expression ::=
+      simple_expression [ shift_operator simple_expression ]
+
+    simple_expression ::=
+      [ sign ] term { adding_operator term }
+
+    term ::=
+      factor { multiplying_operator factor }
+
+    factor ::=
+	primary [ ** primary ]
+      | ABS primary
+      | NOT primary
+
+    primary ::=
+	name
+      | literal
+      | aggregate
+      | function_call
+      | qualified_expression
+      | type_conversion
+      | allocator
+      | ( expression )
+-}
+
+data Expression =
+    EAnd  [Relation]
+  | EOr   [Relation]
+  | EXor  [Relation]
+  | ENand (Relation) (Maybe Relation)
+  | ENor  (Relation) (Maybe Relation)
+  | EXnor [Relation]
+
+data Relation         = Relation {
+    relation_shift_expression :: ShiftExpression
+  , relation_operator         :: Maybe (RelationalOperator, ShiftExpression)
+  }
+
+data ShiftExpression  = ShiftExpression {
+    shifte_simple_expression  :: SimpleExpression
+  , shifte_shift_operator     :: Maybe (ShiftOperator, SimpleExpression)
+  }
+
+data SimpleExpression = SimpleExpression {
+    sexp_sign                 :: Maybe Sign
+  , sexp_term                 :: Term
+  , sexp_adding               :: [(AddingOperator, Term)]
+  }
+
+data Term = Term {
+    term_factor               :: Factor
+  , term_multiplying          :: [(MultiplyingOperator, Factor)]
+  }
+
+data Factor =
+    FacPrim Primary (Maybe Primary)
+  | FacAbs  Primary
+  | FacNot  Primary
+
+data Primary =
+    PrimName  Name
+  | PrimLit   Literal
+  | PrimAgg   Aggregate
+  | PrimFun   FunctionCall
+  | PrimQual  QualifiedExpression
+  | PrimTCon  TypeConversion
+  | PrimAlloc Allocator
+  | PrimExp   Expression
+
+--------------------------------------------------------------------------------
+-- * 7.2 Operators
+{-
+    logical_operator ::= AND | OR | NAND | NOR | XOR | XNOR
+
+    relational_operator ::= = | /= | < | <= | > | >=
+
+    shift_operator ::= SLL | SRL | SLA | SRA | ROL | ROR
+
+    adding_operator ::= + | – | &
+
+    sign ::= + | –
+
+    multiplying_operator ::= * | / | MOD | REM
+
+    miscellaneous_operator ::= ** | ABS | NOT
+-}
+
+data LogicalOperator  = And | Or | Nand | Nor | Xor | Xnor
+
+data RelationalOperator = Eq | Neq | Lt | Lte | Gt | Gte
+
+data ShiftOperator    = Sll | Srl | Sla | Sra | Rol | Ror
+
+data AddingOperator   = Plus | Minus | Concat
+
+data Sign             = Identity | Negation
+
+data MultiplyingOperator = Times | Div | Mod | Rem
+
+data MiscellaneousOperator = Exp | Abs | Not
+
+--------------------------------------------------------------------------------
+-- ** 7.2.1 Logical operators
+
+-- ...
+
+--------------------------------------------------------------------------------
+-- ** 7.2.2 Relational operators
+
+-- ...
+
+--------------------------------------------------------------------------------
+-- ** 7.2.3 Shift operators
+
+-- ...
+
+--------------------------------------------------------------------------------
+-- ** 7.2.4 Adding operators
+
+-- ...
+
+--------------------------------------------------------------------------------
+-- ** 7.2.5 Sign operators
+
+-- ...
+
+--------------------------------------------------------------------------------
+-- ** 7.2.6 Multiplying operators
+
+-- ...
+
+--------------------------------------------------------------------------------
+-- ** 7.2.7 Miscellaneous operators
+
+-- ...
+
+--------------------------------------------------------------------------------
+-- * 7.3 Operands
+
+--------------------------------------------------------------------------------
+-- ** 7.3.1 Literals
+{-
+    literal ::=
+	numeric_literal
+      | enumeration_literal
+      | string_literal
+      | bit_string_literal
+      | NULL
+
+    numeric_literal ::=
+	abstract_literal
+      | physical_literal
+-}
+
+data Literal =
+    LitNum       NumericLiteral
+  | LitEnum      EnumerationLiteral
+  | LitString    StringLiteral
+  | LitBitString BitStringLiteral
+  | LitNull 
+
+data NumericLiteral =
+    NLitAbstract AbstractLiteral
+  | NLitPhysical PhysicalLiteral
+
+--------------------------------------------------------------------------------
+-- ** 7.3.2 Aggregates
+
+{-
+    aggregate ::=
+      ( element_association { , element_association } )
+
+    element_association ::=
+      [ choices => ] expression
+
+    choices ::= choice { | choice }
+
+    choice ::=
+        simple_expression
+      | discrete_range
+      | element_simple_name
+      | OTHERS
+-}
+
+data Aggregate = Aggregate {
+    agg_element_association :: [ElementAssociation]
+  }
+
+data ElementAssociation = ElementAssociation {
+    eassoc_choices'   :: Maybe Choices
+  , eassoc_expression :: Expression
+  }
+
+data Choices = Choices [Choice]
+
+data Choice =
+    ChoiceSimple SimpleExpression
+  | ChoiceRange  DiscreteRange
+  | ChoiceName   SimpleName
+  | ChoiceOthers
+
+--------------------------------------------------------------------------------
+-- *** 7.3.2.1 Record aggregates
+
+-- ...
+
+--------------------------------------------------------------------------------
+-- *** 7.3.2.2 Array aggregates
+
+-- ...
+
+--------------------------------------------------------------------------------
+-- ** 7.3.3 Function calls
+{-
+    function_call ::=
+      function_name [ ( actual_parameter_part ) ]
+
+    actual_parameter_part ::= parameter_association_list
+-}
+
+data FunctionCall = FunctionCall {
+    fc_function_name         :: Name
+  , fc_actual_parameter_part :: Maybe ActualParameterPart
+  }
+
+type ActualParameterPart = AssociationList
+
+--------------------------------------------------------------------------------
+-- ** 7.3.4 Qualified expressions
+{-
+    qualified_expression ::=
+	type_mark ' ( expression )
+      | type_mark ' aggregate
+-}
+
+data QualifiedExpression =
+    QualExp TypeMark Expression
+  | QualAgg TypeMark Aggregate
+
+--------------------------------------------------------------------------------
+-- ** 7.3.5 Type conversions
+{-
+    type_conversion ::= type_mark ( expression )
+-}
+
+data TypeConversion = TypeConversion {
+    type_mark  :: TypeMark
+  , expression :: Expression
+  }
+
+--------------------------------------------------------------------------------
+-- ** 7.3.6 Allocators
+{-
+    allocator ::=
+	NEW subtype_indication
+      | NEW qualified_expression
+-}
+
+data Allocator =
+    AllocSub  SubtypeIndication
+  | AllocQual QualifiedExpression
+
+--------------------------------------------------------------------------------
+-- * 7.4 Static expressions
+
+--------------------------------------------------------------------------------
+-- ** 7.4.1 Locally static primaries
+
+-- ...
+
+--------------------------------------------------------------------------------
+-- ** 7.4.2 Globally static primaries
+
+-- ...
+
+--------------------------------------------------------------------------------
+-- * 7.5 Universal expressions
+
+-- ...
+
+
+--------------------------------------------------------------------------------
+--
+--                                   -- 8 --
+--
+--                             Sequential statements
+--
+--------------------------------------------------------------------------------
+{-
+    sequence_of_statements ::= { sequential_statement }
+
+    sequential_statement ::=
+        wait_statement
+      | assertion_statement
+      | report_statement
+      | signal_assignment_statement
+      | variable_assignment_statement
+      | procedure_call_statement
+      | if_statement
+      | case_statement
+      | loop_statement
+      | next_statement
+      | exit_statement
+      | return_statement
+      | null_statement
+-}
+
+type SequenceOfStatements = [SequentialStatement]
+
+data SequentialStatement =
+    SWait      WaitStatement
+  | SAssert    AssertionStatement
+  | SReport    ReportStatement
+  | SSignalAss SignalAssignmentStatement
+  | SVarAss    VariableAssignmentStatement
+  | SProc      ProcedureCallStatement
+  | SIf        IfStatement
+  | SCase      CaseStatement
+  | SLoop      LoopStatement
+  | SNext      NextStatement
+  | SExit      ExitStatement
+  | SReturn    ReturnStatement
+  | SNull      NullStatement
+
+--------------------------------------------------------------------------------
+-- * 8.1 Wait statement
+{-
+    wait_statement ::=
+      [ label : ] WAIT [ sensitivity_clause ] [ condition_clause ] [ timeout_clause ] ;
+
+    sensitivity_clause ::= ON sensitivity_list
+
+    sensitivity_list ::= signal_name { , signal_name }
+
+    condition_clause ::= UNTIL condition
+
+    condition ::= boolean_expression
+
+    timeout_clause ::= FOR time_expression
+-}
+
+data WaitStatement = WaitStatement
+    (Maybe Label) (Maybe SensitivityClause) (Maybe ConditionClause) (Maybe TimeoutClause)
+
+data SensitivityClause = SensitivityClause SensitivityList
+
+data SensitivityList = SensitivityList [Name]
+
+data ConditionClause = ConditionClause Condition
+
+type Condition = Expression
+
+data TimeoutClause = TimeoutClause Expression
+
+--------------------------------------------------------------------------------
+-- * 8.2 Assertion statement
+{-
+    assertion_statement ::= [ label : ] assertion ;
+
+    assertion ::=
+      ASSERT condition
+        [ REPORT expression ]
+        [ SEVERITY expression ]
+-}
+
+data AssertionStatement = AssertionStatement
+      (Maybe Label) Assertion
+
+data Assertion = Assertion
+      Condition (Maybe Expression) (Maybe Expression)
+
+--------------------------------------------------------------------------------
+-- * 8.3 Report statement
+{-
+    report_statement ::=
+      [ label : ]
+        REPORT expression
+          [ SEVERITY expression ] ;
+-}
+
+data ReportStatement = ReportStatement
+      (Maybe Label) Expression (Maybe Expression)
+
+--------------------------------------------------------------------------------
+-- * 8.4 Signal assignment statement
+{-
+    signal_assignment_statement ::=
+      [ label : ] target <= [ delay_mechanism ] waveform ;
+
+    delay_mechanism ::=
+        TRANSPORT
+      | [ REJECT time_expression ] INERTIAL
+
+    target ::=
+        name
+      | aggregate
+
+    waveform ::=
+        waveform_element { , waveform_element }
+      | UNAFFECTED
+-}
+
+data SignalAssignmentStatement = SignalAssignmentStatement
+      (Maybe Label) Target (Maybe DelayMechanism) Waveform
+
+data DelayMechanism =
+    DMechTransport
+  | DMechInertial  (Maybe Expression)
+
+data Target = 
+    TargetName Name
+  | TargetAgg  Aggregate
+
+data Waveform =
+    WaveElem [WaveformElement]
+  | WaveUnaffected
+
+--------------------------------------------------------------------------------
+-- ** 8.4.1 Updating a projected output waveform
+{-
+    waveform_element ::=
+        value_expression [ AFTER time_expression ]
+      | null [ AFTER time_expression ]
+-}
+
+data WaveformElement =
+    WaveEExp  Expression (Maybe Expression)
+  | WaveENull            (Maybe Expression)
+
+--------------------------------------------------------------------------------
+-- * 8.5 Variable assignment statement
+{-
+    variable_assignment_statement ::=
+      [ label : ] target := expression ;
+-}
+
+data VariableAssignmentStatement = VariableAssignmentStatement
+      (Maybe Label) Target Expression
+
+--------------------------------------------------------------------------------
+-- ** 8.5.1 Array variable assignments
+
+-- ...
+
+--------------------------------------------------------------------------------
+-- * 8.6 Procedure call statement
+{-
+    procedure_call_statement ::= [ label : ] procedure_call ;
+
+    procedure_call ::= procedure_name [ ( actual_parameter_part ) ]
+-}
+
+data ProcedureCallStatement = ProcedureCallStatement
+      (Maybe Label) ProcedureCall
+
+data ProcedureCall = ProcedureCall
+      Name (Maybe ActualParameterPart)
+
+--------------------------------------------------------------------------------
+-- * 8.7 If statement
+{-
+    if_statement ::=
+      [ if_label : ]
+        IF condition THEN
+          sequence_of_statements
+        { ELSEIF condition THEN
+          sequence_of_statements }
+        [ ELSE
+          sequence_of_statements ]
+        END IF [ if_label ] ;
+-}
+
+data IfStatement = IfStatement {
+    if_label     :: Maybe Label
+  , if_then      :: (Condition, SequenceOfStatements)
+  , if_also      :: [(Condition, SequenceOfStatements)]
+  , if_else      :: Maybe SequenceOfStatements
+  }
+
+--------------------------------------------------------------------------------
+-- * 8.8 Case statement
+{-
+    case_statement ::=
+      [ case_label : ]
+        CASE expression IS
+          case_statement_alternative
+          { case_statement_alternative }
+        END CASE [ case_label ] ;
+
+    case_statement_alternative ::=
+      WHEN choices =>
+        sequence_of_statements
+-}
+
+data CaseStatement = CaseStatement {
+    case_label        :: Maybe Label
+  , case_expression   :: Expression
+  , case_alternatives :: [CaseStatementAlternative]
+  }
+
+data CaseStatementAlternative = CaseStatementAlternative Choices SequenceOfStatements
+
+--------------------------------------------------------------------------------
+-- * 8.9 Loop statement
+{-
+    loop_statement ::=
+      [ loop_label : ]
+        [ iteration_scheme ] LOOP
+          sequence_of_statements
+        END LOOP [ loop_label ] ;
+
+    iteration_scheme ::=
+        WHILE condition
+      | FOR loop_parameter_specification
+
+    parameter_specification ::=
+      identifier IN discrete_range
+-}
+
+data LoopStatement = LoopStatement {
+    loop_label            :: Maybe Label
+  , loop_iteration_scheme :: Maybe IterationScheme
+  , loop_statements       :: SequenceOfStatements
+  }
+
+data IterationScheme =
+    IterWhile Condition
+  | IterFor   ParameterSpecification
+
+data ParameterSpecification = ParameterSpecification {
+    paramspec_identifier     :: Identifier
+  , paramspec_discrete_range :: DiscreteRange
+  }
+
+--------------------------------------------------------------------------------
+-- * 8.10 Next statement
+{-
+    next_statement ::=
+      [ label : ] NEXT [ loop_label ] [ WHEN condition ] ;
+-}
+
+data NextStatement = NextStatement {
+    next_label :: Maybe Label
+  , next_loop  :: Maybe Label
+  , next_when  :: Maybe Condition
+  }
+
+--------------------------------------------------------------------------------
+-- * 8.11 Exit statement
+{-
+    exit_statement ::=
+      [ label : ] EXIT [ loop_label ] [ WHEN condition ] ;
+-}
+
+data ExitStatement = ExitStatement {
+    exit_label :: Maybe Label
+  , exit_loop  :: Maybe Label
+  , exit_when  :: Maybe Condition
+  }
+
+--------------------------------------------------------------------------------
+-- * 8.12 Return statement
+{-
+    return_statement ::=
+      [ label : ] RETURN [ expression ] ;
+-}
+
+data ReturnStatement = ReturnStatement {
+    return_label      :: Maybe Label
+  , return_expression :: Maybe Expression
+  }
+
+--------------------------------------------------------------------------------
+-- * 8.13 Null statement
+{-
+    null_statement ::=
+      [ label : ] NULL ;
+-}
+
+data NullStatement = NullStatement {
+    null_label :: Maybe Label
+  }
+
+--------------------------------------------------------------------------------
+--
+--                                   -- 9 --
+--
+--                            Concurrent statements
+--
+--------------------------------------------------------------------------------
+
+{-
+    concurrent_statement ::=
+        block_statement
+      | process_statement
+      | concurrent_procedure_call_statement
+      | concurrent_assertion_statement
+      | concurrent_signal_assignment_statement
+      | component_instantiation_statement
+      | generate_statement
+-}
+
+data ConcurrentStatement =
+    ConBlock     BlockStatement
+  | ConProcess   ProcessStatement
+  | ConProcCall  ConcurrentProcedureCallStatement
+  | ConAssertion ConcurrentAssertionStatement
+  | ConSignalAss ConcurrentSignalAssignmentStatement
+  | ConComponent ComponentInstantiationStatement
+  | ConGenerate  GenerateStatement
+
+--------------------------------------------------------------------------------
+-- * 9.1 Block statement
+{-
+    block_statement ::=
+      block_label :
+        BLOCK [ ( guard_expression ) ] [ IS ]
+          block_header
+          block_declarative_part
+        BEGIN
+          block_statement_part
+        END BLOCK [ block_label ] ;
+
+    block_header ::=
+      [ generic_clause
+        [ generic_map_aspect ; ] ]
+      [ port_clause
+        [ port_map_aspect ; ] ]
+
+    block_declarative_part ::=
+      { block_declarative_item }
+
+    block_statement_part ::=
+      { concurrent_statement }
+-}
+
+data BlockStatement = BlockStatement {
+    blocks_label            :: Label
+  , blocks_guard_expression :: Maybe Expression
+  , blocks_header           :: BlockHeader
+  , blocks_declarative_part :: BlockDeclarativePart
+  , blocks_statment_part    :: BlockStatementPart
+  }
+
+data BlockHeader = BlockHeader {
+    blockh_generic_clause   :: Maybe (GenericClause, Maybe GenericMapAspect)
+  , blockh_port_clause      :: Maybe (PortClause,    Maybe PortMapAspect)
+  }
+
+type BlockDeclarativePart = [BlockDeclarativeItem]
+
+type BlockStatementPart   = [ConcurrentStatement]
+
+--------------------------------------------------------------------------------
+-- * 9.2 Process statement
+{-
+    process_statement ::=
+      [ process_label : ]
+        [ POSTPONED ] PROCESS [ ( sensitivity_list ) ] [ IS ]
+          process_declarative_part
+        BEGIN
+          process_statement_part
+        END [ POSTPONED ] PROCESS [ process_label ] ;
+
+    process_declarative_part ::=
+      { process_declarative_item }
+
+    process_declarative_item ::=
+        subprogram_declaration
+      | subprogram_body
+      | type_declaration
+      | subtype_declaration
+      | constant_declaration
+      | variable_declaration
+      | file_declaration
+      | alias_declaration
+      | attribute_declaration
+      | attribute_specification
+      | use_clause
+      | group_type_declaration
+-}
+
+data ProcessStatement = ProcessStatement {
+    procs_label            :: Maybe Label
+  , procs_postponed        :: Bool
+  , procs_sensitivity_list :: Maybe SensitivityList
+  , procs_declarative_part :: ProcessDeclarativePart
+  , procs_statement_part   :: ProcessStatement
+  }
+
+type ProcessDeclarativePart = [ProcessDeclarativeItem]
+
+data ProcessDeclarativeItem =
+    ProcDISubprogDecl SubprogramDeclaration
+  | ProcDISubprogBody SubprogramBody
+  | ProcDIType        TypeDeclaration
+  | ProcDISubtype     SubtypeDeclaration
+  | ProcDIConstant    ConstantDeclaration
+  | ProcDIVariable    VariableDeclaration
+  | ProcDIFile        FileDeclaration
+  | ProcDIAlias       AliasDeclaration
+  | ProcDIAttrDecl    AttributeDeclaration
+  | ProcDIAttrSpec    AttributeSpecification
+  | ProcDIUseClause   UseClause
+--  | ProcDIGroupType   ()
+
+--------------------------------------------------------------------------------
+-- * 9.3 Concurrent procedure call statements
+{-
+    concurrent_procedure_call_statement ::=
+      [ label : ] [ POSTPONED ] procedure_call ;
+-}
+
+data ConcurrentProcedureCallStatement = ConcurrentProcedureCallStatement {
+    cpcs_label          :: Maybe Label
+  , cpcs_postponed      :: Bool
+  , cpcs_procedure_call :: ProcedureCall
+  }
+
+--------------------------------------------------------------------------------
+-- * 9.4 Concurrent assertion statements
+{-
+    concurrent_assertion_statement ::=
+      [ label : ] [ POSTPONED ] assertion ;
+-}
+
+data ConcurrentAssertionStatement = ConcurrentAssertionStatement {
+    cas_label          :: Maybe Label
+  , cas_postponed      :: Bool
+  , cas_assertion      :: Assertion
+  }
+
+--------------------------------------------------------------------------------
+-- * 9.5 Concurrent signal assignment statements
+{-
+    concurrent_signal_assignment_statement ::=
+        [ label : ] [ POSTPONED ] conditional_signal_assignment
+      | [ label : ] [ POSTPONED ] selected_signal_assignment
+
+    options ::= [ GUARDED ] [ delay_mechanism ]
+-}
+
+data ConcurrentSignalAssignmentStatement =
+    CSASCond {
+      csas_cond_label               :: Maybe Label
+    , csas_cond_postponed           :: Bool
+    , csas_cond_signal_assignment   :: ConditionalSignalAssignment
+    }
+  | CSASSelect {
+      csas_select_label             :: Maybe Label
+    , csas_select_postponed         :: Bool
+    , csas_select_signal_assignment :: SelectedSignalAssignment
+    }
+
+data Options = Options {
+    options_guarded         :: Bool
+  , options_delay_mechanism :: Maybe DelayMechanism
+  }
+
+--------------------------------------------------------------------------------
+-- ** 9.5.1 Conditional signal assignments
+{-
+    conditional_signal_assignment ::=
+      target <= options conditional_waveforms ;
+
+    conditional_waveforms ::=
+      { waveform WHEN condition ELSE }
+      waveform [ WHEN condition ]
+-}
+
+data ConditionalSignalAssignment = ConditionalSignalAssignment {
+    csa_target                :: Target
+  , csa_options               :: Options
+  , csa_conditional_waveforms :: ConditionalWaveforms
+  }
+
+data ConditionalWaveforms = ConditionalWaveforms {
+    cw_optional              :: [(Waveform, Condition)]
+  , cw_wave                  :: (Waveform, Maybe Condition)
+  }
+
+--------------------------------------------------------------------------------
+-- ** 9.5.2 Selected signal assignments
+{-
+    selected_signal_assignment ::=
+      WITH expression SELECT
+        target <= options selected_waveforms ;
+
+    selected_waveforms ::=
+      { waveform WHEN choices , }
+      waveform WHEN choices
+-}
+
+data SelectedSignalAssignment = SelectedSignalAssignment {
+    ssa_expression         :: Expression
+  , ssa_target             :: Target
+  , ssa_options            :: Options
+  , ssa_selected_waveforms :: SelectedWaveforms
+  }
+
+data SelectedWaveforms = SelectedWaveforms {
+    sw_optional :: Maybe [(Waveform, Choices)]
+  , sw_last     :: (Waveform, Choices)
+  }
+
+--------------------------------------------------------------------------------
+-- * 9.6 Component instantiation statements
+{-
+    component_instantiation_statement ::=
+      instantiation_label :
+        instantiated_unit
+          [ generic_map_aspect ]
+          [ port_map_aspect ] ;
+
+    instantiated_unit ::=
+        [ COMPONENT ] component_name
+      | ENTITY entity_name [ ( architecture_identifier ) ]
+      | CONFIGURATION configuration_name
+-}
+
+data ComponentInstantiationStatement = ComponentInstantiationStatement {
+    cis_instantiation_label :: Label
+  , cis_instantiated_unit   :: InstantiatedUnit
+  , cis_generic_map_aspect  :: Maybe GenericMapAspect
+  , cis_port_map_aspect     :: Maybe PortMapAspect
+  }
+
+data InstantiatedUnit =
+    IUComponent Name
+  | IUEntity    Name (Maybe Identifier)
+  | IUConfig    Name
+
+--------------------------------------------------------------------------------
+-- ** 9.6.1 Instantiation of a component
+
+--------------------------------------------------------------------------------
+-- ** 9.6.2 Instantiation of a design entity
+
+--------------------------------------------------------------------------------
+-- * 9.7 Generate statements
+{-
+    generate_statement ::=
+      generate_label :
+        generation_scheme GENERATE
+          [ { block_declarative_item }
+        BEGIN ]
+          { concurrent_statement }
+        END GENERATE [ generate_label ] ;
+
+    generation_scheme ::=
+        FOR generate_parameter_specification
+      | IF condition
+
+    label ::= identifier
+-}
+
+data GenerateStatement = GenerateStatement {
+    gens_label                  :: Label
+  , gens_generation_scheme      :: GenerationScheme
+  , gens_block_declarative_item :: Maybe (BlockDeclarativeItem)
+  , gens_concurrent_statement   :: [ConcurrentStatement]
+  }
+
+data GenerationScheme =
+    GSFor ParameterSpecification
+  | GSIf Condition
+
+type Label = Identifier
+
+--------------------------------------------------------------------------------
+-- ?
+
+data UseClause        = UseClause [SelectedName]
+
+data Identifier       = Ident String
+
+data CharacterLiteral = CLit Char
+
+data StringLiteral    = SLit String
+
+--------------------------------------------------------------------------------
+--
+--                                  - ToDo -
+--
+--------------------------------------------------------------------------------
+
+data AbstractLiteral  = AbstractLiteral
+
+data Base = Base
+
+data BaseSpecifier = BaseSpecifier
+
+data BaseUnitDeclaration = BaseUnitDeclaration
+
+data BasedInteger = BasedInteger
+
+data BasedLiteral = BasedLiteral
+
+data BasicCharacter = BasicCharacter
+
+data BasicGraphicCharacter = BasicGraphicCharacter
+
+data BasicIdentifier = BasicIdentifier
+
+data BitStringLiteral = BitStringLiteral
+
+data BitValue = BitValue
+
+data ContextClause = ContextClause
+
+data ContextItem = ContextItem
+
+data DecimalLiteral = DecimalLiteral
+
+data DesignFile = DesignFile
+
+data DesignUnit = DesignUnit
+
+data Exponent = Exponent
+
+data ExtendedDigit = ExtendedDigit
+
+data ExtendedIdentifier = ExtendedIdentifier
+
+data GraphicCharacter = GraphicCharacter
+
+data Letter = Letter
+
+data LetterOrDigit = LetterOrDigit
+
+data LibraryClause = LibraryClause
+
+data LibraryUnit = LibraryUnit
+
+data LogicalName = LogicalName
+
+data LogicalNameList = LogicalNameList
+
+data PrimaryUnit = PrimaryUnit
+
+data ProcessStatementPart = ProcessStatementPart
+
+data SecondaryUnit = SecondaryUnit
+
+--------------------------------------------------------------------------------
