Coverage for pyVHDLModel/Type.py: 99%
194 statements
« prev ^ index » next coverage.py v7.16.0, created at 2026-09-11 23:50 +0000
« prev ^ index » next coverage.py v7.16.0, created at 2026-09-11 23:50 +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 typing import Union, List, Iterator, Iterable, Tuple, Optional as Nullable, Dict, Mapping
39from pyTooling.Decorators import export, readonly
40from pyTooling.MetaClasses import ExtendedType
41from pyTooling.Graph import Vertex
43from pyVHDLModel.Base import ModelEntity, NamedEntityMixin, MultipleNamedEntityMixin, DocumentedEntityMixin, ExpressionUnion, Range
44from pyVHDLModel.Symbol import Symbol
45from pyVHDLModel.Expression import EnumerationLiteral, PhysicalIntegerLiteral
46from pyVHDLModel.Regions import ProtectedTypeDeclarationRegionMixin, SequentialDeclarationRegionMixin
49@export
50class BaseType(ModelEntity, NamedEntityMixin, DocumentedEntityMixin):
51 """
52 Represents the base-class of all type entities: full types, subtypes and anonymous types.
54 Every type is a named entity (:data:`Identifier`, :data:`NormalizedIdentifier`) and can carry
55 documentation (:data:`Documentation`).
57 .. seealso::
59 * :class:`Type <pyVHDLModel.Type.Type>`
60 * :class:`Full type <pyVHDLModel.Type.FullType>`
61 * :class:`Subtype <pyVHDLModel.Type.Subtype>`
62 """
64 _objectVertex: Vertex #: The vertex representing this type in the design's object graph.
66 def __init__(self, identifier: str, documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None:
67 """
68 Initializes underlying ``BaseType``.
70 :param identifier: Name of the type.
71 :param documentation: The documentation comment associated with this declaration.
72 :param parent: Reference to the logical parent in the model hierarchy.
73 """
74 super().__init__(parent)
75 NamedEntityMixin.__init__(self, identifier)
76 DocumentedEntityMixin.__init__(self, documentation)
78 self._objectVertex = None
80 def __str__(self) -> str:
81 """
82 Formats the type declaration.
84 **Format:** ``type myType``
86 :returns: Formatted type declaration.
87 """
88 return f"type {self._identifier}"
91@export
92class Type(BaseType):
93 """
94 Represents a base-class for types introduced by a type declaration.
96 Besides real type declarations, this is also the base-class of a generic type interface item, which
97 introduces a type name without defining the type itself.
99 .. seealso::
101 * :class:`Generic type interface item <pyVHDLModel.Interface.GenericTypeInterfaceItem>`
102 * :class:`Anonymous type <pyVHDLModel.Type.AnonymousType>`
103 """
104 pass
107@export
108class AnonymousType(Type):
109 """
110 Represents a base-class for types without a type definition of their own.
112 An incomplete type is the typical case: it names a type (:data:`Identifier`) whose full
113 definition follows later in the same declarative part.
115 .. admonition:: Example
117 .. code-block:: VHDL
119 type node;
120 -- ^^^^ <- Identifier
121 type ptr is access node;
122 type node is record
123 value : integer;
124 nextNode : ptr;
125 end record;
126 """
127 pass
130@export
131class FullType(BaseType):
132 """
133 Represents a base-class for all full type definitions, as opposed to a :class:`Subtype`.
135 This is the distinction the declaration regions index on: a full type is registered in ``Types``, a
136 subtype in ``Subtypes``.
138 .. seealso::
140 * :class:`Scalar type <pyVHDLModel.Type.ScalarType>`
141 * :class:`Composite type <pyVHDLModel.Type.CompositeType>`
142 * :class:`Protected type <pyVHDLModel.Type.ProtectedType>`
143 * :class:`Protected type body <pyVHDLModel.Type.ProtectedTypeBody>`
144 * :class:`Access type <pyVHDLModel.Type.AccessType>`
145 * :class:`File type <pyVHDLModel.Type.FileType>`
146 """
147 pass
150@export
151class Subtype(BaseType):
152 """
153 Represents a subtype declaration.
155 A subtype is a named entity (:data:`Identifier`, :data:`NormalizedIdentifier`) referencing a type
156 (:data:`Type`). Optionally, the subtype can be narrowed by a constraint (:data:`Range`) and/or
157 resolved by a resolution function (:data:`ResolutionFunction`).
159 .. admonition:: Example
161 Without a constraint:
163 .. code-block:: VHDL
165 subtype byte is bit_vector;
166 -- ^^^^ <- Identifier
167 -- ^^^^^^^^^^ <- Type
169 With a constraint:
171 .. code-block:: VHDL
173 subtype nibble is bit_vector(3 downto 0);
174 -- ^^^^^^^^^^^^ <- Range
176 With a resolution function:
178 .. code-block:: VHDL
180 subtype wired is resolved std_ulogic;
181 -- ^^^^^^^^ <- ResolutionFunction
183 .. seealso::
185 * :class:`Reference to a type or subtype <pyVHDLModel.Symbol.SubtypeSymbol>`
186 """
187 _type: Symbol #: Reference to the type or subtype this subtype is derived from.
188 _baseType: BaseType #: The resolved base type of this subtype.
189 _range: Range #: The constraint narrowing the base type, or ``None`` if unconstrained.
190 _resolutionFunction: 'Function' #: The resolution function, or ``None`` if the subtype is unresolved.
192 def __init__(self, identifier: str, symbol: Symbol, documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None:
193 """
194 Initializes a subtype declaration.
196 :param identifier: The identifier of a model entity.
197 :param symbol: Reference to the type or subtype this subtype is derived from.
198 :param documentation: The documentation comment associated with this declaration.
199 :param parent: The parent model entity of this entity.
200 """
201 super().__init__(identifier, documentation, parent)
203 self._type = symbol
204 self._baseType = None
205 self._range = None
206 self._resolutionFunction = None
208 @readonly
209 def Type(self) -> Symbol:
210 """
211 Read-only property to access the type (:attr:`_type`).
213 :returns: The type.
214 """
215 return self._type
217 @readonly
218 def BaseType(self) -> BaseType:
219 """
220 Read-only property to access the base type (:attr:`_baseType`).
222 :returns: The base type.
223 """
224 return self._baseType
226 @readonly
227 def Range(self) -> Range:
228 """
229 Read-only property to access the range (:attr:`_range`).
231 :returns: The range.
232 """
233 return self._range
235 @readonly
236 def ResolutionFunction(self) -> 'Function':
237 """
238 Read-only property to access the resolution function (:attr:`_resolutionFunction`).
240 :returns: The resolution function.
241 """
242 return self._resolutionFunction
244 def __str__(self) -> str:
245 """
246 Formats the subtype declaration.
248 **Format:** ``subtype byte is bit_vector``
250 The *base type* is rendered, so an unlinked subtype shows ``None``.
252 :returns: Formatted subtype declaration.
253 """
254 return f"subtype {self._identifier} is {self._baseType}"
257@export
258class ScalarType(FullType):
259 """
260 Represents a base-class for all scalar types: enumerated, integer, real and physical types.
262 .. seealso::
264 * :class:`Ranged scalar type <pyVHDLModel.Type.RangedScalarType>`
265 * :class:`Enumerated type <pyVHDLModel.Type.EnumeratedType>`
266 """
269@export
270class RangedScalarType(ScalarType):
271 """
272 Represents a base-class for all scalar types constrained by a range (:data:`Range`).
274 Integer, real and physical types are ranged. An enumerated type is scalar but not ranged, so it
275 derives from :class:`ScalarType` directly.
277 .. seealso::
279 * :class:`Integer type <pyVHDLModel.Type.IntegerType>`
280 * :class:`Real type <pyVHDLModel.Type.RealType>`
281 * :class:`Physical type <pyVHDLModel.Type.PhysicalType>`
282 """
284 _range: Range #: The range constraining this scalar type.
286 def __init__(self, identifier: str, rng: Range, documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None:
287 """
288 Initialize a scalar type with a range.
290 :param identifier: The type's identifier.
291 :param rng: The type's range.
292 :param documentation: The type's documentation.
293 :param parent: The parent model entity.
294 """
295 super().__init__(identifier, documentation, parent)
296 self._range = rng
298 @readonly
299 def Range(self) -> Range:
300 """
301 Read-only property to access the type's range (:attr:`_range`).
303 :returns: The range.
304 """
305 return self._range
308@export
309class NumericTypeMixin(metaclass=ExtendedType, mixin=True):
310 """
311 A mixin-class for all numeric types: integer, real and physical types.
313 .. seealso::
315 * :class:`Integer type <pyVHDLModel.Type.IntegerType>`
316 * :class:`Real type <pyVHDLModel.Type.RealType>`
317 * :class:`Physical type <pyVHDLModel.Type.PhysicalType>`
318 """
320 def __init__(self) -> None:
321 """
322 Initializes a numeric type.
323 """
324 pass
327@export
328class DiscreteTypeMixin(metaclass=ExtendedType, mixin=True):
329 """
330 A mixin-class for all discrete types: enumerated and integer types.
332 .. seealso::
334 * :class:`Enumerated type <pyVHDLModel.Type.EnumeratedType>`
335 * :class:`Integer type <pyVHDLModel.Type.IntegerType>`
336 """
338 def __init__(self) -> None:
339 """
340 Initializes a discrete type.
341 """
342 pass
345@export
346class EnumeratedType(ScalarType, DiscreteTypeMixin):
347 """
348 Represents an enumerated type definition.
350 An enumerated type is a named entity (:data:`Identifier`) listing its enumeration literals
351 (:data:`Literals`) in declaration order.
353 .. admonition:: Example
355 .. code-block:: VHDL
357 type state is (Idle, Running, Done);
358 -- ^^^^^ <- Identifier
359 -- ^^^^^^^^^^^^^^^^^^^ <- Literals
360 """
361 _literals: List[EnumerationLiteral] #: List of all enumeration literals, in declaration order.
363 def __init__(self, identifier: str, literals: Iterable[EnumerationLiteral], documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None:
364 """
365 Initializes an enumerated type definition.
367 :param identifier: The identifier of a model entity.
368 :param literals: List of all enumeration literals, in declaration order.
369 :param documentation: The documentation comment associated with this declaration.
370 :param parent: The parent model entity of this entity.
371 """
372 super().__init__(identifier, documentation, parent)
374 self._literals = []
375 if literals is not None:
376 for literal in literals:
377 self._literals.append(literal)
378 literal.Parent = self
380 @readonly
381 def Literals(self) -> List[EnumerationLiteral]:
382 """
383 Read-only property to access the literals (:attr:`_literals`).
385 :returns: List of literals.
386 """
387 return self._literals
389 def __str__(self) -> str:
390 """
391 Formats the enumerated type definition.
393 **Format:** ``state is (idle, run)``
395 :returns: Formatted enumerated type definition.
396 """
397 return f"{self._identifier} is ({', '.join(str(l) for l in self._literals)})"
400@export
401class IntegerType(RangedScalarType, NumericTypeMixin, DiscreteTypeMixin):
402 """
403 Represents an integer type definition.
405 An integer type is a named entity (:data:`Identifier`) constrained by a range (:data:`Range`).
407 .. admonition:: Example
409 .. code-block:: VHDL
411 type nibble is range 0 to 15;
412 -- ^^^^^^ <- Identifier
413 -- ^^^^^^^ <- Range
414 """
415 def __init__(self, identifier: str, rng: Range, documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None:
416 """
417 Initializes an integer type definition.
419 :param identifier: The identifier of a model entity.
420 :param rng: The range constraining this scalar type.
421 :param documentation: The documentation comment associated with this declaration.
422 :param parent: The parent model entity of this entity.
423 """
424 super().__init__(identifier, rng, documentation, parent)
426 def __str__(self) -> str:
427 """
428 Formats the integer type definition.
430 **Format:** ``byte_count is range 0 to 7``
432 :returns: Formatted integer type definition.
433 """
434 return f"{self._identifier} is range {self._range}"
437@export
438class RealType(RangedScalarType, NumericTypeMixin):
439 """
440 Represents a floating-point type definition.
442 A floating-point type is a named entity (:data:`Identifier`) constrained by a range
443 (:data:`Range`).
445 .. admonition:: Example
447 .. code-block:: VHDL
449 type fraction is range 0.0 to 1.0;
450 -- ^^^^^^^^ <- Identifier
451 -- ^^^^^^^^^^ <- Range
452 """
453 def __init__(self, identifier: str, rng: Range, documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None:
454 """
455 Initializes a floating-point type definition.
457 :param identifier: The identifier of a model entity.
458 :param rng: The range constraining this scalar type.
459 :param documentation: The documentation comment associated with this declaration.
460 :param parent: The parent model entity of this entity.
461 """
462 super().__init__(identifier, rng, documentation, parent)
464 def __str__(self) -> str:
465 """
466 Formats the floating-point type definition.
468 **Format:** ``gain is range 0.0 to 1.0``
470 :returns: Formatted floating-point type definition.
471 """
472 return f"{self._identifier} is range {self._range}"
475@export
476class PhysicalType(RangedScalarType, NumericTypeMixin):
477 """
478 Represents a physical type definition.
480 A physical type is a named entity (:data:`Identifier`) constrained by a range (:data:`Range`), and
481 defines a primary unit (:data:`PrimaryUnit`) plus any number of secondary units
482 (:data:`SecondaryUnits`). The model holds the secondary units in a list and has no distinct field
483 per unit, so the markers below name list elements.
485 .. admonition:: Example
487 .. code-block:: VHDL
489 type distance is range 0 to 1000000 units
490 -- ^^^^^^^^ <- Identifier
491 -- ^^^^^^^^^^^^ <- Range
492 um;
493 --^^^ <- PrimaryUnit
494 mm = 1000 um;
495 --^^^^^^^^^^^^^ <- SecondaryUnits[0]
496 m = 1000 mm;
497 --^^^^^^^^^^^^^ <- SecondaryUnits[1]
498 end units;
499 """
500 _primaryUnit: str #: The name of the type's primary unit.
501 _secondaryUnits: List[Tuple[str, PhysicalIntegerLiteral]] #: Secondary units as (name, value) pairs.
503 def __init__(
504 self,
505 identifier: str,
506 rng: Range,
507 primaryUnit: str,
508 units: Iterable[Tuple[str, PhysicalIntegerLiteral]],
509 documentation: Nullable[str] = None,
510 parent: Nullable[ModelEntity] = None
511 ) -> None:
512 """
513 Initializes a physical type definition.
515 :param identifier: The identifier of a model entity.
516 :param rng: The range constraining this scalar type.
517 :param primaryUnit: The name of the type's primary unit.
518 :param units: Iterable of the secondary units as (name, value) pairs.
519 :param documentation: The documentation comment associated with this declaration.
520 :param parent: The parent model entity of this entity.
521 """
522 super().__init__(identifier, rng, documentation, parent)
524 self._primaryUnit = primaryUnit
526 self._secondaryUnits = [] # TODO: convert to dict
527 for unit in units:
528 self._secondaryUnits.append(unit)
529 unit[1].Parent = self
531 @readonly
532 def PrimaryUnit(self) -> str:
533 """
534 Read-only property to access the primary unit (:attr:`_primaryUnit`).
536 :returns: The primary unit.
537 """
538 return self._primaryUnit
540 @readonly
541 def SecondaryUnits(self) -> List[Tuple[str, PhysicalIntegerLiteral]]:
542 """
543 Read-only property to access the secondary units (:attr:`_secondaryUnits`).
545 :returns: List of secondary units.
546 """
547 return self._secondaryUnits
549 def __str__(self) -> str:
550 """
551 Formats the physical type definition.
553 **Format:** ``distance is range 0 to 1000 units um; mm = 1000 um;``
555 :returns: Formatted physical type definition.
556 """
557 return f"{self._identifier} is range {self._range} units {self._primaryUnit}; {'; '.join(su + ' = ' + str(pu) for su, pu in self._secondaryUnits)};"
560@export
561class CompositeType(FullType):
562 """
563 Represents a base-class for all composite types: array and record types.
565 .. seealso::
567 * :class:`Array type <pyVHDLModel.Type.ArrayType>`
568 * :class:`Record type <pyVHDLModel.Type.RecordType>`
569 """
572@export
573class ArrayType(CompositeType):
574 """
575 Represents an array type definition.
577 An array type is a named entity (:data:`Identifier`) defining one or more index ranges
578 (:data:`Dimensions`) and the subtype of its elements (:data:`ElementType`).
580 .. admonition:: Example
582 One dimension:
584 .. code-block:: VHDL
586 type memory is array (0 to 255) of bit_vector(7 downto 0);
587 -- ^^^^^^ <- Identifier
588 -- ^^^^^^^^ <- Dimensions
589 -- ^^^^^^^^^^^^^^^^^^^^^^ <- ElementType
591 Two dimensions, both unconstrained:
593 .. code-block:: VHDL
595 type matrix is array (natural range <>, natural range <>) of bit;
596 -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ <- Dimensions
598 .. seealso::
600 * :class:`Reference to a constrained array subtype <pyVHDLModel.Symbol.ConstrainedArraySubtypeSymbol>`
601 """
602 _dimensions: List[Range] #: List of all index ranges, one per dimension.
603 _elementType: Symbol #: Reference to the subtype of the array's elements.
605 def __init__(
606 self,
607 identifier: str,
608 indices: Iterable,
609 elementSubtype: Symbol,
610 documentation: Nullable[str] = None,
611 parent: Nullable[ModelEntity] = None
612 ) -> None:
613 """
614 Initializes an array type definition.
616 :param identifier: The identifier of a model entity.
617 :param indices: List of all index ranges, one per dimension.
618 :param elementSubtype: Reference to the subtype of the array's elements.
619 :param documentation: The documentation comment associated with this declaration.
620 :param parent: The parent model entity of this entity.
621 """
622 super().__init__(identifier, documentation, parent)
624 self._dimensions = []
625 for index in indices:
626 self._dimensions.append(index)
627 # index.Parent = self # FIXME: indices are provided as empty list
629 self._elementType = elementSubtype
630 # elementSubtype.Parent = self # FIXME: subtype is provided as None
632 @readonly
633 def Dimensions(self) -> List[Range]:
634 """
635 Read-only property to access the dimensions (:attr:`_dimensions`).
637 :returns: List of dimensions.
638 """
639 return self._dimensions
641 @readonly
642 def ElementType(self) -> Symbol:
643 """
644 Read-only property to access the element type (:attr:`_elementType`).
646 :returns: The element type.
647 """
648 return self._elementType
650 def __str__(self) -> str:
651 """
652 Formats the array type definition.
654 **Format:** ``memory is array(0 to 7) of bit``
656 :returns: Formatted array type definition.
657 """
658 return f"{self._identifier} is array({'; '.join(str(r) for r in self._dimensions)}) of {self._elementType}"
661@export
662class RecordTypeElement(ModelEntity, MultipleNamedEntityMixin, DocumentedEntityMixin):
663 """
664 Represents one element declaration inside a record type definition.
666 A single declaration may name several elements at once, hence :data:`Identifiers` rather than one
667 identifier. All of them share the same subtype (:data:`Subtype`).
669 .. admonition:: Example
671 .. code-block:: VHDL
673 type frame is record
674 --! The first fields.
675 --^^^^^^^^^^^^^^^^^^^^^ <- Documentation
676 a, b : bit;
677 --^^^^ <- Identifiers
678 -- ^^^ <- Subtype
679 end record;
681 .. seealso::
683 * :class:`Record type <pyVHDLModel.Type.RecordType>`
684 """
685 _subtype: Symbol #: Reference to the subtype shared by all identifiers of this element declaration.
687 def __init__(
688 self,
689 identifiers: Iterable[str],
690 subtype: Symbol,
691 documentation: Nullable[str] = None,
692 parent: Nullable[ModelEntity] = None
693 ) -> None:
694 """
695 Initializes a record type element.
697 :param identifiers: A list of identifiers.
698 :param subtype: Reference to the subtype shared by all identifiers of this element declaration.
699 :param documentation: The documentation comment associated with this declaration.
700 :param parent: The parent model entity of this entity.
701 """
702 super().__init__(parent)
703 MultipleNamedEntityMixin.__init__(self, identifiers)
704 DocumentedEntityMixin.__init__(self, documentation)
706 self._subtype = subtype
707 subtype.Parent = self
709 @readonly
710 def Subtype(self) -> Symbol:
711 """
712 Read-only property to access the subtype (:attr:`_subtype`).
714 :returns: The subtype.
715 """
716 return self._subtype
718 def __str__(self) -> str:
719 """
720 Formats the record element declaration.
722 **Format:** ``a, b : bit``
724 :returns: Formatted record element declaration.
725 """
726 return f"{', '.join(self._identifiers)} : {self._subtype}"
729@export
730class RecordType(CompositeType):
731 """
732 Represents a record type definition.
734 A record type is a named entity (:data:`Identifier`) holding its element declarations
735 (:data:`Elements`) in declaration order. The model holds them in a list and has no distinct
736 field per element, so the markers below name list elements.
738 .. admonition:: Example
740 .. code-block:: VHDL
742 type frame is record
743 -- ^^^^^ <- Identifier
744 a, b : bit;
745 --^^^^^^^^^^^^^^ <- Elements[0]
746 payload : bit_vector(31 downto 0);
747 --^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ <- Elements[1]
748 end record;
750 .. seealso::
752 * :class:`Record element <pyVHDLModel.Type.RecordTypeElement>`
753 * :class:`Reference to a record element <pyVHDLModel.Symbol.RecordElementSymbol>`
754 """
755 _elements: List[RecordTypeElement] #: List of all element declarations, in declaration order.
757 def __init__(self, identifier: str, elements: Nullable[Iterable[RecordTypeElement]] = None, documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None:
758 """
759 Initializes a record type definition.
761 :param identifier: The identifier of a model entity.
762 :param elements: List of all element declarations, in declaration order.
763 :param documentation: The documentation comment associated with this declaration.
764 :param parent: The parent model entity of this entity.
765 """
766 super().__init__(identifier, documentation, parent)
768 self._elements = [] # TODO: convert to dict
769 if elements is not None:
770 for element in elements:
771 self._elements.append(element)
772 element.Parent = self
774 @readonly
775 def Elements(self) -> List[RecordTypeElement]:
776 """
777 Read-only property to access the elements (:attr:`_elements`).
779 :returns: List of elements.
780 """
781 return self._elements
783 def __str__(self) -> str:
784 """
785 Formats the record type definition.
787 **Format:** ``frame is record a : bit;``
789 :returns: Formatted record type definition.
790 """
791 return f"{self._identifier} is record {'; '.join(str(re) for re in self._elements)};"
794@export
795class ProtectedType(FullType, ProtectedTypeDeclarationRegionMixin):
796 """
797 Represents a protected type declaration.
799 A protected type is a named entity (:data:`Identifier`) exposing only its methods
800 (:data:`Methods`). The implementation lives in a separate :class:`ProtectedTypeBody`.
802 It is a declarative region and owns a namespace. VHDL's ``protected_type_declarative_item`` admits
803 subprogram declarations and nothing else - the narrowest declarative region in the language - so
804 :data:`DeclaredItems` and :data:`Methods` hold the same items. The markers below name list elements,
805 because the model has no distinct field per method.
807 .. admonition:: Example
809 .. code-block:: VHDL
811 type counter is protected
812 -- ^^^^^^^ <- Identifier
813 procedure increment;
814 --^^^^^^^^^^^^^^^^^^^^ <- Methods[0]
815 impure function value return natural;
816 --^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ <- Methods[1]
817 end protected;
819 .. seealso::
821 * :class:`Protected type body <pyVHDLModel.Type.ProtectedTypeBody>`
822 * :class:`Method of a protected type <pyVHDLModel.Subprogram.ProcedureMethod>`
823 """
824 def __init__(self, identifier: str, declaredItems: Union[List, Iterator] = None, documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None:
825 """
826 Initializes a protected type declaration.
828 :param identifier: The identifier of a model entity.
829 :param declaredItems: All items declared by this protected type; only subprograms are legal.
830 :param documentation: The documentation comment associated with this declaration.
831 :param parent: The parent model entity of this entity.
832 """
833 super().__init__(identifier, documentation, parent)
834 ProtectedTypeDeclarationRegionMixin.__init__(self, self._normalizedIdentifier, declaredItems)
836 @readonly
837 def Methods(self) -> List[Union['Procedure', 'Function']]:
838 """
839 Read-only property to access the declared methods, in declaration order.
841 A protected type declares nothing but subprograms, so this is every declared item
842 (:attr:`_declaredItems`). It is kept as a named view because "method" is the VHDL term for a
843 protected type's subprograms.
845 :returns: List of methods, in declaration order.
846 """
847 from pyVHDLModel.Subprogram import Function, Procedure
849 return [item for item in self._declaredItems if isinstance(item, (Function, Procedure))]
852@export
853class ProtectedTypeBody(FullType, SequentialDeclarationRegionMixin):
854 """
855 Represents a protected type body.
857 A protected type body implements the methods (:data:`Methods`) declared by the
858 :class:`ProtectedType` of the same identifier (:data:`Identifier`).
860 It is a declarative region and owns a namespace. Its declarative part matches a subprogram's, so it
861 shares :class:`~pyVHDLModel.Regions.SequentialDeclarationRegionMixin` with subprogram bodies.
862 Everything declared is available as :data:`DeclaredItems`; :data:`Methods` is its subprogram subset.
864 .. admonition:: Example
866 .. code-block:: VHDL
868 type counter is protected body
869 -- ^^^^^^^ <- Identifier
870 variable count : natural := 0;
871 procedure increment is
872 --^^^^^^^^^^^^^^^^^^^^^^ <- Methods[0]
873 begin
874 count := count + 1;
875 end procedure;
876 end protected body;
878 .. seealso::
880 * :class:`Protected type declaration <pyVHDLModel.Type.ProtectedType>`
881 """
882 def __init__(self, identifier: str, declaredItems: Union[List, Iterator] = None, documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None:
883 """
884 Initializes a protected type body.
886 :param identifier: The identifier of a model entity.
887 :param declaredItems: Iterable of all items declared in this body.
888 :param documentation: The documentation comment associated with this declaration.
889 :param parent: The parent model entity of this entity.
890 """
891 super().__init__(identifier, documentation, parent)
892 SequentialDeclarationRegionMixin.__init__(self, self._normalizedIdentifier, declaredItems)
894 # FIXME: needs to be declared items or so
895 @readonly
896 def Methods(self) -> List[Union['Procedure', 'Function']]:
897 """
898 Read-only property to access the implemented methods, in declaration order.
900 A protected type body may also declare variables, types, subtypes, aliases and files, so this is
901 the subprogram subset of :attr:`_declaredItems` rather than all of them.
903 :returns: List of methods, in declaration order.
904 """
905 from pyVHDLModel.Subprogram import Function, Procedure
907 return [item for item in self._declaredItems if isinstance(item, (Function, Procedure))]
910@export
911class AccessType(FullType):
912 """
913 Represents an access type definition.
915 An access type is a named entity (:data:`Identifier`) pointing at values of its designated subtype
916 (:data:`DesignatedSubtype`).
918 .. admonition:: Example
920 .. code-block:: VHDL
922 type ptr is access integer;
923 -- ^^^ <- Identifier
924 -- ^^^^^^^ <- DesignatedSubtype
925 """
926 _designatedSubtype: Symbol #: Reference to the subtype the access values designate.
928 def __init__(self, identifier: str, designatedSubtype: Symbol, documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None:
929 """
930 Initializes an access type definition.
932 :param identifier: The identifier of a model entity.
933 :param designatedSubtype: Reference to the subtype the access values designate.
934 :param documentation: The documentation comment associated with this declaration.
935 :param parent: The parent model entity of this entity.
936 """
937 super().__init__(identifier, documentation, parent)
939 self._designatedSubtype = designatedSubtype
940 designatedSubtype.Parent = self
942 @readonly
943 def DesignatedSubtype(self) -> Symbol:
944 """
945 Read-only property to access the designated subtype (:attr:`_designatedSubtype`).
947 :returns: The designated subtype.
948 """
949 return self._designatedSubtype
951 def __str__(self) -> str:
952 """
953 Formats the access type definition.
955 **Format:** ``ptr is access node``
957 :returns: Formatted access type definition.
958 """
959 return f"{self._identifier} is access {self._designatedSubtype}"
962@export
963class FileType(FullType):
964 """
965 Represents a file type definition.
967 A file type is a named entity (:data:`Identifier`) holding values of its designated subtype
968 (:data:`DesignatedSubtype`).
970 .. admonition:: Example
972 .. code-block:: VHDL
974 type text_file is file of string;
975 -- ^^^^^^^^^ <- Identifier
976 -- ^^^^^^ <- DesignatedSubtype
977 """
978 _designatedSubtype: Symbol #: Reference to the subtype of the values stored in the file.
980 def __init__(self, identifier: str, designatedSubtype: Symbol, documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None:
981 """
982 Initializes a file type definition.
984 :param identifier: The identifier of a model entity.
985 :param designatedSubtype: Reference to the subtype of the values stored in the file.
986 :param documentation: The documentation comment associated with this declaration.
987 :param parent: The parent model entity of this entity.
988 """
989 super().__init__(identifier, documentation, parent)
991 self._designatedSubtype = designatedSubtype
992 designatedSubtype.Parent = self
994 @readonly
995 def DesignatedSubtype(self) -> Symbol:
996 """
997 Read-only property to access the designated subtype (:attr:`_designatedSubtype`).
999 :returns: The designated subtype.
1000 """
1001 return self._designatedSubtype
1003 def __str__(self) -> str:
1004 """
1005 Formats the file type definition.
1007 **Format:** ``ft is file of character``
1009 :returns: Formatted file type definition.
1010 """
1011 return f"{self._identifier} is file of {self._designatedSubtype}"