Merge pull request #4671 from YosysHQ/emil/const-deref-pyosys

py_wrap: implement nested class definitions
This commit is contained in:
Emil J 2024-10-18 11:46:12 +02:00 committed by GitHub
commit 799497ebba
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 35 additions and 31 deletions

View File

@ -53,15 +53,9 @@ namespace RTLIL
CONST_FLAG_NONE = 0, CONST_FLAG_NONE = 0,
CONST_FLAG_STRING = 1, CONST_FLAG_STRING = 1,
CONST_FLAG_SIGNED = 2, // only used for parameters CONST_FLAG_SIGNED = 2, // only used for parameters
CONST_FLAG_REAL = 4, // only used for parameters CONST_FLAG_REAL = 4 // only used for parameters
}; };
// // Union discriminator. Values are exclusive
// enum ConstRepr : unsigned char {
// CONST_REPR_BITS = 1,
// CONST_REPR_STRING = 2,
// };
struct Const; struct Const;
struct AttrObject; struct AttrObject;
struct Selection; struct Selection;
@ -666,7 +660,7 @@ namespace RTLIL
struct RTLIL::Const struct RTLIL::Const
{ {
short flags; short int flags;
private: private:
friend class KernelRtlilTest; friend class KernelRtlilTest;
FRIEND_TEST(KernelRtlilTest, ConstStr); FRIEND_TEST(KernelRtlilTest, ConstStr);

View File

@ -1958,7 +1958,10 @@ def assure_length(text, length, left = False):
if left: if left:
return text + " "*(length - len(text)) return text + " "*(length - len(text))
return " "*(length - len(text)) + text return " "*(length - len(text)) + text
def nesting_delta(s):
return s.count("{") - s.count("}")
def parse_header(source): def parse_header(source):
debug("Parsing " + source.name + ".pyh",1) debug("Parsing " + source.name + ".pyh",1)
source_file = open(source.name + ".pyh", "r") source_file = open(source.name + ".pyh", "r")
@ -1976,12 +1979,13 @@ def parse_header(source):
i = 0 i = 0
namespaces = [] namespaces = []
class_ = None classes = []
private_segment = False private_segment = False
while i < len(source_text): while i < len(source_text):
line = source_text[i].replace("YOSYS_NAMESPACE_BEGIN", " namespace YOSYS_NAMESPACE{").replace("YOSYS_NAMESPACE_END"," }") line = source_text[i].replace("YOSYS_NAMESPACE_BEGIN", " namespace YOSYS_NAMESPACE{").replace("YOSYS_NAMESPACE_END"," }")
ugly_line = unpretty_string(line) ugly_line = unpretty_string(line)
debug(f"READ:>> {line}", 2)
# for anonymous unions, ignore union enclosure by skipping start line and replacing end line with new line # for anonymous unions, ignore union enclosure by skipping start line and replacing end line with new line
if 'union {' in line: if 'union {' in line:
@ -2004,15 +2008,15 @@ def parse_header(source):
continue continue
if len(namespaces) != 0: if len(namespaces) != 0:
namespaces[-1] = (namespaces[-1][0], namespaces[-1][1] + ugly_line.count("{") - ugly_line.count("}")) namespaces[-1] = (namespaces[-1][0], namespaces[-1][1] + nesting_delta(ugly_line))
if namespaces[-1][1] == 0: if namespaces[-1][1] == 0:
debug("-----END NAMESPACE " + concat_namespace(namespaces) + "-----",3) debug("-----END NAMESPACE " + concat_namespace(namespaces) + "-----",3)
del namespaces[-1] namespaces.pop()
i += 1 i += 1
continue continue
if class_ == None and (str.startswith(ugly_line, "struct ") or str.startswith(ugly_line, "class")) and ugly_line.count(";") == 0: if (str.startswith(ugly_line, "struct ") or str.startswith(ugly_line, "class")) and ugly_line.count(";") == 0:
# Opening a record declaration which isn't a forward declaration
struct_name = ugly_line.split(" ")[1].split("::")[-1] struct_name = ugly_line.split(" ")[1].split("::")[-1]
impl_namespaces = ugly_line.split(" ")[1].split("::")[:-1] impl_namespaces = ugly_line.split(" ")[1].split("::")[:-1]
complete_namespace = concat_namespace(namespaces) complete_namespace = concat_namespace(namespaces)
@ -2030,25 +2034,30 @@ def parse_header(source):
debug("\t " + struct_name + " is derived from " + base_class_name,2) debug("\t " + struct_name + " is derived from " + base_class_name,2)
base_class = class_by_name(base_class_name) base_class = class_by_name(base_class_name)
class_ = (class_by_name(struct_name), ugly_line.count("{"))#calc_ident(line)) c = (class_by_name(struct_name), ugly_line.count("{"))#calc_ident(line))
debug(f"switch to {struct_name} in namespace {namespaces}", 2)
if struct_name in classnames: if struct_name in classnames:
class_[0].namespace = complete_namespace c[0].namespace = complete_namespace
class_[0].base_class = base_class c[0].base_class = base_class
classes.append(c)
i += 1 i += 1
continue continue
if class_ != None: if len(classes):
class_ = (class_[0], class_[1] + ugly_line.count("{") - ugly_line.count("}")) c = (classes[-1][0], classes[-1][1] + nesting_delta(ugly_line))
if class_[1] == 0: classes[-1] = c
if class_[0] == None: if c[1] == 0:
if c[0] == None:
debug("\tExiting unknown class", 3) debug("\tExiting unknown class", 3)
else: else:
debug("\tExiting class " + class_[0].name, 3) debug("\tExiting class " + c[0].name, 3)
class_ = None classes.pop()
private_segment = False private_segment = False
i += 1 i += 1
continue continue
class_ = classes[-1] if classes else None
if class_ != None and (line.find("private:") != -1 or line.find("protected:") != -1): if class_ != None and (line.find("private:") != -1 or line.find("protected:") != -1):
private_segment = True private_segment = True
i += 1 i += 1
@ -2156,18 +2165,19 @@ def parse_header(source):
line = source_text[i].replace("YOSYS_NAMESPACE_BEGIN", " namespace YOSYS_NAMESPACE{").replace("YOSYS_NAMESPACE_END"," }") line = source_text[i].replace("YOSYS_NAMESPACE_BEGIN", " namespace YOSYS_NAMESPACE{").replace("YOSYS_NAMESPACE_END"," }")
ugly_line = unpretty_string(line) ugly_line = unpretty_string(line)
if len(namespaces) != 0: if len(namespaces) != 0:
namespaces[-1] = (namespaces[-1][0], namespaces[-1][1] + ugly_line.count("{") - ugly_line.count("}")) namespaces[-1] = (namespaces[-1][0], namespaces[-1][1] + nesting_delta(ugly_line))
if namespaces[-1][1] == 0: if namespaces[-1][1] == 0:
debug("-----END NAMESPACE " + concat_namespace(namespaces) + "-----",3) debug("-----END NAMESPACE " + concat_namespace(namespaces) + "-----",3)
del namespaces[-1] namespaces.pop()
if class_ != None: if len(classes):
class_ = (class_[0] , class_[1] + ugly_line.count("{") - ugly_line.count("}")) c = (classes[-1][0] , classes[-1][1] + nesting_delta(ugly_line))
if class_[1] == 0: classes[-1] = c
if class_[0] == None: if c[1] == 0:
if c[0] == None:
debug("\tExiting unknown class", 3) debug("\tExiting unknown class", 3)
else: else:
debug("\tExiting class " + class_[0].name, 3) debug("\tExiting class " + c[0].name, 3)
class_ = None classes.pop()
private_segment = False private_segment = False
i += 1 i += 1
else: else: