pyVHDLModelTreesitter 0.7.1__tar.gz → 0.8.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/PKG-INFO +17 -17
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/pyproject.toml +21 -23
- pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/Expression.py +37 -0
- pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/_Association.py +53 -0
- pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/_Base.py +154 -0
- pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/_Concurrent.py +192 -0
- pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/_Design.py +24 -0
- pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/_DesignUnit.py +393 -0
- pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/_Document.py +158 -0
- pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/_Interface.py +138 -0
- pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/_Name.py +20 -0
- pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/_Object.py +83 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/__init__.py +1 -12
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/_errors.py +5 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/_parse.py +195 -123
- pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/_subtype_indication.py +169 -0
- pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/format.py +375 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/__init__.py +8 -4
- pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/treesitter/_protocol.py +62 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/_utils.py +0 -17
- pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/treesitter/queries/bit_string_literal.scm +5 -0
- pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/treesitter/queries/component_declaration.scm +8 -0
- pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/treesitter/queries/concurrent_conditional_signal_assignment.scm +6 -0
- pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/treesitter/queries/constant_declaration.scm +13 -0
- pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/treesitter/queries/constrained_scalar.scm +17 -0
- pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/treesitter/queries/physical_literal.scm +4 -0
- pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/treesitter/queries/signal_declaration.scm +13 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/query.py +21 -1
- pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/Association.py +0 -104
- pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/Base.py +0 -205
- pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/Concurrent.py +0 -244
- pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/DesignUnit.py +0 -497
- pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/Expression.py +0 -651
- pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/Interface.py +0 -213
- pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/Name.py +0 -117
- pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/Object.py +0 -146
- pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/Symbol.py +0 -200
- pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/_Design.py +0 -55
- pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/_Document.py +0 -166
- pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/_Library.py +0 -46
- pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/cli/__init__.py +0 -1
- pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/cli/_dump_treesitter_parse.py +0 -29
- pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/format.py +0 -68
- pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/treesitter/_base_class.py +0 -30
- pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/treesitter/queries/constant_declaration.scm +0 -10
- pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/treesitter/queries/signal_declaration.scm +0 -10
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/.gitignore +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/LICENSE +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/README.md +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/py.typed +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/adding_expression.scm +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/architecture_definition.scm +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/association_element.scm +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/association_elements.scm +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/association_list_simple_range.scm +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/component_instantiation_statement.scm +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/concurrent_simple_signal_assignment.scm +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/constrained_1d_array.scm +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/design_units.scm +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/entity_declaration.scm +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/function_call.scm +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/ignorable_parentheses.scm +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/indexed_name.scm +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/interface_declaration.scm +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/interface_declarations.scm +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/library_clauses.scm +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/library_namespaces.scm +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/logical_expression.scm +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/multiplying_expression.scm +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/package_declaration.scm +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/package_definition.scm +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/relational_expression.scm +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/selected_names.scm +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/shift_expression.scm +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/simple_subtype.scm +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/type_conversion.scm +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/unary_expression.scm +0 -0
- {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/use_clauses.scm +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyVHDLModelTreesitter
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8.0
|
|
4
4
|
Summary: An implementation of pyVHDLModel using treesitter
|
|
5
5
|
Project-URL: Repository, https://gitlab.com/dawalters/pyVHDLModelTreesitter
|
|
6
6
|
Author: Dominic Adam Walters
|
|
@@ -16,26 +16,26 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.14
|
|
17
17
|
Requires-Python: >=3.11
|
|
18
18
|
Requires-Dist: pygments>=2.20.0
|
|
19
|
-
Requires-Dist: pyvhdlmodel>=0.
|
|
19
|
+
Requires-Dist: pyvhdlmodel>=0.38.0
|
|
20
20
|
Requires-Dist: rich>=11.0.0
|
|
21
21
|
Requires-Dist: tree-sitter-vhdl>=1.2.5
|
|
22
22
|
Requires-Dist: tree-sitter>=0.23.0
|
|
23
23
|
Provides-Extra: dev
|
|
24
|
-
Requires-Dist: coverage
|
|
25
|
-
Requires-Dist: cryptography
|
|
26
|
-
Requires-Dist: hatch
|
|
27
|
-
Requires-Dist: idna
|
|
28
|
-
Requires-Dist: jaraco-context
|
|
29
|
-
Requires-Dist: mypy
|
|
30
|
-
Requires-Dist: pre-commit
|
|
31
|
-
Requires-Dist: pytest-cov
|
|
32
|
-
Requires-Dist: pytest-order
|
|
33
|
-
Requires-Dist: pytest-sugar
|
|
34
|
-
Requires-Dist: pytest-xdist
|
|
35
|
-
Requires-Dist: pytest
|
|
36
|
-
Requires-Dist: ruff
|
|
37
|
-
Requires-Dist: ty
|
|
38
|
-
Requires-Dist: uv
|
|
24
|
+
Requires-Dist: coverage>=7.15.2; extra == 'dev'
|
|
25
|
+
Requires-Dist: cryptography>=49.0.0; extra == 'dev'
|
|
26
|
+
Requires-Dist: hatch>=1.17.1; extra == 'dev'
|
|
27
|
+
Requires-Dist: idna>=3.18; extra == 'dev'
|
|
28
|
+
Requires-Dist: jaraco-context>=6.1.2; extra == 'dev'
|
|
29
|
+
Requires-Dist: mypy>=2.3.0; extra == 'dev'
|
|
30
|
+
Requires-Dist: pre-commit>=4.6.1; extra == 'dev'
|
|
31
|
+
Requires-Dist: pytest-cov>=7.1.0; extra == 'dev'
|
|
32
|
+
Requires-Dist: pytest-order>=1.5.0; extra == 'dev'
|
|
33
|
+
Requires-Dist: pytest-sugar>=1.1.1; extra == 'dev'
|
|
34
|
+
Requires-Dist: pytest-xdist>=3.8.0; extra == 'dev'
|
|
35
|
+
Requires-Dist: pytest>=9.1.1; extra == 'dev'
|
|
36
|
+
Requires-Dist: ruff>=0.16.1; extra == 'dev'
|
|
37
|
+
Requires-Dist: ty>=0.0.65; extra == 'dev'
|
|
38
|
+
Requires-Dist: uv>=0.12.0; extra == 'dev'
|
|
39
39
|
Description-Content-Type: text/markdown
|
|
40
40
|
|
|
41
41
|
# pyVHDLModelTreesitter
|
|
@@ -4,16 +4,16 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pyVHDLModelTreesitter"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.8.0"
|
|
8
8
|
description = "An implementation of pyVHDLModel using treesitter"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
11
11
|
dependencies = [
|
|
12
|
-
"pyVHDLModel >= 0.
|
|
12
|
+
"pyVHDLModel >= 0.38.0",
|
|
13
13
|
"rich >= 11.0.0",
|
|
14
14
|
"pygments >= 2.20.0", # forced to avoid CVE
|
|
15
15
|
"tree-sitter >= 0.23.0",
|
|
16
|
-
"tree-sitter-vhdl >= 1.2.5",
|
|
16
|
+
"tree-sitter-vhdl >= 1.2.5", # TODO: move to 1.6.0 once released
|
|
17
17
|
]
|
|
18
18
|
authors = [
|
|
19
19
|
{ name = "Dominic Adam Walters" },
|
|
@@ -32,26 +32,23 @@ classifiers = [
|
|
|
32
32
|
|
|
33
33
|
[project.optional-dependencies]
|
|
34
34
|
dev = [
|
|
35
|
-
"coverage
|
|
36
|
-
"hatch
|
|
37
|
-
"cryptography
|
|
38
|
-
"idna
|
|
39
|
-
"jaraco-context
|
|
40
|
-
"mypy
|
|
41
|
-
"pre-commit
|
|
42
|
-
"pytest
|
|
43
|
-
"pytest-cov
|
|
44
|
-
"pytest-order
|
|
45
|
-
"pytest-sugar
|
|
46
|
-
"pytest-xdist
|
|
47
|
-
"ruff
|
|
48
|
-
"ty
|
|
49
|
-
"uv
|
|
35
|
+
"coverage >= 7.15.2",
|
|
36
|
+
"hatch >= 1.17.1",
|
|
37
|
+
"cryptography >= 49.0.0", # forced to avoid CVE
|
|
38
|
+
"idna >= 3.18", # forced to avoid CVE
|
|
39
|
+
"jaraco-context >= 6.1.2", # forced to avoid CVE
|
|
40
|
+
"mypy >= 2.3.0",
|
|
41
|
+
"pre-commit >= 4.6.1",
|
|
42
|
+
"pytest >= 9.1.1",
|
|
43
|
+
"pytest-cov >= 7.1.0",
|
|
44
|
+
"pytest-order >= 1.5.0",
|
|
45
|
+
"pytest-sugar >= 1.1.1",
|
|
46
|
+
"pytest-xdist >= 3.8.0",
|
|
47
|
+
"ruff >= 0.16.1",
|
|
48
|
+
"ty >= 0.0.65",
|
|
49
|
+
"uv >= 0.12.0",
|
|
50
50
|
]
|
|
51
51
|
|
|
52
|
-
[project.scripts]
|
|
53
|
-
dump-treesitter-parse = "pyVHDLModelTreesitter.cli._dump_treesitter_parse:main"
|
|
54
|
-
|
|
55
52
|
[project.urls]
|
|
56
53
|
Repository = "https://gitlab.com/dawalters/pyVHDLModelTreesitter"
|
|
57
54
|
|
|
@@ -92,12 +89,13 @@ dependencies = [
|
|
|
92
89
|
python = ["3.11", "3.12", "3.13", "3.14"]
|
|
93
90
|
|
|
94
91
|
[tool.mypy]
|
|
92
|
+
implicit_reexport = true
|
|
93
|
+
scripts_are_modules = true
|
|
95
94
|
strict = true
|
|
96
95
|
warn_unreachable = true
|
|
97
|
-
implicit_reexport = true
|
|
98
96
|
|
|
99
97
|
[tool.pytest.ini_options]
|
|
100
|
-
addopts = "--capture=fd -n
|
|
98
|
+
addopts = "--capture=fd -n auto --dist loadgroup --cov=pyVHDLModelTreesitter --cov-report html --cov-report xml --verbose --junitxml=.junit.xml -o junit_family=legacy"
|
|
101
99
|
norecursedirs = "oss/*"
|
|
102
100
|
testpaths = [
|
|
103
101
|
"tests",
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""Submodule mirroring modified aspects of pyVHDLModel.Expression."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"FunctionCall",
|
|
7
|
+
]
|
|
8
|
+
|
|
9
|
+
from typing import TYPE_CHECKING
|
|
10
|
+
|
|
11
|
+
import pyVHDLModel
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from pyVHDLModel.Association import ParameterAssociationItem
|
|
15
|
+
from pyVHDLModel.Name import Name
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
#####################################
|
|
19
|
+
# Modified first order base classes #
|
|
20
|
+
#####################################
|
|
21
|
+
class FunctionCall(pyVHDLModel.Expression.FunctionCall): # ruff: ignore[undocumented-public-class]
|
|
22
|
+
# TODO: Report on pyVHDLModel that function calls are currently undefined
|
|
23
|
+
_name: Name
|
|
24
|
+
_arguments: list[ParameterAssociationItem]
|
|
25
|
+
|
|
26
|
+
def __init__( # ruff: ignore[undocumented-public-init]
|
|
27
|
+
self,
|
|
28
|
+
name: Name,
|
|
29
|
+
arguments: list[ParameterAssociationItem],
|
|
30
|
+
parent: pyVHDLModel.Base.ModelEntity | None = None,
|
|
31
|
+
) -> None:
|
|
32
|
+
super().__init__(parent)
|
|
33
|
+
self._name = name
|
|
34
|
+
self._arguments = arguments
|
|
35
|
+
|
|
36
|
+
def __str__(self) -> str: # ruff: ignore[undocumented-magic-method]
|
|
37
|
+
return f"{self._name}({', '.join(str(a) for a in self._arguments)})"
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""Submodule defining parsers for classes from pyVHDLModel.Association."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"parse_association_item",
|
|
7
|
+
]
|
|
8
|
+
|
|
9
|
+
from typing import TYPE_CHECKING, TypeVar
|
|
10
|
+
|
|
11
|
+
from pyVHDLModel.Association import AssociationItem
|
|
12
|
+
from pyVHDLModel.Name import OpenName
|
|
13
|
+
from pyVHDLModel.Symbol import SignalSymbol
|
|
14
|
+
|
|
15
|
+
from pyVHDLModelTreesitter._Name import parse_name
|
|
16
|
+
from pyVHDLModelTreesitter.treesitter import (
|
|
17
|
+
get_node,
|
|
18
|
+
get_node_text,
|
|
19
|
+
inject_node,
|
|
20
|
+
)
|
|
21
|
+
from pyVHDLModelTreesitter.treesitter.query import AssociationElement
|
|
22
|
+
|
|
23
|
+
if TYPE_CHECKING:
|
|
24
|
+
import pyVHDLModel
|
|
25
|
+
import tree_sitter
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
T = TypeVar("T", bound=AssociationItem)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def parse_association_item(cls: type[T], node: tree_sitter.Node) -> T | None:
|
|
32
|
+
"""Create an AssociationItem from a tree-sitter node."""
|
|
33
|
+
captures = AssociationElement.capture_first_root(node)
|
|
34
|
+
formal_node = get_node(node, captures, "formal", optional=True)
|
|
35
|
+
formal = None
|
|
36
|
+
if formal_node is not None:
|
|
37
|
+
formal = SignalSymbol(parse_name(get_node_text(formal_node)))
|
|
38
|
+
actual_node = get_node(node, captures, "actual")
|
|
39
|
+
actual: pyVHDLModel.Base.ExpressionUnion
|
|
40
|
+
if actual_node.type == "OPEN":
|
|
41
|
+
actual = OpenName()
|
|
42
|
+
else:
|
|
43
|
+
# ruff: ignore[import-outside-top-level]
|
|
44
|
+
from pyVHDLModelTreesitter._parse import parse_conditional_expression
|
|
45
|
+
|
|
46
|
+
actual = parse_conditional_expression(actual_node)
|
|
47
|
+
if actual is None:
|
|
48
|
+
return None
|
|
49
|
+
# TODO: `formal` is a `SignalSymbol`, is this correct?
|
|
50
|
+
# TODO: `OpenName` might need wrapping in a `Symbol`
|
|
51
|
+
# ty: ignore[invalid-argument-type]
|
|
52
|
+
ret = cls(formal, actual) # type: ignore[arg-type]
|
|
53
|
+
return inject_node(ret, node)
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"""Submodule defining parsers for classes from pyVHDLModel.Base."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"parse_direction",
|
|
7
|
+
"parse_mode",
|
|
8
|
+
"parse_simple_range",
|
|
9
|
+
"parse_waveform_element",
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
from typing import TYPE_CHECKING
|
|
13
|
+
|
|
14
|
+
import pyVHDLModel
|
|
15
|
+
from pyVHDLModel.Base import SimpleRange, WaveformElement
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from tree_sitter import Node
|
|
19
|
+
|
|
20
|
+
from pyVHDLModelTreesitter._errors import (
|
|
21
|
+
NodeExtraChildError,
|
|
22
|
+
NodeMissingChildError,
|
|
23
|
+
NodeTextIsInvalidError,
|
|
24
|
+
NodeTextIsNoneError,
|
|
25
|
+
NotImplementedWarning,
|
|
26
|
+
)
|
|
27
|
+
from pyVHDLModelTreesitter._parse import parse_simple_expression
|
|
28
|
+
from pyVHDLModelTreesitter.treesitter import inject_node
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def parse_direction(string: str) -> pyVHDLModel.Base.Direction | None:
|
|
32
|
+
"""
|
|
33
|
+
Parse a string as a direction.
|
|
34
|
+
|
|
35
|
+
This will accept any mix of the following:
|
|
36
|
+
- Incorrect capitalisation
|
|
37
|
+
- "tO"
|
|
38
|
+
- "To"
|
|
39
|
+
- Split words with whitespace
|
|
40
|
+
- "down to"
|
|
41
|
+
"""
|
|
42
|
+
# TODO: make a PR on pyVHDLModel to add this
|
|
43
|
+
string = "".join(string.split()).lower().capitalize()
|
|
44
|
+
if string == "Downto":
|
|
45
|
+
string = "DownTo"
|
|
46
|
+
try:
|
|
47
|
+
return pyVHDLModel.Base.Direction[string]
|
|
48
|
+
except IndexError:
|
|
49
|
+
return None
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def parse_mode(string: str) -> pyVHDLModel.Base.Mode | None:
|
|
53
|
+
"""
|
|
54
|
+
Parse a string as a mode.
|
|
55
|
+
|
|
56
|
+
This will accept any mix of the following:
|
|
57
|
+
- Incorrect capitalisation
|
|
58
|
+
- "IN"
|
|
59
|
+
- "iN"
|
|
60
|
+
- "in"
|
|
61
|
+
- Split words with whitespace
|
|
62
|
+
- "in out"
|
|
63
|
+
"""
|
|
64
|
+
# TODO: make a PR on pyVHDLModel to add this
|
|
65
|
+
string = "".join(string.split()).lower().capitalize()
|
|
66
|
+
if string == "Inout":
|
|
67
|
+
string = "InOut"
|
|
68
|
+
try:
|
|
69
|
+
return pyVHDLModel.Base.Mode[string]
|
|
70
|
+
except IndexError:
|
|
71
|
+
return None
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def parse_simple_range(node: Node) -> SimpleRange | None: # ruff: ignore[complex-structure, too-many-branches]
|
|
75
|
+
"""
|
|
76
|
+
Create a SimpleRange from a treesitter node.
|
|
77
|
+
|
|
78
|
+
Raises
|
|
79
|
+
------
|
|
80
|
+
NodeExtraChildError:
|
|
81
|
+
If `node.children` does not have 2 elements.
|
|
82
|
+
NodeMissingChildError:
|
|
83
|
+
If `node.type` is not `simple_range`.
|
|
84
|
+
NodeTextIsInvalidError:
|
|
85
|
+
If the direction in `node` could not be parsed.
|
|
86
|
+
NodeTextIsNoneError:
|
|
87
|
+
If `node` or any relevant subnode doesn't define `text`.
|
|
88
|
+
|
|
89
|
+
"""
|
|
90
|
+
if node.type != "simple_range":
|
|
91
|
+
raise NodeMissingChildError(node, "simple_range")
|
|
92
|
+
if node.text is None or len(node.text) == 0:
|
|
93
|
+
raise NodeTextIsNoneError(node)
|
|
94
|
+
if len(node.children) != 3: # ruff: ignore[magic-value-comparison]
|
|
95
|
+
raise NodeExtraChildError(node, "all children", 3)
|
|
96
|
+
left = node.child(0)
|
|
97
|
+
if left is None:
|
|
98
|
+
raise NodeMissingChildError(node, "first-child")
|
|
99
|
+
if left.type != "simple_expression":
|
|
100
|
+
NotImplementedWarning.warn_child_type(left)
|
|
101
|
+
return None
|
|
102
|
+
if left.text is None or len(left.text) == 0:
|
|
103
|
+
raise NodeTextIsNoneError(left)
|
|
104
|
+
direction_node = node.child(1)
|
|
105
|
+
if direction_node is None:
|
|
106
|
+
raise NodeMissingChildError(node, "second-child")
|
|
107
|
+
if len(direction_node.type) == 0:
|
|
108
|
+
NotImplementedWarning.warn_child_type(direction_node)
|
|
109
|
+
return None
|
|
110
|
+
if direction_node.text is None or len(direction_node.text) == 0:
|
|
111
|
+
raise NodeTextIsNoneError(direction_node)
|
|
112
|
+
direction_str = direction_node.text.decode("utf-8")
|
|
113
|
+
right = node.child(2)
|
|
114
|
+
if right is None:
|
|
115
|
+
raise NodeMissingChildError(node, "third-child")
|
|
116
|
+
if right.type != "simple_expression":
|
|
117
|
+
NotImplementedWarning.warn_child_type(right)
|
|
118
|
+
return None
|
|
119
|
+
if right.text is None or len(right.text) == 0:
|
|
120
|
+
raise NodeTextIsNoneError(right)
|
|
121
|
+
left_expr = parse_simple_expression(left)
|
|
122
|
+
if left_expr is None:
|
|
123
|
+
return None
|
|
124
|
+
right_expr = parse_simple_expression(right)
|
|
125
|
+
if right_expr is None:
|
|
126
|
+
return None
|
|
127
|
+
direction = parse_direction(direction_str)
|
|
128
|
+
if direction is None:
|
|
129
|
+
raise NodeTextIsInvalidError(
|
|
130
|
+
node,
|
|
131
|
+
f"'{direction_str}' is not a valid VHDL direction",
|
|
132
|
+
)
|
|
133
|
+
return inject_node(SimpleRange(left_expr, right_expr, direction), node)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def parse_waveform_element(node: Node) -> WaveformElement | None:
|
|
137
|
+
"""Create a WaveformElement from a treesitter node."""
|
|
138
|
+
if node.type != "waveform_element":
|
|
139
|
+
return None
|
|
140
|
+
simple_expression_node = None
|
|
141
|
+
for child in node.children:
|
|
142
|
+
if child.type == "simple_expression":
|
|
143
|
+
simple_expression_node = child
|
|
144
|
+
break
|
|
145
|
+
if simple_expression_node is None:
|
|
146
|
+
NotImplementedWarning.warn(
|
|
147
|
+
"waveform_element expects a 'simple_expression' child",
|
|
148
|
+
node,
|
|
149
|
+
)
|
|
150
|
+
return None
|
|
151
|
+
expression = parse_simple_expression(simple_expression_node)
|
|
152
|
+
if expression is None:
|
|
153
|
+
return None
|
|
154
|
+
return inject_node(WaveformElement(expression), node)
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"""Submodule defining parsers for classes from pyVHDLModel.Concurrent."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"parse_component_instantiation",
|
|
7
|
+
"parse_concurrent_conditional_signal_assignment",
|
|
8
|
+
"parse_concurrent_simple_signal_assignment",
|
|
9
|
+
"parse_entity_instantiation",
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
from typing import TYPE_CHECKING
|
|
13
|
+
|
|
14
|
+
from pyVHDLModel.Association import (
|
|
15
|
+
GenericAssociationItem,
|
|
16
|
+
PortAssociationItem,
|
|
17
|
+
)
|
|
18
|
+
from pyVHDLModel.Concurrent import (
|
|
19
|
+
ComponentInstantiation,
|
|
20
|
+
ConcurrentConditionalSignalAssignment,
|
|
21
|
+
ConcurrentSimpleSignalAssignment,
|
|
22
|
+
EntityInstantiation,
|
|
23
|
+
)
|
|
24
|
+
from pyVHDLModel.Symbol import (
|
|
25
|
+
ArchitectureSymbol,
|
|
26
|
+
ComponentInstantiationSymbol,
|
|
27
|
+
EntityInstantiationSymbol,
|
|
28
|
+
SignalSymbol,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
from pyVHDLModelTreesitter._Association import parse_association_item
|
|
32
|
+
from pyVHDLModelTreesitter._Base import parse_waveform_element
|
|
33
|
+
from pyVHDLModelTreesitter._errors import NotImplementedWarning
|
|
34
|
+
from pyVHDLModelTreesitter._Name import parse_name
|
|
35
|
+
from pyVHDLModelTreesitter.treesitter import (
|
|
36
|
+
get_node,
|
|
37
|
+
get_node_text,
|
|
38
|
+
get_nodes,
|
|
39
|
+
inject_node,
|
|
40
|
+
sort_into_text_order,
|
|
41
|
+
)
|
|
42
|
+
from pyVHDLModelTreesitter.treesitter.query import (
|
|
43
|
+
ComponentInstantiationStatement,
|
|
44
|
+
)
|
|
45
|
+
from pyVHDLModelTreesitter.treesitter.query import (
|
|
46
|
+
ConcurrentConditionalSignalAssignment as ConcurrentConditionalSignalAssignmentQuery,
|
|
47
|
+
)
|
|
48
|
+
from pyVHDLModelTreesitter.treesitter.query import (
|
|
49
|
+
ConcurrentSimpleSignalAssignment as ConcurrentSimpleSignalAssignmentQuery,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
if TYPE_CHECKING:
|
|
53
|
+
import tree_sitter
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _parse_common_instantiation(
|
|
57
|
+
node: tree_sitter.Node,
|
|
58
|
+
captures: dict[str, list[tree_sitter.Node]],
|
|
59
|
+
) -> tuple[str, list[GenericAssociationItem], list[PortAssociationItem]]:
|
|
60
|
+
label_node = get_node(node, captures, "label")
|
|
61
|
+
label = get_node_text(label_node)
|
|
62
|
+
generic_associations = sort_into_text_order(
|
|
63
|
+
generic_association
|
|
64
|
+
for association_node in get_nodes(node, captures, "generics", optional=True)
|
|
65
|
+
if (
|
|
66
|
+
generic_association := parse_association_item(
|
|
67
|
+
GenericAssociationItem,
|
|
68
|
+
association_node,
|
|
69
|
+
)
|
|
70
|
+
)
|
|
71
|
+
is not None
|
|
72
|
+
)
|
|
73
|
+
port_associations = sort_into_text_order(
|
|
74
|
+
port_association
|
|
75
|
+
for association_node in get_nodes(node, captures, "ports", optional=True)
|
|
76
|
+
if (
|
|
77
|
+
port_association := parse_association_item(
|
|
78
|
+
PortAssociationItem,
|
|
79
|
+
association_node,
|
|
80
|
+
)
|
|
81
|
+
)
|
|
82
|
+
is not None
|
|
83
|
+
)
|
|
84
|
+
return label, generic_associations, port_associations
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def parse_component_instantiation(
|
|
88
|
+
node: tree_sitter.Node,
|
|
89
|
+
) -> ComponentInstantiation | None:
|
|
90
|
+
"""Create a `ComponentInstantiation` from a treesitter node."""
|
|
91
|
+
captures = ComponentInstantiationStatement.capture(node)
|
|
92
|
+
label, generic_associations, port_associations = _parse_common_instantiation(
|
|
93
|
+
node,
|
|
94
|
+
captures,
|
|
95
|
+
)
|
|
96
|
+
name_node = get_node(node, captures, "component_name")
|
|
97
|
+
component_symbol = ComponentInstantiationSymbol(
|
|
98
|
+
parse_name(get_node_text(name_node)),
|
|
99
|
+
)
|
|
100
|
+
return inject_node(
|
|
101
|
+
ComponentInstantiation(
|
|
102
|
+
label=label,
|
|
103
|
+
componentSymbol=component_symbol,
|
|
104
|
+
genericAssociationItems=generic_associations,
|
|
105
|
+
portAssociationItems=port_associations,
|
|
106
|
+
),
|
|
107
|
+
node,
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def parse_concurrent_simple_signal_assignment(
|
|
112
|
+
node: tree_sitter.Node,
|
|
113
|
+
) -> ConcurrentSimpleSignalAssignment | None:
|
|
114
|
+
"""Create a `ConcurrentSimpleSignalAssignment` from a treesitter node."""
|
|
115
|
+
captures = ConcurrentSimpleSignalAssignmentQuery.capture(node)
|
|
116
|
+
label_node = get_node(node, captures, "label", optional=True)
|
|
117
|
+
label = get_node_text(label_node) if label_node is not None else None
|
|
118
|
+
target_node = get_node(node, captures, "lhs")
|
|
119
|
+
target = SignalSymbol(parse_name(get_node_text(target_node)))
|
|
120
|
+
waveform_node = get_node(node, captures, "rhs")
|
|
121
|
+
waveform = [
|
|
122
|
+
we
|
|
123
|
+
for child in waveform_node.children
|
|
124
|
+
if child.type == "waveform_element"
|
|
125
|
+
for we in [parse_waveform_element(child)]
|
|
126
|
+
if we is not None
|
|
127
|
+
]
|
|
128
|
+
# TODO: label is incorrectly `str` rather than `Nullable[str]`
|
|
129
|
+
# ty: ignore[invalid-argument-type]
|
|
130
|
+
return inject_node(ConcurrentSimpleSignalAssignment(label, target, waveform), node) # type: ignore[arg-type]
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def parse_concurrent_conditional_signal_assignment(
|
|
134
|
+
node: tree_sitter.Node,
|
|
135
|
+
) -> ConcurrentConditionalSignalAssignment | None:
|
|
136
|
+
"""Create a `ConcurrentConditionalSignalAssignment` from a treesitter node."""
|
|
137
|
+
captures = ConcurrentConditionalSignalAssignmentQuery.capture(node)
|
|
138
|
+
label_node = get_node(node, captures, "label", optional=True)
|
|
139
|
+
label = get_node_text(label_node) if label_node is not None else None
|
|
140
|
+
target_node = get_node(node, captures, "lhs")
|
|
141
|
+
target = SignalSymbol(parse_name(get_node_text(target_node)))
|
|
142
|
+
_rhs_node = get_node(node, captures, "rhs")
|
|
143
|
+
NotImplementedWarning.warn_incomplete_model(
|
|
144
|
+
ConcurrentConditionalSignalAssignment,
|
|
145
|
+
node,
|
|
146
|
+
)
|
|
147
|
+
return inject_node(
|
|
148
|
+
ConcurrentConditionalSignalAssignment(
|
|
149
|
+
# TODO: label is incorrectly `str` rather than `Nullable[str]`
|
|
150
|
+
# ty: ignore[invalid-argument-type]
|
|
151
|
+
label=label, # type: ignore[arg-type]
|
|
152
|
+
target=target,
|
|
153
|
+
conditionalWaveforms=[], # TODO: implement this
|
|
154
|
+
),
|
|
155
|
+
node,
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def parse_entity_instantiation(
|
|
160
|
+
node: tree_sitter.Node,
|
|
161
|
+
) -> EntityInstantiation | None:
|
|
162
|
+
"""Create an `EntityInstantiation` from a treesitter node."""
|
|
163
|
+
captures = ComponentInstantiationStatement.capture(node)
|
|
164
|
+
label, generic_associations, port_associations = _parse_common_instantiation(
|
|
165
|
+
node,
|
|
166
|
+
captures,
|
|
167
|
+
)
|
|
168
|
+
entity_str = ""
|
|
169
|
+
namespace_node = get_node(node, captures, "namespace", optional=True)
|
|
170
|
+
if namespace_node is not None:
|
|
171
|
+
entity_str = f"{get_node_text(namespace_node)}."
|
|
172
|
+
entity_node = get_node(node, captures, "entity")
|
|
173
|
+
entity_str += get_node_text(entity_node)
|
|
174
|
+
entity_symbol = EntityInstantiationSymbol(
|
|
175
|
+
parse_name(entity_str),
|
|
176
|
+
)
|
|
177
|
+
architecture_node = get_node(node, captures, "architecture", optional=True)
|
|
178
|
+
architecture_symbol = None
|
|
179
|
+
if architecture_node is not None:
|
|
180
|
+
architecture_symbol = ArchitectureSymbol(
|
|
181
|
+
parse_name(get_node_text(architecture_node)),
|
|
182
|
+
)
|
|
183
|
+
return inject_node(
|
|
184
|
+
EntityInstantiation(
|
|
185
|
+
label=label,
|
|
186
|
+
entitySymbol=entity_symbol,
|
|
187
|
+
architectureSymbol=architecture_symbol,
|
|
188
|
+
genericAssociationItems=generic_associations,
|
|
189
|
+
portAssociationItems=port_associations,
|
|
190
|
+
),
|
|
191
|
+
node,
|
|
192
|
+
)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""Classes related to `Design`."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import cast
|
|
6
|
+
|
|
7
|
+
from pyVHDLModel import Design as VHDLModel_Design
|
|
8
|
+
from pyVHDLModel import Library
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Design(VHDLModel_Design):
|
|
12
|
+
def GetLibrary( # ruff: ignore[invalid-function-name]
|
|
13
|
+
self,
|
|
14
|
+
libraryName: str, # ruff: ignore[invalid-argument-name]
|
|
15
|
+
) -> Library:
|
|
16
|
+
library = self.Libraries.get(libraryName)
|
|
17
|
+
if library is not None:
|
|
18
|
+
return cast("Library", library)
|
|
19
|
+
library = Library(
|
|
20
|
+
libraryName,
|
|
21
|
+
allowBlackbox=self._allowBlackbox,
|
|
22
|
+
)
|
|
23
|
+
self.AddLibrary(library)
|
|
24
|
+
return library
|