Coverage for pyVHDLModel/Type.py: 98%
287 statements
« prev ^ index » next coverage.py v7.17.0, created at 2026-10-25 10:05 +0000
« prev ^ index » next coverage.py v7.17.0, created at 2026-10-25 10:05 +0000
1# ==================================================================================================================== #
2# __ ___ _ ____ _ __ __ _ _ #
3# _ __ _ \ \ / / | | | _ \| | | \/ | ___ __| | ___| | #
4# | '_ \| | | \ \ / /| |_| | | | | | | |\/| |/ _ \ / _` |/ _ \ | #
5# | |_) | |_| |\ V / | _ | |_| | |___| | | | (_) | (_| | __/ | #
6# | .__/ \__, | \_/ |_| |_|____/|_____|_| |_|\___/ \__,_|\___|_| #
7# |_| |___/ #
8# ==================================================================================================================== #
9# Authors: #
10# Patrick Lehmann #
11# #
12# License: #
13# ==================================================================================================================== #
14# Copyright 2017-2026 Patrick Lehmann - Boetzingen, Germany #
15# Copyright 2016-2017 Patrick Lehmann - Dresden, Germany #
16# #
17# Licensed under the Apache License, Version 2.0 (the "License"); #
18# you may not use this file except in compliance with the License. #
19# You may obtain a copy of the License at #
20# #
21# http://www.apache.org/licenses/LICENSE-2.0 #
22# #
23# Unless required by applicable law or agreed to in writing, software #
24# distributed under the License is distributed on an "AS IS" BASIS, #
25# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
26# See the License for the specific language governing permissions and #
27# limitations under the License. #
28# #
29# SPDX-License-Identifier: Apache-2.0 #
30# ==================================================================================================================== #
31#
32"""
33This module contains parts of an abstract document language model for VHDL.
35Types.
36"""
37from __future__ import annotations
39from typing import TYPE_CHECKING, Union, Iterator, Iterable, Optional as Nullable, Self
41from pyTooling.Decorators import export, readonly
42from pyTooling.MetaClasses import ExtendedType, abstractclass
43from pyTooling.Graph import Vertex
45from pyVHDLModel.Base import ModelEntity, NamedEntityMixin, MultipleNamedEntityMixin, DocumentedEntityMixin, Range
46from pyVHDLModel.Symbol import Symbol, SimpleSubtypeSymbol
47from pyVHDLModel.Expression import EnumerationLiteral, PhysicalIntegerLiteral
48from pyVHDLModel.Regions import ProtectedTypeDeclarationRegionMixin, SequentialDeclarationRegionMixin, \
49 WithoutStatementsMixin
51if TYPE_CHECKING: 51 ↛ 52line 51 didn't jump to line 52 because the condition on line 51 was never true
52 from pyVHDLModel.Visitor import Visitor
55@export
56@abstractclass
57class BaseType(ModelEntity, NamedEntityMixin, DocumentedEntityMixin):
58 """
59 Represents the base-class of all type entities: full types, subtypes and anonymous types.
61 Every type is a named entity (:data:`Identifier`, :data:`NormalizedIdentifier`) and can carry
62 documentation (:data:`Documentation`).
64 .. seealso::
66 * :class:`Type <pyVHDLModel.Type.Type>`
67 * :class:`Full type <pyVHDLModel.Type.FullType>`
68 * :class:`Subtype <pyVHDLModel.Type.Subtype>`
69 """
71 _objectVertex: Vertex #: The vertex representing this type in the design's object graph.
73 def __init__(self, identifier: str, documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None:
74 """
75 Initializes underlying ``BaseType``.
77 :param identifier: Name of the type.
78 :param documentation: The documentation comment associated with this declaration.
79 :param parent: Reference to the logical parent in the model hierarchy.
80 """
81 super().__init__(parent)
82 NamedEntityMixin.__init__(self, identifier)
83 DocumentedEntityMixin.__init__(self, documentation)
85 self._objectVertex = None
87 def __str__(self) -> str:
88 """
89 Formats the type declaration.
91 **Format:** ``type myType``
93 :returns: Formatted type declaration.
94 """
95 return f"type {self._identifier}"
98@export
99@abstractclass
100class Type(BaseType):
101 """
102 Represents a base-class for types introduced by a type declaration.
104 Besides real type declarations, this is also the base-class of a generic type interface item, which
105 introduces a type name without defining the type itself.
107 .. seealso::
109 * :class:`Generic type interface item <pyVHDLModel.Interface.GenericTypeInterfaceItem>`
110 * :class:`Anonymous type <pyVHDLModel.Type.AnonymousType>`
111 """
112 pass
115@export
116class AnonymousType(Type):
117 """
118 Represents a base-class for types without a type definition of their own.
120 An incomplete type is the typical case: it names a type (:data:`Identifier`) whose full
121 definition follows later in the same declarative part.
123 .. admonition:: Example
125 .. code-block:: VHDL
127 type node;
128 -- ^^^^ <- Identifier
129 type ptr is access node;
130 type node is record
131 value : integer;
132 nextNode : ptr;
133 end record;
134 """
136 def Visit(self, visitor: Visitor) -> None:
137 """
138 Walk this incomplete type declaration with a visitor.
140 :param visitor: The visitor receiving the events.
141 """
142 visitor.VisitAnonymousType(self)
143 visitor.DepartAnonymousType(self)
146@export
147class FullType(BaseType):
148 """
149 Represents a base-class for all full type definitions, as opposed to a :class:`Subtype`.
151 This is the distinction the declaration regions index on: a full type is registered in ``Types``, a
152 subtype in ``Subtypes``.
154 .. seealso::
156 * :class:`Scalar type <pyVHDLModel.Type.ScalarType>`
157 * :class:`Composite type <pyVHDLModel.Type.CompositeType>`
158 * :class:`Protected type <pyVHDLModel.Type.ProtectedType>`
159 * :class:`Protected type body <pyVHDLModel.Type.ProtectedTypeBody>`
160 * :class:`Access type <pyVHDLModel.Type.AccessType>`
161 * :class:`File type <pyVHDLModel.Type.FileType>`
162 """
163 pass
166@export
167class Subtype(BaseType):
168 """
169 Represents a subtype declaration.
171 A subtype is a named entity (:data:`Identifier`, :data:`NormalizedIdentifier`) referencing a type
172 (:data:`Type`). Optionally, the subtype can be narrowed by a constraint (:data:`Range`) and/or
173 resolved by a resolution function (:data:`ResolutionFunction`).
175 .. admonition:: Example
177 Without a constraint:
179 .. code-block:: VHDL
181 subtype byte is bit_vector;
182 -- ^^^^ <- Identifier
183 -- ^^^^^^^^^^ <- Type
185 With a constraint:
187 .. code-block:: VHDL
189 subtype nibble is bit_vector(3 downto 0);
190 -- ^^^^^^^^^^^^ <- Range
192 With a resolution function:
194 .. code-block:: VHDL
196 subtype wired is resolved std_ulogic;
197 -- ^^^^^^^^ <- ResolutionFunction
199 .. seealso::
201 * :class:`Reference to a type or subtype <pyVHDLModel.Symbol.SubtypeSymbol>`
202 """
203 _type: Symbol #: Reference to the type or subtype this subtype is derived from.
204 _baseType: BaseType #: The resolved base type of this subtype.
205 _range: Range #: The constraint narrowing the base type, or ``None`` if unconstrained.
206 _resolutionFunction: Function #: The resolution function, or ``None`` if the subtype is unresolved.
208 def __init__(self, identifier: str, symbol: Symbol, documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None:
209 """
210 Initializes a subtype declaration.
212 :param identifier: The identifier of a model entity.
213 :param symbol: Reference to the type or subtype this subtype is derived from.
214 :param documentation: The documentation comment associated with this declaration.
215 :param parent: The parent model entity of this entity.
216 """
217 super().__init__(identifier, documentation, parent)
219 self._type = symbol
220 self._baseType = None
221 self._range = None
222 self._resolutionFunction = None
224 @readonly
225 def Type(self) -> Symbol:
226 """
227 Read-only property to access the type (:attr:`_type`).
229 :returns: The type.
230 """
231 return self._type
233 @readonly
234 def BaseType(self) -> BaseType:
235 """
236 Read-only property to access the base type (:attr:`_baseType`).
238 :returns: The base type.
239 """
240 return self._baseType
242 @readonly
243 def Range(self) -> Range:
244 """
245 Read-only property to access the range (:attr:`_range`).
247 :returns: The range.
248 """
249 return self._range
251 @readonly
252 def ResolutionFunction(self) -> Function:
253 """
254 Read-only property to access the resolution function (:attr:`_resolutionFunction`).
256 :returns: The resolution function.
257 """
258 return self._resolutionFunction
260 def Visit(self, visitor: Visitor) -> None:
261 """
262 Walk this subtype declaration and its subtype indication with a visitor.
264 :param visitor: The visitor receiving the events.
265 """
266 visitor.VisitSubtype(self)
267 self._type.Visit(visitor)
268 visitor.DepartSubtype(self)
270 def __str__(self) -> str:
271 """
272 Formats the subtype declaration.
274 **Format:** ``subtype byte is bit_vector``
276 The *base type* is rendered, so an unlinked subtype shows ``None``.
278 :returns: Formatted subtype declaration.
279 """
280 return f"subtype {self._identifier} is {self._baseType}"
283@export
284@abstractclass
285class ScalarType(FullType):
286 """
287 Represents a base-class for all scalar types: enumerated, integer, real and physical types.
289 .. seealso::
291 * :class:`Ranged scalar type <pyVHDLModel.Type.RangedScalarType>`
292 * :class:`Enumerated type <pyVHDLModel.Type.EnumeratedType>`
293 """
296@export
297@abstractclass
298class RangedScalarType(ScalarType):
299 """
300 Represents a base-class for all scalar types constrained by a range (:data:`Range`).
302 Integer, real and physical types are ranged. An enumerated type is scalar but not ranged, so it
303 derives from :class:`ScalarType` directly.
305 .. seealso::
307 * :class:`Integer type <pyVHDLModel.Type.IntegerType>`
308 * :class:`Real type <pyVHDLModel.Type.RealType>`
309 * :class:`Physical type <pyVHDLModel.Type.PhysicalType>`
310 """
312 _range: Range #: The range constraining this scalar type.
314 def __init__(self, identifier: str, rng: Range, documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None:
315 """
316 Initialize a scalar type with a range.
318 :param identifier: The type's identifier.
319 :param rng: The type's range.
320 :param documentation: The type's documentation.
321 :param parent: The parent model entity.
322 """
323 super().__init__(identifier, documentation, parent)
324 self._range = rng
326 @readonly
327 def Range(self) -> Range:
328 """
329 Read-only property to access the type's range (:attr:`_range`).
331 :returns: The range.
332 """
333 return self._range
336@export
337class NumericTypeMixin(metaclass=ExtendedType, mixin=True):
338 """
339 A mixin-class for all numeric types: integer, real and physical types.
341 .. seealso::
343 * :class:`Integer type <pyVHDLModel.Type.IntegerType>`
344 * :class:`Real type <pyVHDLModel.Type.RealType>`
345 * :class:`Physical type <pyVHDLModel.Type.PhysicalType>`
346 """
348 def __init__(self) -> None:
349 """
350 Initializes a numeric type.
351 """
352 pass
355@export
356class DiscreteTypeMixin(metaclass=ExtendedType, mixin=True):
357 """
358 A mixin-class for all discrete types: enumerated and integer types.
360 .. seealso::
362 * :class:`Enumerated type <pyVHDLModel.Type.EnumeratedType>`
363 * :class:`Integer type <pyVHDLModel.Type.IntegerType>`
364 """
366 def __init__(self) -> None:
367 """
368 Initializes a discrete type.
369 """
370 pass
373@export
374class EnumeratedType(ScalarType, DiscreteTypeMixin):
375 """
376 Represents an enumerated type definition.
378 An enumerated type is a named entity (:data:`Identifier`) listing its enumeration literals
379 (:data:`Literals`) in declaration order.
381 .. admonition:: Example
383 .. code-block:: VHDL
385 type state is (Idle, Running, Done);
386 -- ^^^^^ <- Identifier
387 -- ^^^^^^^^^^^^^^^^^^^ <- Literals
388 """
389 _literals: list[EnumerationLiteral] #: List of all enumeration literals, in declaration order.
391 def __init__(self, identifier: str, literals: Iterable[EnumerationLiteral], documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None:
392 """
393 Initializes an enumerated type definition.
395 :param identifier: The identifier of a model entity.
396 :param literals: List of all enumeration literals, in declaration order.
397 :param documentation: The documentation comment associated with this declaration.
398 :param parent: The parent model entity of this entity.
399 """
400 super().__init__(identifier, documentation, parent)
402 self._literals = literalList = []
403 if literals is not None:
404 for literal in literals:
405 literalList.append(literal)
406 literal.Parent = self
408 @readonly
409 def Literals(self) -> list[EnumerationLiteral]:
410 """
411 Read-only property to access the literals (:attr:`_literals`).
413 :returns: List of literals.
414 """
415 return self._literals
417 def Visit(self, visitor: Visitor) -> None:
418 """
419 Walk this enumerated type and its literals with a visitor.
421 :param visitor: The visitor receiving the events.
422 """
423 visitor.VisitEnumeratedType(self)
424 for index, literal in enumerate(self._literals):
425 if index > 0:
426 visitor.VisitComma(self)
428 literal.Visit(visitor)
430 visitor.DepartEnumeratedType(self)
432 def __str__(self) -> str:
433 """
434 Formats the enumerated type definition.
436 **Format:** ``state is (idle, run)``
438 :returns: Formatted enumerated type definition.
439 """
440 return f"{self._identifier} is ({', '.join(str(l) for l in self._literals)})"
443@export
444class IntegerType(RangedScalarType, NumericTypeMixin, DiscreteTypeMixin):
445 """
446 Represents an integer type definition.
448 An integer type is a named entity (:data:`Identifier`) constrained by a range (:data:`Range`).
450 .. admonition:: Example
452 .. code-block:: VHDL
454 type nibble is range 0 to 15;
455 -- ^^^^^^ <- Identifier
456 -- ^^^^^^^ <- Range
457 """
458 def __init__(self, identifier: str, rng: Range, documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None:
459 """
460 Initializes an integer type definition.
462 :param identifier: The identifier of a model entity.
463 :param rng: The range constraining this scalar type.
464 :param documentation: The documentation comment associated with this declaration.
465 :param parent: The parent model entity of this entity.
466 """
467 super().__init__(identifier, rng, documentation, parent)
469 def Visit(self, visitor: Visitor) -> None:
470 """
471 Walk this integer type and its range with a visitor.
473 :param visitor: The visitor receiving the events.
474 """
475 visitor.VisitIntegerType(self)
476 self._range.Visit(visitor)
477 visitor.DepartIntegerType(self)
479 def __str__(self) -> str:
480 """
481 Formats the integer type definition.
483 **Format:** ``byte_count is range 0 to 7``
485 :returns: Formatted integer type definition.
486 """
487 return f"{self._identifier} is range {self._range}"
490@export
491class RealType(RangedScalarType, NumericTypeMixin):
492 """
493 Represents a floating-point type definition.
495 A floating-point type is a named entity (:data:`Identifier`) constrained by a range
496 (:data:`Range`).
498 .. admonition:: Example
500 .. code-block:: VHDL
502 type fraction is range 0.0 to 1.0;
503 -- ^^^^^^^^ <- Identifier
504 -- ^^^^^^^^^^ <- Range
505 """
506 def __init__(self, identifier: str, rng: Range, documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None:
507 """
508 Initializes a floating-point type definition.
510 :param identifier: The identifier of a model entity.
511 :param rng: The range constraining this scalar type.
512 :param documentation: The documentation comment associated with this declaration.
513 :param parent: The parent model entity of this entity.
514 """
515 super().__init__(identifier, rng, documentation, parent)
517 def Visit(self, visitor: Visitor) -> None:
518 """
519 Walk this floating-point type and its range with a visitor.
521 :param visitor: The visitor receiving the events.
522 """
523 visitor.VisitRealType(self)
524 self._range.Visit(visitor)
525 visitor.DepartRealType(self)
527 def __str__(self) -> str:
528 """
529 Formats the floating-point type definition.
531 **Format:** ``gain is range 0.0 to 1.0``
533 :returns: Formatted floating-point type definition.
534 """
535 return f"{self._identifier} is range {self._range}"
538@export
539class PhysicalType(RangedScalarType, NumericTypeMixin):
540 """
541 Represents a physical type definition.
543 A physical type is a named entity (:data:`Identifier`) constrained by a range (:data:`Range`), and
544 defines a primary unit (:data:`PrimaryUnit`) plus any number of secondary units
545 (:data:`SecondaryUnits`). The model holds the secondary units in a list and has no distinct field
546 per unit, so the markers below name list elements.
548 .. admonition:: Example
550 .. code-block:: VHDL
552 type distance is range 0 to 1000000 units
553 -- ^^^^^^^^ <- Identifier
554 -- ^^^^^^^^^^^^ <- Range
555 um;
556 --^^^ <- PrimaryUnit
557 mm = 1000 um;
558 --^^^^^^^^^^^^^ <- SecondaryUnits[0]
559 m = 1000 mm;
560 --^^^^^^^^^^^^^ <- SecondaryUnits[1]
561 end units;
562 """
563 _primaryUnit: str #: The name of the type's primary unit.
564 _secondaryUnits: list[tuple[str, PhysicalIntegerLiteral]] #: Secondary units as (name, value) pairs.
566 def __init__(
567 self,
568 identifier: str,
569 rng: Range,
570 primaryUnit: str,
571 units: Iterable[tuple[str, PhysicalIntegerLiteral]],
572 documentation: Nullable[str] = None,
573 parent: Nullable[ModelEntity] = None
574 ) -> None:
575 """
576 Initializes a physical type definition.
578 :param identifier: The identifier of a model entity.
579 :param rng: The range constraining this scalar type.
580 :param primaryUnit: The name of the type's primary unit.
581 :param units: Iterable of the secondary units as (name, value) pairs.
582 :param documentation: The documentation comment associated with this declaration.
583 :param parent: The parent model entity of this entity.
584 """
585 super().__init__(identifier, rng, documentation, parent)
587 self._primaryUnit = primaryUnit
589 self._secondaryUnits = secondaryUnits = [] # TODO: convert to dict
590 for unit in units:
591 secondaryUnits.append(unit)
592 unit[1].Parent = self
594 @readonly
595 def PrimaryUnit(self) -> str:
596 """
597 Read-only property to access the primary unit (:attr:`_primaryUnit`).
599 :returns: The primary unit.
600 """
601 return self._primaryUnit
603 @readonly
604 def SecondaryUnits(self) -> list[tuple[str, PhysicalIntegerLiteral]]:
605 """
606 Read-only property to access the secondary units (:attr:`_secondaryUnits`).
608 :returns: List of secondary units.
609 """
610 return self._secondaryUnits
612 def Visit(self, visitor: Visitor) -> None:
613 """
614 Walk this physical type, its range and its secondary units with a visitor.
616 :param visitor: The visitor receiving the events.
617 """
618 visitor.VisitPhysicalType(self)
619 self._range.Visit(visitor)
620 visitor.VisitUnits(self)
621 for identifier, value in self._secondaryUnits:
622 visitor.VisitSecondaryUnitDeclaration(self, identifier)
623 value.Visit(visitor)
624 visitor.DepartSecondaryUnitDeclaration(self, identifier)
626 visitor.DepartPhysicalType(self)
628 def __str__(self) -> str:
629 """
630 Formats the physical type definition.
632 **Format:** ``distance is range 0 to 1000 units um; mm = 1000 um;``
634 :returns: Formatted physical type definition.
635 """
636 return f"{self._identifier} is range {self._range} units {self._primaryUnit}; {'; '.join(su + ' = ' + str(pu) for su, pu in self._secondaryUnits)};"
639@export
640@abstractclass
641class CompositeType(FullType):
642 """
643 Represents a base-class for all composite types: array and record types.
645 .. seealso::
647 * :class:`Array type <pyVHDLModel.Type.ArrayType>`
648 * :class:`Record type <pyVHDLModel.Type.RecordType>`
649 """
652@export
653class ArrayType(CompositeType):
654 """
655 Represents an array type definition.
657 An array type is a named entity (:data:`Identifier`) defining one or more index ranges
658 (:data:`Dimensions`) and the subtype of its elements (:data:`ElementType`).
660 .. admonition:: Example
662 One dimension:
664 .. code-block:: VHDL
666 type memory is array (0 to 255) of bit_vector(7 downto 0);
667 -- ^^^^^^ <- Identifier
668 -- ^^^^^^^^ <- Dimensions
669 -- ^^^^^^^^^^^^^^^^^^^^^^ <- ElementType
671 Two dimensions, both unconstrained:
673 .. code-block:: VHDL
675 type matrix is array (natural range <>, natural range <>) of bit;
676 -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ <- Dimensions
678 .. seealso::
680 * :class:`Reference to a constrained array subtype <pyVHDLModel.Symbol.ConstrainedArraySubtypeSymbol>`
681 """
682 _dimensions: list[Range] #: List of all index ranges, one per dimension.
683 _elementType: Symbol #: Reference to the subtype of the array's elements.
685 def __init__(
686 self,
687 identifier: str,
688 indices: Iterable,
689 elementSubtype: Symbol,
690 documentation: Nullable[str] = None,
691 parent: Nullable[ModelEntity] = None
692 ) -> None:
693 """
694 Initializes an array type definition.
696 :param identifier: The identifier of a model entity.
697 :param indices: List of all index ranges, one per dimension.
698 :param elementSubtype: Reference to the subtype of the array's elements.
699 :param documentation: The documentation comment associated with this declaration.
700 :param parent: The parent model entity of this entity.
701 """
702 super().__init__(identifier, documentation, parent)
704 self._dimensions = dimensions = []
705 for index in indices:
706 dimensions.append(index)
707 # index.Parent = self # FIXME: indices are provided as empty list
709 self._elementType = elementSubtype
710 # elementSubtype.Parent = self # FIXME: subtype is provided as None
712 @readonly
713 def Dimensions(self) -> list[Range]:
714 """
715 Read-only property to access the dimensions (:attr:`_dimensions`).
717 :returns: List of dimensions.
718 """
719 return self._dimensions
721 @readonly
722 def ElementType(self) -> Symbol:
723 """
724 Read-only property to access the element type (:attr:`_elementType`).
726 :returns: The element type.
727 """
728 return self._elementType
730 def Visit(self, visitor: Visitor) -> None:
731 """
732 Walk this array type, its index ranges and its element subtype with a visitor.
734 :param visitor: The visitor receiving the events.
735 """
736 visitor.VisitArrayType(self)
737 visitor.VisitIndexConstraint(self)
738 for index, dimension in enumerate(self._dimensions):
739 if index > 0:
740 visitor.VisitComma(self)
742 dimension.Visit(visitor)
743 if isinstance(dimension, SimpleSubtypeSymbol):
744 visitor.VisitBox(self)
746 visitor.DepartIndexConstraint(self)
747 visitor.VisitOf(self)
748 self._elementType.Visit(visitor)
749 visitor.DepartArrayType(self)
751 def __str__(self) -> str:
752 """
753 Formats the array type definition.
755 **Format:** ``memory is array(0 to 7) of bit``
757 :returns: Formatted array type definition.
758 """
759 return f"{self._identifier} is array({'; '.join(str(r) for r in self._dimensions)}) of {self._elementType}"
762@export
763class RecordTypeElement(ModelEntity, MultipleNamedEntityMixin, DocumentedEntityMixin):
764 """
765 Represents one element declaration inside a record type definition.
767 A single declaration may name several elements at once, hence :data:`Identifiers` rather than one
768 identifier. All of them share the same subtype (:data:`Subtype`).
770 .. admonition:: Example
772 .. code-block:: VHDL
774 type frame is record
775 --! The first fields.
776 --^^^^^^^^^^^^^^^^^^^^^ <- Documentation
777 a, b : bit;
778 --^^^^ <- Identifiers
779 -- ^^^ <- Subtype
780 end record;
782 .. seealso::
784 * :class:`Record type <pyVHDLModel.Type.RecordType>`
785 """
786 _subtype: Symbol #: Reference to the subtype shared by all identifiers of this element declaration.
788 def __init__(
789 self,
790 identifiers: Iterable[str],
791 subtype: Symbol,
792 documentation: Nullable[str] = None,
793 parent: Nullable[ModelEntity] = None
794 ) -> None:
795 """
796 Initializes a record type element.
798 :param identifiers: A list of identifiers.
799 :param subtype: Reference to the subtype shared by all identifiers of this element declaration.
800 :param documentation: The documentation comment associated with this declaration.
801 :param parent: The parent model entity of this entity.
802 """
803 super().__init__(parent)
804 MultipleNamedEntityMixin.__init__(self, identifiers)
805 DocumentedEntityMixin.__init__(self, documentation)
807 self._subtype = subtype
808 subtype.Parent = self
810 @readonly
811 def Subtype(self) -> Symbol:
812 """
813 Read-only property to access the subtype (:attr:`_subtype`).
815 :returns: The subtype.
816 """
817 return self._subtype
819 def Copy(self) -> Self:
820 """
821 Create a copy of this record type element.
823 The copy has no parent. Its subtype is a copy of this element's subtype.
825 :returns: The new record type element.
826 """
827 return self.__class__(self._identifiers, self._subtype.Copy(), self._documentation)
829 def Visit(self, visitor: Visitor) -> None:
830 """
831 Walk this record element declaration and its subtype with a visitor.
833 :param visitor: The visitor receiving the events.
834 """
835 visitor.VisitRecordTypeElement(self)
836 self._subtype.Visit(visitor)
837 visitor.DepartRecordTypeElement(self)
839 def __str__(self) -> str:
840 """
841 Formats the record element declaration.
843 **Format:** ``a, b : bit``
845 :returns: Formatted record element declaration.
846 """
847 return f"{', '.join(self._identifiers)} : {self._subtype}"
850@export
851class RecordType(CompositeType):
852 """
853 Represents a record type definition.
855 A record type is a named entity (:data:`Identifier`) holding its element declarations
856 (:data:`Elements`) in declaration order. The model holds them in a list and has no distinct
857 field per element, so the markers below name list elements.
859 .. admonition:: Example
861 .. code-block:: VHDL
863 type frame is record
864 -- ^^^^^ <- Identifier
865 a, b : bit;
866 --^^^^^^^^^^^^^^ <- Elements[0]
867 payload : bit_vector(31 downto 0);
868 --^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ <- Elements[1]
869 end record;
871 .. seealso::
873 * :class:`Record element <pyVHDLModel.Type.RecordTypeElement>`
874 * :class:`Reference to a record element <pyVHDLModel.Symbol.RecordElementSymbol>`
875 """
876 _elements: list[RecordTypeElement] #: List of all element declarations, in declaration order.
878 def __init__(self, identifier: str, elements: Nullable[Iterable[RecordTypeElement]] = None, documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None:
879 """
880 Initializes a record type definition.
882 :param identifier: The identifier of a model entity.
883 :param elements: List of all element declarations, in declaration order.
884 :param documentation: The documentation comment associated with this declaration.
885 :param parent: The parent model entity of this entity.
886 """
887 super().__init__(identifier, documentation, parent)
889 self._elements = elementList = [] # TODO: convert to dict
890 if elements is not None:
891 for element in elements:
892 elementList.append(element)
893 element.Parent = self
895 @readonly
896 def Elements(self) -> list[RecordTypeElement]:
897 """
898 Read-only property to access the elements (:attr:`_elements`).
900 :returns: List of elements.
901 """
902 return self._elements
904 def Visit(self, visitor: Visitor) -> None:
905 """
906 Walk this record type and its element declarations with a visitor.
908 :param visitor: The visitor receiving the events.
909 """
910 visitor.VisitRecordType(self)
911 for element in self._elements:
912 element.Visit(visitor)
914 visitor.DepartRecordType(self)
916 def __str__(self) -> str:
917 """
918 Formats the record type definition.
920 **Format:** ``frame is record a : bit;``
922 :returns: Formatted record type definition.
923 """
924 return f"{self._identifier} is record {'; '.join(str(re) for re in self._elements)};"
927@export
928class ProtectedType(FullType, ProtectedTypeDeclarationRegionMixin, WithoutStatementsMixin):
929 """
930 Represents a protected type declaration.
932 A protected type is a named entity (:data:`Identifier`) exposing only its methods
933 (:data:`Methods`). The implementation lives in a separate :class:`ProtectedTypeBody`.
935 It is a declarative region and owns a namespace. VHDL's ``protected_type_declarative_item`` admits
936 subprogram declarations and nothing else - the narrowest declarative region in the language - so
937 :data:`DeclaredItems` and :data:`Methods` hold the same items. The markers below name list elements,
938 because the model has no distinct field per method.
940 .. admonition:: Example
942 .. code-block:: VHDL
944 type counter is protected
945 -- ^^^^^^^ <- Identifier
946 procedure increment;
947 --^^^^^^^^^^^^^^^^^^^^ <- Methods[0]
948 impure function value return natural;
949 --^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ <- Methods[1]
950 end protected;
952 .. seealso::
954 * :class:`Protected type body <pyVHDLModel.Type.ProtectedTypeBody>`
955 * :class:`Method of a protected type <pyVHDLModel.Subprogram.ProcedureMethod>`
956 """
957 def __init__(self, identifier: str, declaredItems: Union[list, Iterator] = None, documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None:
958 """
959 Initializes a protected type declaration.
961 :param identifier: The identifier of a model entity.
962 :param declaredItems: All items declared by this protected type; only subprograms are legal.
963 :param documentation: The documentation comment associated with this declaration.
964 :param parent: The parent model entity of this entity.
965 """
966 super().__init__(identifier, documentation, parent)
967 ProtectedTypeDeclarationRegionMixin.__init__(self, self._normalizedIdentifier, declaredItems)
969 def Visit(self, visitor: Visitor) -> None:
970 """
971 Walk this protected type declaration and its methods with a visitor.
973 :param visitor: The visitor receiving the events.
974 """
975 visitor.VisitProtectedType(self)
976 self._VisitDeclaredItems(visitor)
977 visitor.DepartProtectedType(self)
979 @readonly
980 def Methods(self) -> list[Union[Procedure, Function]]:
981 """
982 Read-only property to access the declared methods, in declaration order.
984 A protected type declares nothing but subprograms, so this is every declared item
985 (:attr:`_declaredItems`). It is kept as a named view because "method" is the VHDL term for a
986 protected type's subprograms.
988 :returns: List of methods, in declaration order.
989 """
990 from pyVHDLModel.Subprogram import Function, Procedure
992 return [item for item in self._declaredItems if isinstance(item, (Function, Procedure))]
995@export
996class ProtectedTypeBody(FullType, SequentialDeclarationRegionMixin, WithoutStatementsMixin):
997 """
998 Represents a protected type body.
1000 A protected type body implements the methods (:data:`Methods`) declared by the
1001 :class:`ProtectedType` of the same identifier (:data:`Identifier`).
1003 It is a declarative region and owns a namespace. Its declarative part matches a subprogram's, so it
1004 shares :class:`~pyVHDLModel.Regions.SequentialDeclarationRegionMixin` with subprogram bodies.
1005 Everything declared is available as :data:`DeclaredItems`; :data:`Methods` is its subprogram subset.
1007 .. admonition:: Example
1009 .. code-block:: VHDL
1011 type counter is protected body
1012 -- ^^^^^^^ <- Identifier
1013 variable count : natural := 0;
1014 procedure increment is
1015 --^^^^^^^^^^^^^^^^^^^^^^ <- Methods[0]
1016 begin
1017 count := count + 1;
1018 end procedure;
1019 end protected body;
1021 .. seealso::
1023 * :class:`Protected type declaration <pyVHDLModel.Type.ProtectedType>`
1024 """
1025 def __init__(self, identifier: str, declaredItems: Union[list, Iterator] = None, documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None:
1026 """
1027 Initializes a protected type body.
1029 :param identifier: The identifier of a model entity.
1030 :param declaredItems: Iterable of all items declared in this body.
1031 :param documentation: The documentation comment associated with this declaration.
1032 :param parent: The parent model entity of this entity.
1033 """
1034 super().__init__(identifier, documentation, parent)
1035 SequentialDeclarationRegionMixin.__init__(self, self._normalizedIdentifier, declaredItems)
1037 def Visit(self, visitor: Visitor) -> None:
1038 """
1039 Walk this protected type body and its declared items with a visitor.
1041 :param visitor: The visitor receiving the events.
1042 """
1043 visitor.VisitProtectedTypeBody(self)
1044 self._VisitDeclaredItems(visitor)
1045 visitor.DepartProtectedTypeBody(self)
1047 # FIXME: needs to be declared items or so
1048 @readonly
1049 def Methods(self) -> list[Union[Procedure, Function]]:
1050 """
1051 Read-only property to access the implemented methods, in declaration order.
1053 A protected type body may also declare variables, types, subtypes, aliases and files, so this is
1054 the subprogram subset of :attr:`_declaredItems` rather than all of them.
1056 :returns: List of methods, in declaration order.
1057 """
1058 from pyVHDLModel.Subprogram import Function, Procedure
1060 return [item for item in self._declaredItems if isinstance(item, (Function, Procedure))]
1063@export
1064class AccessType(FullType):
1065 """
1066 Represents an access type definition.
1068 An access type is a named entity (:data:`Identifier`) pointing at values of its designated subtype
1069 (:data:`DesignatedSubtype`).
1071 .. admonition:: Example
1073 .. code-block:: VHDL
1075 type ptr is access integer;
1076 -- ^^^ <- Identifier
1077 -- ^^^^^^^ <- DesignatedSubtype
1078 """
1079 _designatedSubtype: Symbol #: Reference to the subtype the access values designate.
1081 def __init__(self, identifier: str, designatedSubtype: Symbol, documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None:
1082 """
1083 Initializes an access type definition.
1085 :param identifier: The identifier of a model entity.
1086 :param designatedSubtype: Reference to the subtype the access values designate.
1087 :param documentation: The documentation comment associated with this declaration.
1088 :param parent: The parent model entity of this entity.
1089 """
1090 super().__init__(identifier, documentation, parent)
1092 self._designatedSubtype = designatedSubtype
1093 designatedSubtype.Parent = self
1095 @readonly
1096 def DesignatedSubtype(self) -> Symbol:
1097 """
1098 Read-only property to access the designated subtype (:attr:`_designatedSubtype`).
1100 :returns: The designated subtype.
1101 """
1102 return self._designatedSubtype
1104 def Visit(self, visitor: Visitor) -> None:
1105 """
1106 Walk this access type and its designated subtype with a visitor.
1108 :param visitor: The visitor receiving the events.
1109 """
1110 visitor.VisitAccessType(self)
1111 self._designatedSubtype.Visit(visitor)
1112 visitor.DepartAccessType(self)
1114 def __str__(self) -> str:
1115 """
1116 Formats the access type definition.
1118 **Format:** ``ptr is access node``
1120 :returns: Formatted access type definition.
1121 """
1122 return f"{self._identifier} is access {self._designatedSubtype}"
1125@export
1126class FileType(FullType):
1127 """
1128 Represents a file type definition.
1130 A file type is a named entity (:data:`Identifier`) holding values of its designated subtype
1131 (:data:`DesignatedSubtype`).
1133 .. admonition:: Example
1135 .. code-block:: VHDL
1137 type text_file is file of string;
1138 -- ^^^^^^^^^ <- Identifier
1139 -- ^^^^^^ <- DesignatedSubtype
1140 """
1141 _designatedSubtype: Symbol #: Reference to the subtype of the values stored in the file.
1143 def __init__(self, identifier: str, designatedSubtype: Symbol, documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None:
1144 """
1145 Initializes a file type definition.
1147 :param identifier: The identifier of a model entity.
1148 :param designatedSubtype: Reference to the subtype of the values stored in the file.
1149 :param documentation: The documentation comment associated with this declaration.
1150 :param parent: The parent model entity of this entity.
1151 """
1152 super().__init__(identifier, documentation, parent)
1154 self._designatedSubtype = designatedSubtype
1155 designatedSubtype.Parent = self
1157 @readonly
1158 def DesignatedSubtype(self) -> Symbol:
1159 """
1160 Read-only property to access the designated subtype (:attr:`_designatedSubtype`).
1162 :returns: The designated subtype.
1163 """
1164 return self._designatedSubtype
1166 def Visit(self, visitor: Visitor) -> None:
1167 """
1168 Walk this file type and its designated subtype with a visitor.
1170 :param visitor: The visitor receiving the events.
1171 """
1172 visitor.VisitFileType(self)
1173 self._designatedSubtype.Visit(visitor)
1174 visitor.DepartFileType(self)
1176 def __str__(self) -> str:
1177 """
1178 Formats the file type definition.
1180 **Format:** ``ft is file of character``
1182 :returns: Formatted file type definition.
1183 """
1184 return f"{self._identifier} is file of {self._designatedSubtype}"