Coverage for pyVHDLModel/Object.py: 98%
122 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.
35Objects are constants, variables, signals and files.
36"""
37from __future__ import annotations
39from typing import TYPE_CHECKING, ClassVar, 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, MultipleNamedEntityMixin, DocumentedEntityMixin, ExpressionUnion, \
46 ReservedWord
47from pyVHDLModel.Symbol import Symbol
49if TYPE_CHECKING: 49 ↛ 50line 49 didn't jump to line 50 because the condition on line 49 was never true
50 from pyVHDLModel.Visitor import Visitor
53@export
54@abstractclass
55class Obj(ModelEntity, MultipleNamedEntityMixin, DocumentedEntityMixin):
56 """
57 Base-class for all objects (constants, signals, variables and files) in VHDL.
59 An object (syntax element) can define multiple objects (semantic elements) in a single declaration, thus
60 :class:`~pyVHDLModel.Base.MultipleNamedEntityMixin` is inherited. All objects can be documented, thus
61 :class:`~pyVHDLModel.Base.DocumentedEntityMixin` is inherited too.
63 Each object references a subtype via :data:`_subtype`.
65 Objects are elements in the type and object graph, thus a reference to a vertex in that graph is stored in
66 :data:`__objectVertex`.
68 .. seealso::
70 * :class:`Base constant <pyVHDLModel.Object.BaseConstant>`
71 * :class:`Variable <pyVHDLModel.Object.Variable>`
72 * :class:`Shared variable <pyVHDLModel.Object.SharedVariable>`
73 * :class:`Signal <pyVHDLModel.Object.Signal>`
74 * :class:`File <pyVHDLModel.Object.File>`
75 """
77 _OBJECT_KEYWORD: ClassVar[tuple[ReservedWord, ...]] #: The reserved words introducing this object class.
79 _subtype: Symbol #: Reference to the object's subtype.
80 _objectVertex: Nullable[Vertex] #: The vertex representing this object in the design's object graph.
82 def __init__(self, identifiers: Iterable[str], subtype: Symbol, documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None:
83 """
84 Initializes an object.
86 :param identifiers: A list of identifiers.
87 :param subtype: Reference to the object's subtype.
88 :param documentation: The documentation comment associated with this declaration.
89 :param parent: The parent model entity of this entity.
90 """
91 super().__init__(parent)
92 MultipleNamedEntityMixin.__init__(self, identifiers)
93 DocumentedEntityMixin.__init__(self, documentation)
95 self._subtype = subtype
96 subtype.Parent = self
98 self._objectVertex = None
100 @readonly
101 def Subtype(self) -> Symbol:
102 """
103 Read-only property to access the subtype (:attr:`_subtype`).
105 :returns: The subtype.
106 """
107 return self._subtype
109 @readonly
110 def ObjectVertex(self) -> Nullable[Vertex]:
111 """
112 Read-only property to access the corresponding object vertex (:attr:`_objectVertex`).
114 The object vertex references this Object by its value field.
116 :returns: The corresponding object vertex.
117 """
118 return self._objectVertex
120 def Copy(self) -> Self:
121 """
122 Create a copy of this object declaration.
124 The copy has no parent and no object vertex. Its subtype is a copy of this declaration's subtype.
126 :returns: The new object declaration.
127 """
128 return self.__class__(self._identifiers, self._subtype.Copy(), self._documentation)
130 def __str__(self) -> str:
131 """
132 Formats the object declaration.
134 **Format:** ``signal s1, s2 : bit``
136 :returns: Formatted object declaration.
137 """
138 return f"{' '.join(self._OBJECT_KEYWORD)} {', '.join(self._identifiers)} : {self._subtype}"
141@export
142class WithDefaultExpressionMixin(metaclass=ExtendedType, mixin=True):
143 """
144 A ``WithDefaultExpression`` is a mixin-class for all objects declarations accepting default expressions.
146 The default expression is referenced by :data:`__defaultExpression`. If no default expression is present, this field
147 is ``None``.
149 .. seealso::
151 * :class:`Constant <pyVHDLModel.Object.Constant>`
152 * :class:`Variable <pyVHDLModel.Object.Variable>`
153 * :class:`Signal <pyVHDLModel.Object.Signal>`
154 """
156 _defaultExpression: Nullable[ExpressionUnion] #: The default value, or ``None`` if none was given.
158 def __init__(self, defaultExpression: Nullable[ExpressionUnion] = None) -> None:
159 """
160 Initializes an object with a default expression.
162 :param defaultExpression: The default value, or ``None`` if none was given.
163 """
164 self._defaultExpression = defaultExpression
165 if defaultExpression is not None:
166 defaultExpression.Parent = self
168 @readonly
169 def DefaultExpression(self) -> Nullable[ExpressionUnion]:
170 """
171 Read-only property to access the default expression (:attr:`_defaultExpression`).
173 :returns: The default expression, or ``None`` if not set.
174 """
175 return self._defaultExpression
177 def _VisitDefaultExpression(self, visitor: Visitor) -> None:
178 """
179 Walk the default expression, if any, after a variable assignment delimiter (``:=``) with a visitor.
181 :param visitor: The visitor receiving the events.
182 """
183 if self._defaultExpression is not None:
184 visitor.VisitVariableAssignment(self)
185 self._defaultExpression.Visit(visitor)
188@export
189@abstractclass
190class BaseConstant(Obj):
191 """
192 Base-class for all constants (normal and deferred constants) in VHDL.
194 .. seealso::
196 * :class:`Constant <pyVHDLModel.Object.Constant>`
197 * :class:`Deferred constant <pyVHDLModel.Object.DeferredConstant>`
198 """
200 _OBJECT_KEYWORD: ClassVar[tuple[ReservedWord, ...]] = (ReservedWord.Constant,) #: The reserved words introducing this object class.
203@export
204class Constant(BaseConstant, WithDefaultExpressionMixin):
205 """
206 Represents a constant.
208 As constants (always) have a default expression, the class :class:`~pyVHDLModel.Object.WithDefaultExpressionMixin` is inherited.
210 .. admonition:: Example
212 .. code-block:: VHDL
214 constant BITS : positive := 8;
216 .. seealso::
218 * :class:`Generic constant interface item <pyVHDLModel.Interface.GenericConstantInterfaceItem>`
219 * :class:`Parameter constant interface item <pyVHDLModel.Interface.ParameterConstantInterfaceItem>`
220 """
222 def __init__(
223 self,
224 identifiers: Iterable[str],
225 subtype: Symbol,
226 defaultExpression: Nullable[ExpressionUnion] = None,
227 documentation: Nullable[str] = None,
228 parent: Nullable[ModelEntity] = None
229 ) -> None:
230 """
231 Initializes a constant.
233 :param identifiers: A list of identifiers.
234 :param subtype: Reference to the object's subtype.
235 :param defaultExpression: The default value, or ``None`` if none was given.
236 :param documentation: The documentation comment associated with this declaration.
237 :param parent: The parent model entity of this entity.
238 """
239 super().__init__(identifiers, subtype, documentation, parent)
240 WithDefaultExpressionMixin.__init__(self, defaultExpression)
242 def Copy(self) -> Self:
243 """
244 Create a copy of this constant.
246 The copy has no parent and no object vertex. Its subtype and default expression are copies of this constant's
247 subtype and default expression.
249 :returns: The new constant.
250 """
251 defaultExpression = None if self._defaultExpression is None else self._defaultExpression.Copy()
252 return self.__class__(self._identifiers, self._subtype.Copy(), defaultExpression, self._documentation)
254 def Visit(self, visitor: Visitor) -> None:
255 """
256 Walk this constant declaration, its subtype and its default expression with a visitor.
258 :param visitor: The visitor receiving the events.
259 """
260 visitor.VisitConstant(self)
261 self._subtype.Visit(visitor)
262 self._VisitDefaultExpression(visitor)
263 visitor.DepartConstant(self)
266@export
267class DeferredConstant(BaseConstant):
268 """
269 Represents a deferred constant.
271 Deferred constants are forward declarations for a (complete) constant declaration, thus it contains a
272 field :data:`__constantReference` to the complete constant declaration.
274 .. admonition:: Example
276 .. code-block:: VHDL
278 constant BITS : positive;
279 """
280 _constantReference: Nullable[Constant] #: The full declaration, or ``None`` if unlinked.
282 def __init__(
283 self,
284 identifiers: Iterable[str],
285 subtype: Symbol,
286 documentation: Nullable[str] = None,
287 parent: Nullable[ModelEntity] = None
288 ) -> None:
289 """
290 Initializes a deferred constant.
292 :param identifiers: A list of identifiers.
293 :param subtype: Reference to the object's subtype.
294 :param documentation: The documentation comment associated with this declaration.
295 :param parent: The parent model entity of this entity.
296 """
297 super().__init__(identifiers, subtype, documentation, parent)
299 self._constantReference = None
301 def Visit(self, visitor: Visitor) -> None:
302 """
303 Walk this deferred constant declaration, its subtype with a visitor.
305 :param visitor: The visitor receiving the events.
306 """
307 visitor.VisitDeferredConstant(self)
308 self._subtype.Visit(visitor)
309 visitor.DepartDeferredConstant(self)
311 @readonly
312 def ConstantReference(self) -> Nullable[Constant]:
313 """
314 Read-only property to access the constant reference (:attr:`_constantReference`).
316 :returns: The constant reference, or ``None`` if not set.
317 """
318 return self._constantReference
320 def Copy(self) -> Self:
321 """
322 Create a copy of this deferred constant.
324 The copy has no parent and no object vertex. Its subtype is a copy of this deferred constant's subtype; the full
325 constant declaration, if linked, is the same.
327 :returns: The new deferred constant.
328 """
329 copy = self.__class__(self._identifiers, self._subtype.Copy(), self._documentation)
330 copy._constantReference = self._constantReference
331 return copy
334@export
335class Variable(Obj, WithDefaultExpressionMixin):
336 """
337 Represents a variable.
339 As variables might have a default expression, the class :class:`~pyVHDLModel.Object.WithDefaultExpressionMixin` is inherited.
341 .. admonition:: Example
343 .. code-block:: VHDL
345 variable result : natural := 0;
347 .. seealso::
349 * :class:`Parameter variable interface item <pyVHDLModel.Interface.ParameterVariableInterfaceItem>`
350 """
352 _OBJECT_KEYWORD: ClassVar[tuple[ReservedWord, ...]] = (ReservedWord.Variable,) #: The reserved words introducing this object class.
354 def __init__(
355 self,
356 identifiers: Iterable[str],
357 subtype: Symbol,
358 defaultExpression: Nullable[ExpressionUnion] = None,
359 documentation: Nullable[str] = None,
360 parent: Nullable[ModelEntity] = None
361 ) -> None:
362 """
363 Initializes a variable.
365 :param identifiers: A list of identifiers.
366 :param subtype: Reference to the object's subtype.
367 :param defaultExpression: The default value, or ``None`` if none was given.
368 :param documentation: The documentation comment associated with this declaration.
369 :param parent: The parent model entity of this entity.
370 """
371 super().__init__(identifiers, subtype, documentation, parent)
372 WithDefaultExpressionMixin.__init__(self, defaultExpression)
374 def Copy(self) -> Self:
375 """
376 Create a copy of this variable.
378 The copy has no parent and no object vertex. Its subtype and default expression are copies of this variable's
379 subtype and default expression.
381 :returns: The new variable.
382 """
383 defaultExpression = None if self._defaultExpression is None else self._defaultExpression.Copy()
384 return self.__class__(self._identifiers, self._subtype.Copy(), defaultExpression, self._documentation)
386 def Visit(self, visitor: Visitor) -> None:
387 """
388 Walk this variable declaration, its subtype and its default expression with a visitor.
390 :param visitor: The visitor receiving the events.
391 """
392 visitor.VisitVariable(self)
393 self._subtype.Visit(visitor)
394 self._VisitDefaultExpression(visitor)
395 visitor.DepartVariable(self)
398@export
399class SharedVariable(Obj):
400 """
401 Represents a shared variable.
403 .. todo:: Shared variable object not implemented.
404 """
406 _OBJECT_KEYWORD: ClassVar[tuple[ReservedWord, ...]] = (ReservedWord.Shared, ReservedWord.Variable) #: The reserved words introducing this object class.
408 def Visit(self, visitor: Visitor) -> None:
409 """
410 Walk this shared variable declaration, its subtype with a visitor.
412 :param visitor: The visitor receiving the events.
413 """
414 visitor.VisitSharedVariable(self)
415 self._subtype.Visit(visitor)
416 visitor.DepartSharedVariable(self)
420@export
421class Signal(Obj, WithDefaultExpressionMixin):
422 """
423 Represents a signal.
425 As signals might have a default expression, the class :class:`~pyVHDLModel.Object.WithDefaultExpressionMixin` is inherited.
427 .. admonition:: Example
429 .. code-block:: VHDL
431 signal counter : unsigned(7 downto 0) := '0';
433 .. seealso::
435 * :class:`Port signal interface item <pyVHDLModel.Interface.PortSignalInterfaceItem>`
436 * :class:`Parameter signal interface item <pyVHDLModel.Interface.ParameterSignalInterfaceItem>`
437 """
439 _OBJECT_KEYWORD: ClassVar[tuple[ReservedWord, ...]] = (ReservedWord.Signal,) #: The reserved words introducing this object class.
441 def __init__(
442 self,
443 identifiers: Iterable[str],
444 subtype: Symbol,
445 defaultExpression: Nullable[ExpressionUnion] = None,
446 documentation: Nullable[str] = None,
447 parent: Nullable[ModelEntity] = None
448 ) -> None:
449 """
450 Initializes a signal.
452 :param identifiers: A list of identifiers.
453 :param subtype: Reference to the object's subtype.
454 :param defaultExpression: The default value, or ``None`` if none was given.
455 :param documentation: The documentation comment associated with this declaration.
456 :param parent: The parent model entity of this entity.
457 """
458 super().__init__(identifiers, subtype, documentation, parent)
459 WithDefaultExpressionMixin.__init__(self, defaultExpression)
461 def Copy(self) -> Self:
462 """
463 Create a copy of this signal.
465 The copy has no parent and no object vertex. Its subtype and default expression are copies of this signal's
466 subtype and default expression.
468 :returns: The new signal.
469 """
470 defaultExpression = None if self._defaultExpression is None else self._defaultExpression.Copy()
471 return self.__class__(self._identifiers, self._subtype.Copy(), defaultExpression, self._documentation)
473 def Visit(self, visitor: Visitor) -> None:
474 """
475 Walk this signal declaration, its subtype and its default expression with a visitor.
477 :param visitor: The visitor receiving the events.
478 """
479 visitor.VisitSignal(self)
480 self._subtype.Visit(visitor)
481 self._VisitDefaultExpression(visitor)
482 visitor.DepartSignal(self)
485@export
486class File(Obj):
487 """
488 Represents a file.
490 .. todo:: File object not implemented.
492 .. seealso::
494 * :class:`Parameter file interface item <pyVHDLModel.Interface.ParameterFileInterfaceItem>`
495 """
497 _OBJECT_KEYWORD: ClassVar[tuple[ReservedWord, ...]] = (ReservedWord.File,) #: The reserved words introducing this object class.
499 def Visit(self, visitor: Visitor) -> None:
500 """
501 Walk this file declaration, its subtype with a visitor.
503 :param visitor: The visitor receiving the events.
504 """
505 visitor.VisitFile(self)
506 self._subtype.Visit(visitor)
507 visitor.DepartFile(self)