Skip to content

Commit 96bf7e1

Browse files
committed
Issue #85 ignoring function generics
1 parent bac58c5 commit 96bf7e1

2 files changed

Lines changed: 51 additions & 1 deletion

File tree

vunit/test/unit/test_vhdl_parser.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,26 @@ def test_parsing_entity_with_type_generic(self):
6868
self.assertEqual(entity.generics[0].identifier, 'type_g')
6969
self.assertEqual(entity.generics[0].subtype_indication.type_mark, 'integer')
7070

71+
def test_parsing_entity_with_function_generic(self):
72+
entity = self.parse_single_entity("""\
73+
entity ent is
74+
generic (
75+
function f(a : integer; b : integer) return integer;
76+
function_g : boolean;
77+
impure function if(a : integer; b : integer) return integer;
78+
procedure_g : boolean;
79+
procedure p(a : integer; b : integer)
80+
);
81+
end entity;
82+
""")
83+
self.assertEqual(entity.identifier, "ent")
84+
self.assertEqual(entity.ports, [])
85+
self.assertEqual(len(entity.generics), 2)
86+
self.assertEqual(entity.generics[0].identifier, 'function_g')
87+
self.assertEqual(entity.generics[0].subtype_indication.type_mark, 'boolean')
88+
self.assertEqual(entity.generics[1].identifier, 'procedure_g')
89+
self.assertEqual(entity.generics[1].subtype_indication.type_mark, 'boolean')
90+
7191
def test_getting_entities_from_design_file(self):
7292
design_file = VHDLDesignFile.parse("""
7393
entity entity1 is

vunit/vhdl_parser.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,8 +396,34 @@ def _find_port_clause(cls, code):
396396
code[match.start(): match.end() + closing_pos + match_semicolon.end()])
397397
return []
398398

399+
@staticmethod
400+
def _split_not_in_par(string, sep):
401+
"""
402+
Split string at all occurences of sep but not inside of a parenthesis
403+
"""
404+
result = []
405+
count = 0
406+
split = []
407+
for char in string:
408+
if char == '(':
409+
count += 1
410+
elif char == ')':
411+
count -= 1
412+
413+
if char == sep and count == 0:
414+
result.append("".join(split))
415+
split = []
416+
else:
417+
split.append(char)
418+
419+
if len(split) > 0:
420+
result.append("".join(split))
421+
422+
return result
423+
399424
_package_generic_re = re.compile(r"\s*package\s+", re.MULTILINE | re.IGNORECASE)
400425
_type_generic_re = re.compile(r"\s*type\s+", re.MULTILINE | re.IGNORECASE)
426+
_function_generic_re = re.compile(r"\s*(impure\s+)?(function|procedure)\s+", re.MULTILINE | re.IGNORECASE)
401427

402428
@classmethod
403429
def _parse_generic_clause(cls, code):
@@ -408,7 +434,7 @@ def _parse_generic_clause(cls, code):
408434
generic_list_string = code[code.find('(') + 1: code.rfind(')')]
409435

410436
# Split the interface elements
411-
interface_elements = generic_list_string.split(';')
437+
interface_elements = cls._split_not_in_par(generic_list_string, ';')
412438

413439
generic_list = []
414440
# Add interface elements to the generic list
@@ -422,6 +448,10 @@ def _parse_generic_clause(cls, code):
422448
# Ignore type generics
423449
continue
424450

451+
if cls._function_generic_re.match(interface_element) is not None:
452+
# Ignore function generics
453+
continue
454+
425455
generic_list.append(VHDLInterfaceElement.parse(interface_element))
426456

427457
return generic_list

0 commit comments

Comments
 (0)