Coverage for pyVHDLModel/Symbol.py: 99%

458 statements  

« 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. 

34 

35Symbols are entity specific wrappers for names that reference VHDL language entities. 

36""" 

37from __future__ import annotations 

38 

39from enum import Flag, auto 

40from typing import TYPE_CHECKING, Any, Optional as Nullable, Iterable, Mapping, Self 

41 

42from pyTooling.Common import getTypeName 

43from pyTooling.Decorators import export, notimplemented, readonly 

44from pyTooling.MetaClasses import ExtendedType, abstractclass 

45 

46from pyVHDLModel.Base import Range 

47from pyVHDLModel.Name import Name, AllName 

48if TYPE_CHECKING: 48 ↛ 49line 48 didn't jump to line 49 because the condition on line 48 was never true

49 from pyVHDLModel.Visitor import Visitor 

50 

51 

52@export 

53class PossibleReference(Flag): 

54 """ 

55 Is an enumeration, representing possible targets for a reference in a :class:`~pyVHDLModel.Symbol.Symbol`. 

56 """ 

57 

58 Unknown = 0 

59 Library = auto() #: Library 

60 Entity = auto() #: Entity 

61 Architecture = auto() #: Architecture 

62 Component = auto() #: Component 

63 Package = auto() #: Package 

64 Configuration = auto() #: Configuration 

65 Context = auto() #: Context 

66 Type = auto() #: Type 

67 Subtype = auto() #: Subtype 

68 ScalarType = auto() #: ScalarType 

69 ArrayType = auto() #: ArrayType 

70 RecordType = auto() #: RecordType 

71 RecordElement = auto() #: RecordElement 

72 AccessType = auto() #: AccessType 

73 ProtectedType = auto() #: ProtectedType 

74 FileType = auto() #: FileType 

75# Alias = auto() # TODO: Is this needed? 

76 Attribute = auto() #: Attribute 

77 TypeAttribute = auto() #: TypeAttribute 

78 ValueAttribute = auto() #: ValueAttribute 

79 SignalAttribute = auto() #: SignalAttribute 

80 RangeAttribute = auto() #: RangeAttribute 

81 ViewAttribute = auto() #: ViewAttribute 

82 Constant = auto() #: Constant 

83 Variable = auto() #: Variable 

84 Signal = auto() #: Signal 

85 File = auto() #: File 

86# Object = auto() # TODO: Is this needed? 

87 EnumLiteral = auto() #: EnumLiteral 

88 Procedure = auto() #: Procedure 

89 Function = auto() #: Function 

90 Label = auto() #: Label 

91 View = auto() #: View 

92 

93 AnyType = ScalarType | ArrayType | RecordType | ProtectedType | AccessType | FileType | Subtype #: Any possible type incl. subtypes. 

94 Object = Constant | Variable | Signal # | File #: Any object 

95 SubProgram = Procedure | Function #: Any subprogram 

96 PackageMember = AnyType | Object | SubProgram | Component #: Any member of a package 

97 SimpleNameInExpression = Constant | Variable | Signal | ScalarType | EnumLiteral | Function #: Any possible item in an expression. 

98 

99 

100# QUESTION: Why is it not a ModelEntity? 

101@export 

102class Symbol(metaclass=ExtendedType): 

103 """ 

104 Base-class for all symbol classes. 

105 """ 

106 

107 _name: Name #: The name to reference the language entity. 

108 _possibleReferences: PossibleReference #: An enumeration to filter possible references. 

109 _reference: Nullable[Any] #: The resolved language entity, otherwise ``None``. 

110 

111 def __init__(self, name: Name, possibleReferences: PossibleReference) -> None: 

112 """ 

113 Initializes a symbol. 

114 

115 :param name: The name to reference the language entity. 

116 :param possibleReferences: An enumeration to filter possible references. 

117 """ 

118 self._name = name 

119 self._possibleReferences = possibleReferences 

120 self._reference = None 

121 

122 @readonly 

123 def Name(self) -> Name: 

124 """ 

125 Read-only property to access the name (:attr:`_name`). 

126 

127 :returns: The name. 

128 """ 

129 return self._name 

130 

131 @readonly 

132 def Reference(self) -> Nullable[Any]: 

133 """ 

134 Read-only property to access the reference (:attr:`_reference`). 

135 

136 :returns: The reference, or ``None`` if not set. 

137 """ 

138 return self._reference 

139 

140 @readonly 

141 def IsResolved(self) -> bool: 

142 """ 

143 Check if the symbol is resolved, i.e. :attr:`_reference` is set. 

144 

145 :returns: ``True``, if the symbol is resolved. 

146 """ 

147 return self._reference is not None 

148 

149 def __bool__(self) -> bool: 

150 """ 

151 Reports whether this symbol has been resolved. 

152 

153 :returns: ``True`` if the symbol references a model entity. 

154 """ 

155 return self._reference is not None 

156 

157 def Copy(self) -> Self: 

158 """ 

159 Create a copy of this symbol. 

160 

161 The name is copied; the reference, if resolved, is the same. 

162 

163 :returns: The new symbol. 

164 """ 

165 copy = self.__class__(self._name.Copy(), self._possibleReferences) 

166 copy._reference = self._reference 

167 return copy 

168 

169 def Visit(self, visitor: Visitor) -> None: 

170 """ 

171 Walk this symbol and its name with a visitor. 

172 

173 :param visitor: The visitor receiving the events. 

174 """ 

175 visitor.VisitSymbol(self) 

176 self._name.Visit(visitor) 

177 visitor.DepartSymbol(self) 

178 

179 def __repr__(self) -> str: 

180 """ 

181 Formats a representation of the symbol. 

182 

183 **Format:** ``SignalSymbol: 'clk' -> <signal>``, or ``... -> ?`` while unresolved 

184 

185 :returns: String representation of the symbol. 

186 """ 

187 if self._reference is not None: 

188 return f"{getTypeName(self)}: '{self._name!s}' -> {self._reference!s}" 

189 

190 return f"{getTypeName(self)}: '{self._name!s}' -> unresolved" 

191 

192 def __str__(self) -> str: 

193 """ 

194 Formats the symbol. 

195 

196 **Format:** the referenced model entity once resolved, else the name plus ``?`` 

197 

198 :returns: Formatted symbol. 

199 """ 

200 if self._reference is not None: 

201 return str(self._reference) 

202 

203 return f"{self._name!s}?" 

204 

205 

206@export 

207class LibraryReferenceSymbol(Symbol): 

208 """ 

209 Represents a reference (name) to a library. 

210 

211 The internal name will be a :class:`~pyVHDLModel.Name.SimpleName`. 

212 

213 .. admonition:: Example 

214 

215 .. code-block:: VHDL 

216 

217 library ieee; 

218 -- ^^^^ 

219 """ 

220 

221 def __init__(self, name: Name) -> None: 

222 """ 

223 Initializes a reference (name) to a library. 

224 

225 :param name: The name to reference the language entity. 

226 """ 

227 super().__init__(name, PossibleReference.Library) 

228 

229 @property 

230 def Library(self) -> Nullable[Library]: 

231 """ 

232 Property to access the library (:attr:`_reference`). 

233 

234 :returns: The library, or ``None`` if not set. 

235 """ 

236 return self._reference 

237 

238 @Library.setter 

239 def Library(self, value: Library) -> None: 

240 self._reference = value 

241 

242 def Copy(self) -> Self: 

243 """ 

244 Create a copy of this library reference symbol. 

245 

246 The name is copied; the reference, if resolved, is the same. 

247 

248 :returns: The new library reference symbol. 

249 """ 

250 copy = self.__class__(self._name.Copy()) 

251 copy._reference = self._reference 

252 return copy 

253 

254 

255@export 

256class PackageReferenceSymbol(Symbol): 

257 """ 

258 Represents a reference (name) to a package. 

259 

260 The internal name will be a :class:`~pyVHDLModel.Name.SelectedName`. 

261 

262 .. admonition:: Example 

263 

264 .. code-block:: VHDL 

265 

266 use ieee.numeric_std; 

267 -- ^^^^^^^^^^^^^^^^ 

268 """ 

269 

270 def __init__(self, name: Name) -> None: 

271 """ 

272 Initializes a reference (name) to a package. 

273 

274 :param name: The name to reference the language entity. 

275 """ 

276 super().__init__(name, PossibleReference.Package) 

277 

278 @property 

279 def Package(self) -> Nullable[Package]: 

280 """ 

281 Property to access the package (:attr:`_reference`). 

282 

283 :returns: The package, or ``None`` if not set. 

284 """ 

285 return self._reference 

286 

287 @Package.setter 

288 def Package(self, value: Package) -> None: 

289 self._reference = value 

290 

291 def Copy(self) -> Self: 

292 """ 

293 Create a copy of this package reference symbol. 

294 

295 The name is copied; the reference, if resolved, is the same. 

296 

297 :returns: The new package reference symbol. 

298 """ 

299 copy = self.__class__(self._name.Copy()) 

300 copy._reference = self._reference 

301 return copy 

302 

303 

304@export 

305class ModeViewSymbol(Symbol): 

306 """ 

307 Represents a reference to a mode view (VHDL-2019). 

308 

309 The referenced mode view is available as :data:`Reference` once resolved. A reference may also 

310 select the converse view. 

311 

312 .. admonition:: Example 

313 

314 Referencing a mode view: 

315 

316 .. code-block:: VHDL 

317 

318 port (p : view MasterView); 

319 -- ^^^^^^^^^^ <- Name 

320 

321 Referencing its converse: 

322 

323 .. code-block:: VHDL 

324 

325 port (p : view MasterView'converse); 

326 -- ^^^^^^^^^^^^^^^^^^^ <- Name 

327 """ 

328 

329 def __init__(self, name: Name) -> None: 

330 """ 

331 Initializes a reference to a mode view (VHDL-2019). 

332 

333 :param name: The name to reference the language entity. 

334 """ 

335 super().__init__(name, PossibleReference.View) 

336 

337 @property 

338 def ModeView(self) -> Nullable[ModeViewDeclaration]: 

339 """ 

340 Property to access the mode view (:attr:`_reference`). 

341 

342 :returns: The mode view, or ``None`` if not set. 

343 """ 

344 return self._reference 

345 

346 @ModeView.setter 

347 def ModeView(self, value: ModeViewDeclaration) -> None: 

348 self._reference = value 

349 

350 def Copy(self) -> Self: 

351 """ 

352 Create a copy of this mode view symbol. 

353 

354 The name is copied; the reference, if resolved, is the same. 

355 

356 :returns: The new mode view symbol. 

357 """ 

358 copy = self.__class__(self._name.Copy()) 

359 copy._reference = self._reference 

360 return copy 

361 

362 

363@export 

364class SubprogramReferenceSymbol(Symbol): 

365 """ 

366 Represents a reference to a subprogram. 

367 

368 The referenced subprogram is available as :data:`Reference` once resolved. 

369 

370 .. admonition:: Example 

371 

372 .. code-block:: VHDL 

373 

374 function f is new gen_fun generic map (N => 1); 

375 -- ^^^^^^^ <- Name 

376 """ 

377 

378 def __init__(self, name: Name) -> None: 

379 """ 

380 Initializes a reference to a subprogram. 

381 

382 :param name: The name to reference the language entity. 

383 """ 

384 super().__init__(name, PossibleReference.SubProgram) 

385 

386 @property 

387 def Subprogram(self) -> Nullable[Subprogram]: 

388 """ 

389 Property to access the subprogram (:attr:`_reference`). 

390 

391 :returns: The subprogram, or ``None`` if not set. 

392 """ 

393 return self._reference 

394 

395 @Subprogram.setter 

396 def Subprogram(self, value: Subprogram) -> None: 

397 self._reference = value 

398 

399 def Copy(self) -> Self: 

400 """ 

401 Create a copy of this subprogram reference symbol. 

402 

403 The name is copied; the reference, if resolved, is the same. 

404 

405 :returns: The new subprogram reference symbol. 

406 """ 

407 copy = self.__class__(self._name.Copy()) 

408 copy._reference = self._reference 

409 return copy 

410 

411 

412@export 

413class ConfigurationSymbol(Symbol): 

414 """ 

415 Represents a reference to a configuration. 

416 

417 The referenced configuration is available as :data:`Reference` once resolved. 

418 

419 .. admonition:: Example 

420 

421 .. code-block:: VHDL 

422 

423 for U1 : comp use configuration work.cfg; 

424 -- ^^^^^^^^ <- Name 

425 """ 

426 

427 def __init__(self, name: Name) -> None: 

428 """ 

429 Initializes a reference to a configuration. 

430 

431 :param name: The name to reference the language entity. 

432 """ 

433 super().__init__(name, PossibleReference.Configuration) 

434 

435 @property 

436 def Configuration(self) -> Nullable[Configuration]: 

437 """ 

438 Property to access the configuration (:attr:`_reference`). 

439 

440 :returns: The configuration, or ``None`` if not set. 

441 """ 

442 return self._reference 

443 

444 @Configuration.setter 

445 def Configuration(self, value: Configuration) -> None: 

446 self._reference = value 

447 

448 def Copy(self) -> Self: 

449 """ 

450 Create a copy of this configuration symbol. 

451 

452 The name is copied; the reference, if resolved, is the same. 

453 

454 :returns: The new configuration symbol. 

455 """ 

456 copy = self.__class__(self._name.Copy()) 

457 copy._reference = self._reference 

458 return copy 

459 

460 

461@export 

462class VariableSymbol(Symbol): 

463 """ 

464 Represents a reference (name) to a variable. 

465 

466 The target of a variable assignment is such a reference. 

467 

468 .. admonition:: Example 

469 

470 .. code-block:: VHDL 

471 

472 v := '1'; 

473 --^ 

474 """ 

475 

476 def __init__(self, name: Name) -> None: 

477 """ 

478 Initializes a variable symbol. 

479 

480 :param name: The name to reference the language entity. 

481 """ 

482 super().__init__(name, PossibleReference.Variable) 

483 

484 @property 

485 def Variable(self) -> Nullable[Variable]: 

486 """ 

487 Property to access the variable (:attr:`_reference`). 

488 

489 :returns: The variable, or ``None`` if not set. 

490 """ 

491 return self._reference 

492 

493 @Variable.setter 

494 def Variable(self, value: Variable) -> None: 

495 self._reference = value 

496 

497 def Copy(self) -> Self: 

498 """ 

499 Create a copy of this variable symbol. 

500 

501 The name is copied; the reference, if resolved, is the same. 

502 

503 :returns: The new variable symbol. 

504 """ 

505 copy = self.__class__(self._name.Copy()) 

506 copy._reference = self._reference 

507 return copy 

508 

509 

510@export 

511class SignalSymbol(Symbol): 

512 """ 

513 Represents a reference (name) to a signal. 

514 

515 The target of a signal assignment is such a reference. 

516 

517 .. admonition:: Example 

518 

519 .. code-block:: VHDL 

520 

521 s <= '1'; 

522 --^ 

523 """ 

524 

525 def __init__(self, name: Name) -> None: 

526 """ 

527 Initializes a signal symbol. 

528 

529 :param name: The name to reference the language entity. 

530 """ 

531 super().__init__(name, PossibleReference.Signal) 

532 

533 @property 

534 def Signal(self) -> Nullable[Signal]: 

535 """ 

536 Property to access the signal (:attr:`_reference`). 

537 

538 :returns: The signal, or ``None`` if not set. 

539 """ 

540 return self._reference 

541 

542 @Signal.setter 

543 def Signal(self, value: Signal) -> None: 

544 self._reference = value 

545 

546 def Copy(self) -> Self: 

547 """ 

548 Create a copy of this signal symbol. 

549 

550 The name is copied; the reference, if resolved, is the same. 

551 

552 :returns: The new signal symbol. 

553 """ 

554 copy = self.__class__(self._name.Copy()) 

555 copy._reference = self._reference 

556 return copy 

557 

558 

559@export 

560class ContextReferenceSymbol(Symbol): 

561 """ 

562 Represents a reference (name) to a context. 

563 

564 The internal name will be a :class:`~pyVHDLModel.Name.SelectedName`. 

565 

566 .. admonition:: Example 

567 

568 .. code-block:: VHDL 

569 

570 context ieee.ieee_std_context; 

571 -- ^^^^^^^^^^^^^^^^^^^^^ 

572 """ 

573 

574 def __init__(self, name: Name) -> None: 

575 """ 

576 Initializes a reference (name) to a context. 

577 

578 :param name: The name to reference the language entity. 

579 """ 

580 super().__init__(name, PossibleReference.Context) 

581 

582 @property 

583 def Context(self) -> Context: 

584 """ 

585 Property to access the context (:attr:`_reference`). 

586 

587 :returns: The context. 

588 """ 

589 return self._reference 

590 

591 @Context.setter 

592 def Context(self, value: Context) -> None: 

593 self._reference = value 

594 

595 def Copy(self) -> Self: 

596 """ 

597 Create a copy of this context reference symbol. 

598 

599 The name is copied; the reference, if resolved, is the same. 

600 

601 :returns: The new context reference symbol. 

602 """ 

603 copy = self.__class__(self._name.Copy()) 

604 copy._reference = self._reference 

605 return copy 

606 

607 

608@export 

609class PackageMemberReferenceSymbol(Symbol): 

610 """ 

611 Represents a reference (name) to a package member. 

612 

613 The internal name will be a :class:`~pyVHDLModel.Name.SelectedName`. 

614 

615 .. admonition:: Example 

616 

617 .. code-block:: VHDL 

618 

619 use ieee.numeric_std.unsigned; 

620 -- ^^^^^^^^^^^^^^^^^^^^^^^^^ 

621 """ 

622 

623 def __init__(self, name: Name) -> None: 

624 """ 

625 Initializes a reference (name) to a package member. 

626 

627 :param name: The name to reference the language entity. 

628 """ 

629 super().__init__(name, PossibleReference.PackageMember) 

630 

631 @property 

632 def Member(self) -> Nullable[Package]: # TODO: typehint 

633 """ 

634 Property to access the member (:attr:`_reference`). 

635 

636 :returns: The member, or ``None`` if not set. 

637 """ 

638 return self._reference 

639 

640 @Member.setter 

641 def Member(self, value: Package) -> None: # TODO: typehint 

642 self._reference = value 

643 

644 def Copy(self) -> Self: 

645 """ 

646 Create a copy of this package member reference symbol. 

647 

648 The name is copied; the reference, if resolved, is the same. 

649 

650 :returns: The new package member reference symbol. 

651 """ 

652 copy = self.__class__(self._name.Copy()) 

653 copy._reference = self._reference 

654 return copy 

655 

656 

657@export 

658class AllPackageMembersReferenceSymbol(Symbol): 

659 """ 

660 Represents a reference (name) to all package members. 

661 

662 The internal name will be a :class:`~pyVHDLModel.Name.AllName`. 

663 

664 .. admonition:: Example 

665 

666 .. code-block:: VHDL 

667 

668 use ieee.numeric_std.all; 

669 -- ^^^^^^^^^^^^^^^^^^^^ 

670 """ 

671 

672 def __init__(self, name: AllName) -> None: 

673 """ 

674 Initializes a reference (name) to all package members. 

675 

676 :param name: The name to reference the language entity. 

677 """ 

678 super().__init__(name, PossibleReference.PackageMember) 

679 

680 @property 

681 def Members(self) -> Package: # TODO: typehint 

682 """ 

683 Property to access the members (:attr:`_reference`). 

684 

685 :returns: The members. 

686 """ 

687 return self._reference 

688 

689 @Members.setter 

690 def Members(self, value: Package) -> None: # TODO: typehint 

691 self._reference = value 

692 

693 def Copy(self) -> Self: 

694 """ 

695 Create a copy of this all package members reference symbol. 

696 

697 The name is copied; the reference, if resolved, is the same. 

698 

699 :returns: The new all package members reference symbol. 

700 """ 

701 copy = self.__class__(self._name.Copy()) 

702 copy._reference = self._reference 

703 return copy 

704 

705 

706@export 

707class EntityInstantiationSymbol(Symbol): 

708 """ 

709 Represents a reference (name) to an entity in a direct entity instantiation. 

710 

711 The internal name will be a :class:`~pyVHDLModel.Name.SimpleName` or :class:`~pyVHDLModel.Name.SelectedName`. 

712 

713 .. admonition:: Example 

714 

715 .. code-block:: VHDL 

716 

717 inst : entity work.Counter; 

718 -- ^^^^^^^^^^^^ 

719 """ 

720 

721 def __init__(self, name: Name) -> None: 

722 """ 

723 Initializes a reference (name) to an entity in a direct entity instantiation. 

724 

725 :param name: The name to reference the language entity. 

726 """ 

727 super().__init__(name, PossibleReference.Entity) 

728 

729 @property 

730 def Entity(self) -> Entity: 

731 """ 

732 Property to access the entity (:attr:`_reference`). 

733 

734 :returns: The entity. 

735 """ 

736 return self._reference 

737 

738 @Entity.setter 

739 def Entity(self, value: Entity) -> None: 

740 self._reference = value 

741 

742 def Copy(self) -> Self: 

743 """ 

744 Create a copy of this entity instantiation symbol. 

745 

746 The name is copied; the reference, if resolved, is the same. 

747 

748 :returns: The new entity instantiation symbol. 

749 """ 

750 copy = self.__class__(self._name.Copy()) 

751 copy._reference = self._reference 

752 return copy 

753 

754 

755@export 

756class ComponentInstantiationSymbol(Symbol): 

757 """ 

758 Represents a reference (name) to an entity in a component instantiation. 

759 

760 The internal name will be a :class:`~pyVHDLModel.Name.SimpleName` or :class:`~pyVHDLModel.Name.SelectedName`. 

761 

762 .. admonition:: Example 

763 

764 .. code-block:: VHDL 

765 

766 inst : component Counter; 

767 -- ^^^^^^^ 

768 """ 

769 

770 def __init__(self, name: Name) -> None: 

771 """ 

772 Initializes a reference (name) to an entity in a component instantiation. 

773 

774 :param name: The name to reference the language entity. 

775 """ 

776 super().__init__(name, PossibleReference.Component) 

777 

778 @property 

779 def Component(self) -> Component: 

780 """ 

781 Property to access the component (:attr:`_reference`). 

782 

783 :returns: The component. 

784 """ 

785 return self._reference 

786 

787 @Component.setter 

788 def Component(self, value: Component) -> None: 

789 self._reference = value 

790 

791 def Copy(self) -> Self: 

792 """ 

793 Create a copy of this component instantiation symbol. 

794 

795 The name is copied; the reference, if resolved, is the same. 

796 

797 :returns: The new component instantiation symbol. 

798 """ 

799 copy = self.__class__(self._name.Copy()) 

800 copy._reference = self._reference 

801 return copy 

802 

803 

804@export 

805class ConfigurationInstantiationSymbol(Symbol): 

806 """ 

807 Represents a reference (name) to an entity in a configuration instantiation. 

808 

809 The internal name will be a :class:`~pyVHDLModel.Name.SimpleName` or :class:`~pyVHDLModel.Name.SelectedName`. 

810 

811 .. admonition:: Example 

812 

813 .. code-block:: VHDL 

814 

815 inst : configuration Counter; 

816 -- ^^^^^^^ 

817 """ 

818 

819 def __init__(self, name: Name) -> None: 

820 """ 

821 Initializes a reference (name) to an entity in a configuration instantiation. 

822 

823 :param name: The name to reference the language entity. 

824 """ 

825 super().__init__(name, PossibleReference.Configuration) 

826 

827 @property 

828 def Configuration(self) -> Configuration: 

829 """ 

830 Property to access the configuration (:attr:`_reference`). 

831 

832 :returns: The configuration. 

833 """ 

834 return self._reference 

835 

836 @Configuration.setter 

837 def Configuration(self, value: Configuration) -> None: 

838 self._reference = value 

839 

840 def Copy(self) -> Self: 

841 """ 

842 Create a copy of this configuration instantiation symbol. 

843 

844 The name is copied; the reference, if resolved, is the same. 

845 

846 :returns: The new configuration instantiation symbol. 

847 """ 

848 copy = self.__class__(self._name.Copy()) 

849 copy._reference = self._reference 

850 return copy 

851 

852 

853@export 

854class EntitySymbol(Symbol): 

855 """ 

856 Represents a reference (name) to an entity in an architecture declaration. 

857 

858 The internal name will be a :class:`~pyVHDLModel.Name.SimpleName` or :class:`~pyVHDLModel.Name.SelectedName`. 

859 

860 .. admonition:: Example 

861 

862 .. code-block:: VHDL 

863 

864 architecture rtl of Counter is 

865 -- ^^^^^^^ 

866 begin 

867 end architecture; 

868 """ 

869 

870 def __init__(self, name: Name) -> None: 

871 """ 

872 Initializes a reference (name) to an entity in an architecture declaration. 

873 

874 :param name: The name to reference the language entity. 

875 """ 

876 super().__init__(name, PossibleReference.Entity) 

877 

878 @property 

879 def Entity(self) -> Entity: 

880 """ 

881 Property to access the entity (:attr:`_reference`). 

882 

883 :returns: The entity. 

884 """ 

885 return self._reference 

886 

887 @Entity.setter 

888 def Entity(self, value: Entity) -> None: 

889 self._reference = value 

890 

891 def Copy(self) -> Self: 

892 """ 

893 Create a copy of this entity symbol. 

894 

895 The name is copied; the reference, if resolved, is the same. 

896 

897 :returns: The new entity symbol. 

898 """ 

899 copy = self.__class__(self._name.Copy()) 

900 copy._reference = self._reference 

901 return copy 

902 

903 

904@export 

905class ArchitectureSymbol(Symbol): 

906 """An entity reference in an entity instantiation with architecture name.""" 

907 

908 def __init__(self, name: Name) -> None: 

909 """ 

910 Initializes an architecture symbol. 

911 

912 :param name: The name to reference the language entity. 

913 """ 

914 super().__init__(name, PossibleReference.Architecture) 

915 

916 @property 

917 def Architecture(self) -> Architecture: 

918 """ 

919 Property to access the architecture (:attr:`_reference`). 

920 

921 :returns: The architecture. 

922 """ 

923 return self._reference 

924 

925 @Architecture.setter 

926 def Architecture(self, value: Architecture) -> None: 

927 self._reference = value 

928 

929 def Copy(self) -> Self: 

930 """ 

931 Create a copy of this architecture symbol. 

932 

933 The name is copied; the reference, if resolved, is the same. 

934 

935 :returns: The new architecture symbol. 

936 """ 

937 copy = self.__class__(self._name.Copy()) 

938 copy._reference = self._reference 

939 return copy 

940 

941 

942@export 

943class PackageSymbol(Symbol): 

944 """ 

945 Represents a reference (name) to a package in a package body declaration. 

946 

947 The internal name will be a :class:`~pyVHDLModel.Name.SimpleName` or :class:`~pyVHDLModel.Name.SelectedName`. 

948 

949 .. admonition:: Example 

950 

951 .. code-block:: VHDL 

952 

953 package body Utilities is 

954 -- ^^^^^^^^^ 

955 end package body; 

956 """ 

957 

958 def __init__(self, name: Name) -> None: 

959 """ 

960 Initializes a reference (name) to a package in a package body declaration. 

961 

962 :param name: The name to reference the language entity. 

963 """ 

964 super().__init__(name, PossibleReference.Package) 

965 

966 @property 

967 def Package(self) -> Package: 

968 """ 

969 Property to access the package (:attr:`_reference`). 

970 

971 :returns: The package. 

972 """ 

973 return self._reference 

974 

975 @Package.setter 

976 def Package(self, value: Package) -> None: 

977 self._reference = value 

978 

979 def Copy(self) -> Self: 

980 """ 

981 Create a copy of this package symbol. 

982 

983 The name is copied; the reference, if resolved, is the same. 

984 

985 :returns: The new package symbol. 

986 """ 

987 copy = self.__class__(self._name.Copy()) 

988 copy._reference = self._reference 

989 return copy 

990 

991 

992@export 

993class RecordElementSymbol(Symbol): 

994 """ 

995 Represents a reference to a record element. 

996 

997 The referenced language entity is available as :data:`Reference` once resolved. 

998 

999 .. admonition:: Example 

1000 

1001 .. code-block:: VHDL 

1002 

1003 r := (a => '1', b => '0'); 

1004 -- ^ <- Name 

1005 """ 

1006 def __init__(self, name: Name) -> None: 

1007 """ 

1008 Initializes a reference to a record element. 

1009 

1010 :param name: The name to reference the language entity. 

1011 """ 

1012 super().__init__(name, PossibleReference.RecordElement) 

1013 

1014 def Copy(self) -> Self: 

1015 """ 

1016 Create a copy of this record element symbol. 

1017 

1018 The name is copied; the reference, if resolved, is the same. 

1019 

1020 :returns: The new record element symbol. 

1021 """ 

1022 copy = self.__class__(self._name.Copy()) 

1023 copy._reference = self._reference 

1024 return copy 

1025 

1026 

1027@export 

1028class RangeAttributeSymbol(Symbol): 

1029 """ 

1030 A symbol referencing a range attribute. 

1031 

1032 ``vector'range`` is such a reference. 

1033 """ 

1034 

1035 def __init__(self, name: Name) -> None: 

1036 """ 

1037 Initialize a range attribute symbol. 

1038 

1039 :param name: The attribute name referencing the range. 

1040 """ 

1041 super().__init__(name, PossibleReference.RangeAttribute) 

1042 

1043 def Copy(self) -> Self: 

1044 """ 

1045 Create a copy of this range attribute symbol. 

1046 

1047 The name is copied; the reference, if resolved, is the same. 

1048 

1049 :returns: The new range attribute symbol. 

1050 """ 

1051 copy = self.__class__(self._name.Copy()) 

1052 copy._reference = self._reference 

1053 return copy 

1054 

1055 

1056@export 

1057class SubtypeSymbol(Symbol): 

1058 """ 

1059 Represents the base-class of all references to a type or subtype. 

1060 

1061 The referenced language entity is available as :data:`Reference` once resolved. 

1062 

1063 .. seealso:: 

1064 

1065 * :class:`Simple subtype symbol <pyVHDLModel.Symbol.SimpleSubtypeSymbol>` 

1066 * :class:`Constrained scalar subtype symbol <pyVHDLModel.Symbol.ConstrainedScalarSubtypeSymbol>` 

1067 * :class:`Constrained composite subtype symbol <pyVHDLModel.Symbol.ConstrainedCompositeSubtypeSymbol>` 

1068 """ 

1069 def __init__(self, name: Name) -> None: 

1070 """ 

1071 Initializes a subtype symbol. 

1072 

1073 :param name: The name to reference the language entity. 

1074 """ 

1075 super().__init__(name, PossibleReference.Type | PossibleReference.Subtype) 

1076 

1077 @readonly 

1078 def TypeMark(self) -> str: 

1079 """ 

1080 Read-only property to return the type mark's name, as written: its identifiers joined by dots. 

1081 

1082 A simple name gives its identifier (``natural``), a selected name the identifiers of its prefixes too 

1083 (``ieee.numeric_std.unsigned``). The model doesn't resolve type marks yet, so this isn't the fully qualified name of 

1084 the denoted type. 

1085 

1086 :returns: The type mark's name. 

1087 """ 

1088 name = self._name 

1089 identifiers = [name._identifier] 

1090 while name._prefix is not None: 

1091 name = name._prefix 

1092 identifiers.append(name._identifier) 

1093 

1094 return ".".join(reversed(identifiers)) 

1095 

1096 @property 

1097 def Subtype(self) -> Subtype: 

1098 """ 

1099 Property to access the subtype (:attr:`_reference`). 

1100 

1101 :returns: The subtype. 

1102 """ 

1103 return self._reference 

1104 

1105 @Subtype.setter 

1106 def Subtype(self, value: Subtype) -> None: 

1107 self._reference = value 

1108 

1109 def Copy(self) -> Self: 

1110 """ 

1111 Create a copy of this subtype symbol. 

1112 

1113 The name is copied; the reference, if resolved, is the same. 

1114 

1115 :returns: The new subtype symbol. 

1116 """ 

1117 copy = self.__class__(self._name.Copy()) 

1118 copy._reference = self._reference 

1119 return copy 

1120 

1121 

1122@export 

1123class SimpleSubtypeSymbol(SubtypeSymbol): 

1124 """ 

1125 Represents a reference to a type or subtype by its type mark. 

1126 

1127 The referenced language entity is available as :data:`Reference` once resolved. 

1128 

1129 .. admonition:: Example 

1130 

1131 .. code-block:: VHDL 

1132 

1133 signal s : bit := '0'; 

1134 -- ^^^ <- Name 

1135 """ 

1136 pass 

1137 

1138 

1139@export 

1140class Constraint(metaclass=ExtendedType, mixin=True): 

1141 """ 

1142 A mixin-class for symbols carrying a constraint. 

1143 

1144 .. seealso:: 

1145 

1146 * :class:`Scalar constraint <pyVHDLModel.Symbol.ScalarConstraint>` 

1147 * :class:`Array constraint <pyVHDLModel.Symbol.ArrayConstraint>` 

1148 * :class:`Record constraint <pyVHDLModel.Symbol.RecordConstraint>` 

1149 """ 

1150 pass 

1151 

1152 

1153@export 

1154class ScalarConstraint(Constraint, mixin=True): 

1155 """ 

1156 A mixin-class for a scalar constraint: a range. 

1157 

1158 The range is available as :data:`Constraint`. 

1159 

1160 .. seealso:: 

1161 

1162 * :class:`Constrained scalar subtype symbol <pyVHDLModel.Symbol.ConstrainedScalarSubtypeSymbol>` 

1163 """ 

1164 _constraint: Range #: The range constraining the scalar subtype. 

1165 

1166 def __init__(self, constraint: Range) -> None: 

1167 """ 

1168 Initializes a scalar constraint. 

1169 

1170 :param constraint: The range constraining the scalar subtype. 

1171 """ 

1172 self._constraint = constraint 

1173 

1174 @readonly 

1175 def Constraint(self) -> Range: 

1176 """ 

1177 Read-only property to access the scalar type's range constraint (:attr:`_constraint`). 

1178 

1179 :returns: The constraint of the scalar subtype. 

1180 """ 

1181 return self._constraint 

1182 

1183 

1184@export 

1185class ConstrainedScalarSubtypeSymbol(SubtypeSymbol, ScalarConstraint): 

1186 """ 

1187 Represents a reference to a scalar subtype narrowed by a range. 

1188 

1189 The referenced language entity is available as :data:`Reference` once resolved. The range is 

1190 mandatory: a type mark without a range constraint is a :class:`~pyVHDLModel.Symbol.SimpleSubtypeSymbol`. 

1191 

1192 .. admonition:: Example 

1193 

1194 .. code-block:: VHDL 

1195 

1196 for i in integer range 0 to 3 loop 

1197 -- ^^^^^^^ <- Name 

1198 -- ^^^^^^ <- Constraint 

1199 

1200 A range constraint written as a range attribute is a :class:`~pyVHDLModel.Base.RangeFromName` 

1201 referring to a :class:`~pyVHDLModel.Symbol.RangeAttributeSymbol`: 

1202 

1203 .. code-block:: VHDL 

1204 

1205 subtype index is natural range vector'range; 

1206 -- ^^^^^^^ <- Name 

1207 -- ^^^^^^^^^^^^ <- Constraint 

1208 """ 

1209 

1210 def __init__(self, name: Name, constraint: Range) -> None: 

1211 """ 

1212 Initializes a reference to a scalar subtype narrowed by a range. 

1213 

1214 :param name: The name to reference the language entity. 

1215 :param constraint: The range constraining the scalar subtype. 

1216 """ 

1217 super().__init__(name) 

1218 ScalarConstraint.__init__(self, constraint) 

1219 

1220 def Copy(self) -> Self: 

1221 """ 

1222 Create a copy of this constrained scalar subtype symbol. 

1223 

1224 The name and the range are copied; the reference, if resolved, is the same. 

1225 

1226 :returns: The new constrained scalar subtype symbol. 

1227 """ 

1228 copy = self.__class__(self._name.Copy(), self._constraint.Copy()) 

1229 copy._reference = self._reference 

1230 return copy 

1231 

1232 def Visit(self, visitor: Visitor) -> None: 

1233 """ 

1234 Walk this constrained scalar subtype symbol, its name and its range constraint with a visitor. 

1235 

1236 :param visitor: The visitor receiving the events. 

1237 """ 

1238 visitor.VisitConstrainedScalarSubtypeSymbol(self) 

1239 self._name.Visit(visitor) 

1240 visitor.VisitRangeConstraint(self) 

1241 self._constraint.Visit(visitor) 

1242 visitor.DepartRangeConstraint(self) 

1243 visitor.DepartConstrainedScalarSubtypeSymbol(self) 

1244 

1245 

1246@export 

1247class ArrayConstraint(Constraint, mixin=True): 

1248 """ 

1249 A mixin-class for an array constraint: one range per dimension. 

1250 

1251 The ranges are available as :data:`Constraints`. 

1252 

1253 .. seealso:: 

1254 

1255 * :class:`Constrained array subtype symbol <pyVHDLModel.Symbol.ConstrainedArraySubtypeSymbol>` 

1256 """ 

1257 _constraints: list[Range] #: List of all index ranges, one per dimension. 

1258 

1259 def __init__(self, constraints: Iterable[Range]) -> None: 

1260 """ 

1261 Initializes an array constraint. 

1262 

1263 :param constraints: List of all index ranges, one per dimension. 

1264 """ 

1265 self._constraints = list(constraints) 

1266 

1267 @readonly 

1268 def Constraints(self) -> list[Range]: 

1269 """ 

1270 Read-only property to access the constraints (:attr:`_constraints`). 

1271 

1272 :returns: List of constraints. 

1273 """ 

1274 return self._constraints 

1275 

1276 

1277@export 

1278class RecordConstraint(Constraint, mixin=True): 

1279 """ 

1280 A mixin-class for a record constraint: one constraint per element. 

1281 

1282 The constraints are available as :data:`Constraints`. 

1283 

1284 .. seealso:: 

1285 

1286 * :class:`Constrained record subtype symbol <pyVHDLModel.Symbol.ConstrainedRecordSubtypeSymbol>` 

1287 """ 

1288 _constraints: dict[RecordElementSymbol, Range] #: Dictionary of the constraint per constrained record element. 

1289 

1290 def __init__(self, constraints: Mapping[RecordElementSymbol, Range]) -> None: 

1291 """ 

1292 Initializes a record constraint. 

1293 

1294 :param constraints: Dictionary of the constraint per constrained record element. 

1295 """ 

1296 self._constraints = dict(constraints) 

1297 

1298 @readonly 

1299 def Constraints(self) -> dict[RecordElementSymbol, Range]: 

1300 """ 

1301 Read-only property to access the constraints (:attr:`_constraints`). 

1302 

1303 :returns: Dictionary of constraints. 

1304 """ 

1305 return self._constraints 

1306 

1307 

1308@export 

1309@abstractclass 

1310class ConstrainedCompositeSubtypeSymbol(SubtypeSymbol): 

1311 """ 

1312 Represents the base-class of references to constrained composite subtypes. 

1313 

1314 The referenced language entity is available as :data:`Reference` once resolved. 

1315 

1316 .. seealso:: 

1317 

1318 * :class:`Constrained array subtype symbol <pyVHDLModel.Symbol.ConstrainedArraySubtypeSymbol>` 

1319 * :class:`Constrained record subtype symbol <pyVHDLModel.Symbol.ConstrainedRecordSubtypeSymbol>` 

1320 """ 

1321 @notimplemented("Model element has no walk for a visitor.") 

1322 def Visit(self, visitor: Visitor) -> None: 

1323 """ 

1324 Walk this constrained composite subtype symbol with a visitor. 

1325 

1326 The walk of its base class would drop the constraint; the array and record subclasses walk their constraint. 

1327 

1328 :param visitor: The visitor receiving the events. 

1329 :raises NotImplementedError: Always, because a subclass without a walk of its own can't walk its constraint. 

1330 """ 

1331 

1332 

1333@export 

1334class ConstrainedArraySubtypeSymbol(ConstrainedCompositeSubtypeSymbol, ArrayConstraint): 

1335 """ 

1336 Represents a reference to an array subtype narrowed by index ranges. 

1337 

1338 The referenced language entity is available as :data:`Reference` once resolved. 

1339 

1340 .. admonition:: Example 

1341 

1342 .. code-block:: VHDL 

1343 

1344 signal v : bit_vector(7 downto 0); 

1345 -- ^^^^^^^^^^ <- Name 

1346 -- ^^^^^^^^^^ <- Constraints 

1347 """ 

1348 _constraints: list #: List of all index ranges, one per dimension. 

1349 

1350 def __init__(self, name: Name, constraints: Iterable) -> None: 

1351 """ 

1352 Initializes a reference to an array subtype narrowed by index ranges. 

1353 

1354 :param name: The name to reference the language entity. 

1355 :param constraints: List of all index ranges, one per dimension. 

1356 """ 

1357 super().__init__(name) 

1358 ArrayConstraint.__init__(self, constraints) 

1359 

1360 def Copy(self) -> Self: 

1361 """ 

1362 Create a copy of this constrained array subtype symbol. 

1363 

1364 The name and the index ranges are copied; the reference, if resolved, is the same. 

1365 

1366 :returns: The new constrained array subtype symbol. 

1367 """ 

1368 copy = self.__class__(self._name.Copy(), [constraint.Copy() for constraint in self._constraints]) 

1369 copy._reference = self._reference 

1370 return copy 

1371 

1372 def Visit(self, visitor: Visitor) -> None: 

1373 """ 

1374 Walk this constrained array subtype symbol, its name and its index constraint with a visitor. 

1375 

1376 :param visitor: The visitor receiving the events. 

1377 """ 

1378 visitor.VisitConstrainedArraySubtypeSymbol(self) 

1379 self._name.Visit(visitor) 

1380 visitor.VisitIndexConstraint(self) 

1381 for index, constraint in enumerate(self._constraints): 

1382 if index > 0: 

1383 visitor.VisitComma(self) 

1384 

1385 constraint.Visit(visitor) 

1386 

1387 visitor.DepartIndexConstraint(self) 

1388 visitor.DepartConstrainedArraySubtypeSymbol(self) 

1389 

1390 

1391@export 

1392class ConstrainedRecordSubtypeSymbol(ConstrainedCompositeSubtypeSymbol, RecordConstraint): 

1393 """ 

1394 Represents a reference to a record subtype with constrained elements. 

1395 

1396 The referenced language entity is available as :data:`Reference` once resolved. 

1397 """ 

1398 _constraints: dict[RecordElementSymbol, Any] #: Dictionary of the constraint per constrained record element. 

1399 

1400 def __init__(self, name: Name, constraints: Mapping) -> None: 

1401 """ 

1402 Initializes a reference to a record subtype with constrained elements. 

1403 

1404 :param name: The name to reference the language entity. 

1405 :param constraints: Dictionary of the constraint per constrained record element. 

1406 """ 

1407 super().__init__(name) 

1408 RecordConstraint.__init__(self, constraints) 

1409 

1410 def Copy(self) -> Self: 

1411 """ 

1412 Create a copy of this constrained record subtype symbol. 

1413 

1414 The name, the record elements and their constraints are copied; the reference, if resolved, is the same. 

1415 

1416 :returns: The new constrained record subtype symbol. 

1417 """ 

1418 constraints = { 

1419 element.Copy(): None if constraint is None else constraint.Copy() 

1420 for element, constraint in self._constraints.items() 

1421 } 

1422 copy = self.__class__(self._name.Copy(), constraints) 

1423 copy._reference = self._reference 

1424 return copy 

1425 

1426 def Visit(self, visitor: Visitor) -> None: 

1427 """ 

1428 Walk this constrained record subtype symbol, its name and its record constraint with a visitor. 

1429 

1430 Each record element constraint is walked as the element's name followed by an index constraint. 

1431 

1432 :param visitor: The visitor receiving the events. 

1433 """ 

1434 visitor.VisitConstrainedRecordSubtypeSymbol(self) 

1435 self._name.Visit(visitor) 

1436 visitor.VisitRecordConstraint(self) 

1437 for index, (element, constraint) in enumerate(self._constraints.items()): 

1438 if index > 0: 

1439 visitor.VisitComma(self) 

1440 

1441 element.Visit(visitor) 

1442 visitor.VisitIndexConstraint(self) 

1443 constraint.Visit(visitor) 

1444 visitor.DepartIndexConstraint(self) 

1445 

1446 visitor.DepartRecordConstraint(self) 

1447 visitor.DepartConstrainedRecordSubtypeSymbol(self) 

1448 

1449 

1450@export 

1451class SimpleObjectOrFunctionCallSymbol(Symbol): 

1452 """ 

1453 Represents a reference that is either an object or a parameterless function call. 

1454 

1455 Which of the two it is cannot be decided before the name is resolved. The referenced language 

1456 entity is available as :data:`Reference` once resolved. 

1457 """ 

1458 def __init__(self, name: Name) -> None: 

1459 """ 

1460 Initializes a reference that is either an object or a parameterless function call. 

1461 

1462 :param name: The name to reference the language entity. 

1463 """ 

1464 super().__init__(name, PossibleReference.SimpleNameInExpression) 

1465 

1466 def Copy(self) -> Self: 

1467 """ 

1468 Create a copy of this simple object or function call symbol. 

1469 

1470 The name is copied; the reference, if resolved, is the same. 

1471 

1472 :returns: The new simple object or function call symbol. 

1473 """ 

1474 copy = self.__class__(self._name.Copy()) 

1475 copy._reference = self._reference 

1476 return copy 

1477 

1478 

1479@export 

1480class IndexedObjectOrFunctionCallSymbol(Symbol): 

1481 """ 

1482 Represents a reference that is either an indexed object, a function call or a type conversion. 

1483 

1484 The referenced language entity is available as :data:`Reference` once resolved. 

1485 

1486 .. attention:: 

1487 

1488 All three are written the same way - ``arr(0)``, ``f(0)`` and ``integer(0)`` are indistinguishable 

1489 as syntax, so a parser produces one shape for them and only name resolution tells them apart. 

1490 

1491 .. seealso:: 

1492 

1493 * :class:`Type conversion <pyVHDLModel.Expression.TypeConversion>` 

1494 * :class:`Simple object or function call <pyVHDLModel.Symbol.SimpleObjectOrFunctionCallSymbol>` 

1495 """ 

1496 def __init__(self, name: Name) -> None: 

1497 """ 

1498 Initializes a reference that is either an indexed object, a function call or a type conversion. 

1499 

1500 :param name: The name to reference the language entity. 

1501 """ 

1502 super().__init__( 

1503 name, 

1504 PossibleReference.Object | PossibleReference.Function | PossibleReference.Type | PossibleReference.Subtype 

1505 ) 

1506 

1507 def Copy(self) -> Self: 

1508 """ 

1509 Create a copy of this indexed object or function call symbol. 

1510 

1511 The name is copied; the reference, if resolved, is the same. 

1512 

1513 :returns: The new indexed object or function call symbol. 

1514 """ 

1515 copy = self.__class__(self._name.Copy()) 

1516 copy._reference = self._reference 

1517 return copy