From 111fe055b2f0f3a0225d2553cf739572d691a14d Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Sat, 26 Jun 2021 13:48:09 +0200 Subject: More DOM improvements (#1806) * First try to handle names. * Reworked names. * Reworked range expressions. * Handle AttributeNames. * Added handling of file declaration and attribute declarations. * Improved error outputs. * Handle protected types. * Make black happy with ugly code. * Handle Null literal and File parameters. * File type and physical type. * Don't fail on reported syntax errors. Catch call errors into libghdl. * Improved Sanity checks for pyGHDL.dom. * Load sourcecode via Python and process in-memory. Fixed testcases. * Added package instantiations and packages with generics. * Added UseClause, AttributeSpecification and PhysicalTypes. * Improved pretty-printing. * Fixed AttributeName in subtype indication. * Get code position of IIR nodes. * Added DOMMixin into all derived classes. * Mark as not yet implemented. * Pinned pyVHDLModel version to v0.10.4. * Removed xfail in LSP test. Bumped requirement of pyVHDLModel to v0.10.4. Fixed some Codacy issues. (cherry picked from commit f64e7ed7c3d69cbf84cd60db8e9b085e90b846cb) --- testsuite/pyunit/Current.vhdl | 42 +++++++++++++++++++++-- testsuite/pyunit/dom/Expressions.py | 61 +++++++++++++++++++++++++--------- testsuite/pyunit/dom/Literals.py | 2 +- testsuite/pyunit/dom/Sanity.py | 15 ++++++--- testsuite/pyunit/lsp/LanguageServer.py | 1 + 5 files changed, 98 insertions(+), 23 deletions(-) (limited to 'testsuite') diff --git a/testsuite/pyunit/Current.vhdl b/testsuite/pyunit/Current.vhdl index ff03e1d04..a017b9f46 100644 --- a/testsuite/pyunit/Current.vhdl +++ b/testsuite/pyunit/Current.vhdl @@ -21,7 +21,8 @@ end entity entity_1; architecture behav of entity_1 is constant MAX : positive := -25; signal rst : std_logic := foo('U'); --- signal vec : bit_vector(pack.input'bar'range); + signal vec : bit_vector(pack(3 to 2).signaal'range'value); + signal copy : input'subtype; type newInt is range -4 to 3; type newFp is range 4.3 downto -3.9; @@ -34,9 +35,10 @@ architecture behav of entity_1 is end record; type enum is (e1, e2, e3); type acc is access bar; + type fil is file of string; subtype uint8 is integer range 0 to 255; --- file f : text; + file f : text; function func (a : integer; b : boolean) return bit is begin @@ -50,6 +52,27 @@ architecture behav of entity_1 is end procedure; + type prot is protected + function meth(a : int) return bit; + end protected; + + type prot is protected body + variable var : positive; + constant const : boolean; + + function meth(a : int) return bit is + begin + + end function; + end protected body; + + package pack_inst is new generic_pack + generic map ( + BITS => 32 + ); + + attribute att : boolean; + alias bar is boolean; begin process(Clock) @@ -65,7 +88,14 @@ begin end architecture behav; package package_1 is + generic ( + BITS : positive + ); + + use lib.pack.all; + constant ghdl : float := (3, 5, 0 to 2 => 5, 3 => 4, name => 10); -- 2.3; + attribute fixed of ghdl : constant is true; component comp is port ( @@ -76,4 +106,12 @@ end package; package body package_1 is constant ghdl : float := (1); -- => 2, 4 => 5, others => 10); -- .5; + + type CAPACITY is range 0 to 1E5 units + pF; + nF = 1000 pF; + uF = 1000 nF; + mF = 1000 uF; + F = 1000 mF; + end units; end package body; diff --git a/testsuite/pyunit/dom/Expressions.py b/testsuite/pyunit/dom/Expressions.py index f9c066f52..4de36a2b2 100644 --- a/testsuite/pyunit/dom/Expressions.py +++ b/testsuite/pyunit/dom/Expressions.py @@ -30,17 +30,20 @@ # # SPDX-License-Identifier: GPL-2.0-or-later # ============================================================================ +import ctypes +from inspect import currentframe from pathlib import Path from textwrap import dedent from unittest import TestCase -from pyGHDL.dom.DesignUnit import Package from pyGHDL.dom import Expression from pyGHDL.dom.NonStandard import Design, Document +from pyGHDL.dom.DesignUnit import Package from pyGHDL.dom.Symbol import SimpleObjectOrFunctionCallSymbol from pyGHDL.dom.Object import Constant -from pyGHDL.dom.Expression import InverseExpression +from pyGHDL.dom.Expression import InverseExpression, AbsoluteExpression + if __name__ == "__main__": print("ERROR: you called a testcase declaration file as an executable module.") @@ -50,34 +53,60 @@ if __name__ == "__main__": class Expressions(TestCase): _root = Path(__file__).resolve().parent.parent - - def test_NotExpression(self): - self._filename: Path = self._root / "{className}.vhdl".format( - className=self.__class__.__name__ - ) - - sourceCode = dedent( + _design = Design() + _packageTemplate = dedent( """\ package package_1 is - constant c0 : boolean := not true; + {code} end package; """ ) - with self._filename.open(mode="w", encoding="utf-8") as file: - file.write(sourceCode) + def parse(self, filename: Path, code: str) -> Expression: + sourceCode = self._packageTemplate.format(code=code) - design = Design() - document = Document(self._filename) - design.Documents.append(document) + document = Document(filename, sourceCode) + self._design.Documents.append(document) - package: Package = design.Documents[0].Packages[0] + # Traverse already to default value expression + package: Package = document.Packages[0] item: Constant = package.DeclaredItems[0] default: Expression = item.DefaultExpression + + return default + + def test_NotExpression(self): + filename: Path = self._root / "{className}_{funcName}.vhdl".format( + className=self.__class__.__name__, funcName= currentframe().f_code.co_name[5:] + ) + + # Define test data + constantDeclartion = "constant c0 : boolean := not true;" + + # Parse in-memory + default: Expression = self.parse(filename, constantDeclartion) + + # Start checks self.assertTrue(isinstance(default, InverseExpression)) self.assertTrue(isinstance(default.Operand, SimpleObjectOrFunctionCallSymbol)) self.assertTrue(default.Operand.SymbolName == "true") + # def test_AbsExpression(self): + # filename: Path = self._root / "{className}_{funcName}.vhdl".format( + # className=self.__class__.__name__, funcName= currentframe().f_code.co_name[5:] + # ) + # + # # Define test data + # constantDeclartion = "constant c0 : integer := abs 3;" + # + # # Parse in-memory + # default: Expression = self.parse(filename, constantDeclartion) + # + # # Start checks + # self.assertTrue(isinstance(default, AbsoluteExpression)) + # self.assertTrue(isinstance(default.Operand, SimpleObjectOrFunctionCallSymbol)) + # self.assertTrue(default.Operand.SymbolName == "-3") + # def test_Aggregare(self): # self._filename: Path = self._root / "{className}.vhdl".format(className=self.__class__.__name__) # diff --git a/testsuite/pyunit/dom/Literals.py b/testsuite/pyunit/dom/Literals.py index ebd702f5e..a69481ef4 100644 --- a/testsuite/pyunit/dom/Literals.py +++ b/testsuite/pyunit/dom/Literals.py @@ -80,6 +80,6 @@ class Literals(TestCase): item: Constant = package.DeclaredItems[i] self.assertTrue(isinstance(item, Constant)) self.assertTrue(item.Name == "c{}".format(i)) - self.assertTrue(item.SubType.SymbolName == "integer") + self.assertTrue(str(item.SubType.SymbolName) == "integer") self.assertTrue(isinstance(item.DefaultExpression, IntegerLiteral)) self.assertTrue(item.DefaultExpression.Value == expected[i]) diff --git a/testsuite/pyunit/dom/Sanity.py b/testsuite/pyunit/dom/Sanity.py index 10258c38c..dc415446b 100644 --- a/testsuite/pyunit/dom/Sanity.py +++ b/testsuite/pyunit/dom/Sanity.py @@ -30,11 +30,13 @@ # # SPDX-License-Identifier: GPL-2.0-or-later # ============================================================================ -from sys import executable -from subprocess import check_call, STDOUT from pathlib import Path +from subprocess import check_call, STDOUT + from pytest import mark +from pyGHDL.dom.NonStandard import Design, Document + if __name__ == "__main__": print("ERROR: you called a testcase declaration file as an executable module.") print("Use: 'python -m unitest '") @@ -44,7 +46,12 @@ _TESTSUITE_ROOT = Path(__file__).parent.parent.parent.resolve() _GHDL_ROOT = _TESTSUITE_ROOT.parent +design = Design() + @mark.xfail -@mark.parametrize("file", [str(f) for f in _TESTSUITE_ROOT.glob("sanity/**/*.vhdl")]) +@mark.parametrize("file", [str(f.relative_to(_TESTSUITE_ROOT)) for f in _TESTSUITE_ROOT.glob("sanity/**/*.vhdl")]) def test_AllVHDLSources(file): - check_call([executable, _GHDL_ROOT / "pyGHDL/cli/DOM.py", file], stderr=STDOUT) + check_call(["python", _GHDL_ROOT / "pyGHDL/cli/DOM.py", file], stderr=STDOUT) + +# document = Document(Path(file)) +# design.Documents.append(document) diff --git a/testsuite/pyunit/lsp/LanguageServer.py b/testsuite/pyunit/lsp/LanguageServer.py index a406dce91..51e26ca7d 100644 --- a/testsuite/pyunit/lsp/LanguageServer.py +++ b/testsuite/pyunit/lsp/LanguageServer.py @@ -8,6 +8,7 @@ from subprocess import run as subprocess_run, PIPE from typing import Optional from unittest import TestCase + from pyGHDL.lsp.lsp import LanguageProtocolServer, LSPConn is_windows = os.name == "nt" -- cgit v1.2.3