Skip to content

Commit f1236f8

Browse files
committed
Handle package references in contexts.
1 parent f03ab2f commit f1236f8

File tree

1 file changed

+64
-6
lines changed

1 file changed

+64
-6
lines changed

pyVHDLModel/SyntaxModel.py

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,7 @@ def LinkLibraryReferences(self):
578578
DEFAULT_LIBRARIES = ("std",)
579579

580580
for designUnit in self.IterateDesignUnits(DesignUnits.WithContext):
581+
# All primary units supporting a context, have at least one library implicitly referenced
581582
if isinstance(designUnit, PrimaryUnit):
582583
for libraryIdentifier in DEFAULT_LIBRARIES:
583584
designUnit._referencedLibraries[libraryIdentifier] = self._libraries[libraryIdentifier]
@@ -589,6 +590,7 @@ def LinkLibraryReferences(self):
589590
libraryIdentifier = workingLibrary.NormalizedIdentifier
590591
designUnit._referencedLibraries[libraryIdentifier] = self._libraries[libraryIdentifier]
591592
designUnit._referencedPackages[libraryIdentifier] = {}
593+
# All secondary units inherit referenced libraries from their primary units.
592594
else:
593595
if isinstance(designUnit, Architecture):
594596
referencedLibraries = designUnit.Entity.Entity._referencedLibraries
@@ -601,15 +603,16 @@ def LinkLibraryReferences(self):
601603
designUnit._referencedLibraries[libraryIdentifier] = library
602604

603605
for libraryReference in designUnit._libraryReferences:
606+
# A library clause can have multiple comma-separated references
604607
for librarySymbol in libraryReference.Symbols:
605608
libraryIdentifier = librarySymbol.NormalizedIdentifier
606609
try:
607-
lib = self._libraries[libraryIdentifier]
610+
library = self._libraries[libraryIdentifier]
608611
except KeyError:
609612
raise Exception(f"Library '{librarySymbol.Identifier}' referenced by library clause of design unit '{designUnit.Identifier}' doesn't exist in design.")
610613

611-
librarySymbol.Library = lib
612-
designUnit._referencedLibraries[libraryIdentifier] = lib
614+
librarySymbol.Library = library
615+
designUnit._referencedLibraries[libraryIdentifier] = library
613616
designUnit._referencedPackages[libraryIdentifier] = {}
614617
# TODO: warn duplicate library reference
615618

@@ -619,6 +622,7 @@ def LinkPackageReferences(self):
619622
)
620623

621624
for designUnit in self.IterateDesignUnits(DesignUnits.WithContext):
625+
# All primary units supporting a context, have at least one package implicitly referenced
622626
if isinstance(designUnit, PrimaryUnit):
623627
for lib in DEFAULT_PACKAGES:
624628
if lib[0] not in designUnit._referencedLibraries:
@@ -627,6 +631,7 @@ def LinkPackageReferences(self):
627631
designUnit._referencedPackages[lib[0]][pack] = self._libraries[lib[0]]._packages[pack]
628632
# TODO: catch KeyError on self._libraries[lib[0]]._packages[pack]
629633
# TODO: warn duplicate package reference
634+
# All secondary units inherit referenced packages from their primary units.
630635
else:
631636
if isinstance(designUnit, Architecture):
632637
referencedPackages = designUnit.Entity.Entity._referencedPackages
@@ -639,13 +644,15 @@ def LinkPackageReferences(self):
639644
designUnit._referencedPackages[packageIdentifier] = package
640645

641646
for packageReference in designUnit.PackageReferences:
647+
# A use clause can have multiple comma-separated references
642648
for symbol in packageReference.Symbols:
643649
packageSymbol = symbol.Prefix
644650
librarySymbol = packageSymbol.Prefix
645651

646652
libraryIdentifier = librarySymbol.NormalizedIdentifier
647653
packageIdentifier = packageSymbol.NormalizedIdentifier
648654

655+
# In case work is used, resolve to the real library name.
649656
if libraryIdentifier == "work":
650657
library: Library = designUnit.Library
651658
libraryIdentifier = library.NormalizedIdentifier
@@ -666,6 +673,7 @@ def LinkPackageReferences(self):
666673
librarySymbol.Library = library
667674
packageSymbol.Package = package
668675

676+
# TODO: update the namespace with visible members
669677
if isinstance(symbol, AllPackageMembersReferenceSymbol):
670678
pass
671679

@@ -679,19 +687,68 @@ def LinkContextReferences(self):
679687

680688
def LinkContexts(self):
681689
for context in self.IterateDesignUnits(DesignUnits.Context):
690+
# Create entries in _referenced*** for the current working library under its real name.
691+
workingLibrary: Library = context.Library
692+
libraryIdentifier = workingLibrary.NormalizedIdentifier
693+
context._referencedLibraries[libraryIdentifier] = self._libraries[libraryIdentifier]
694+
context._referencedPackages[libraryIdentifier] = {}
695+
696+
# Process all library clauses
682697
for libraryReference in context._libraryReferences:
698+
# A library clause can have multiple comma-separated references
683699
for librarySymbol in libraryReference.Symbols:
684700
libraryIdentifier = librarySymbol.NormalizedIdentifier
685701
try:
686-
lib = self._libraries[libraryIdentifier]
702+
library = self._libraries[libraryIdentifier]
687703
except KeyError:
688704
raise Exception(f"Library '{librarySymbol.Identifier}' referenced by library clause of context '{context.Identifier}' doesn't exist in design.")
705+
# TODO: add position to these messages
689706

690-
librarySymbol.Library = lib
691-
context._referencedLibraries[libraryIdentifier] = lib
707+
librarySymbol.Library = library
708+
context._referencedLibraries[libraryIdentifier] = library
692709
context._referencedPackages[libraryIdentifier] = {}
693710
# TODO: warn duplicate library reference
694711

712+
# Process all use clauses
713+
for packageReference in context.PackageReferences:
714+
# A use clause can have multiple comma-separated references
715+
for symbol in packageReference.Symbols:
716+
packageSymbol = symbol.Prefix
717+
librarySymbol = packageSymbol.Prefix
718+
719+
libraryIdentifier = librarySymbol.NormalizedIdentifier
720+
packageIdentifier = packageSymbol.NormalizedIdentifier
721+
722+
# In case work is used, resolve to the real library name.
723+
if libraryIdentifier == "work":
724+
library: Library = context.Library
725+
libraryIdentifier = library.NormalizedIdentifier
726+
elif libraryIdentifier not in context._referencedLibraries:
727+
# TODO: This check doesn't trigger if it's the working library.
728+
raise Exception(f"Use clause references library '{librarySymbol.Identifier}', which was not referenced by a library clause.")
729+
else:
730+
library = self._libraries[libraryIdentifier]
731+
732+
try:
733+
package = library._packages[packageIdentifier]
734+
except KeyError:
735+
raise Exception(f"Package '{packageSymbol.Identifier}' not found in {'working ' if librarySymbol.NormalizedIdentifier == 'work' else ''}library '{library.Identifier}'.")
736+
737+
# TODO: warn duplicate package reference
738+
context._referencedPackages[libraryIdentifier][packageIdentifier] = package
739+
740+
librarySymbol.Library = library
741+
packageSymbol.Package = package
742+
743+
# TODO: update the namespace with visible members
744+
if isinstance(symbol, AllPackageMembersReferenceSymbol):
745+
pass
746+
747+
elif isinstance(symbol, PackageMembersReferenceSymbol):
748+
raise NotImplementedError()
749+
else:
750+
raise Exception()
751+
695752
def LinkArchitectures(self):
696753
for library in self._libraries.values():
697754
library.LinkArchitectures()
@@ -793,6 +850,7 @@ def LinkArchitectures(self):
793850

794851
for architecture in architecturesPerEntity.values():
795852
entity = self._entities[entityName]
853+
entity._architectures.append(architecture) # TODO: convert to dict
796854
architecture.Entity.Entity = entity
797855

798856
def LinkPackageBodies(self):

0 commit comments

Comments
 (0)