From: Dmitry Selyutin Date: Wed, 20 Apr 2022 01:09:37 +0000 (+0000) Subject: sv_binutils: simplify array syntax X-Git-Tag: sv_maxu_works-initial~477 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=cbcde50a720aeba00bdb5f8e087cfbd532279f91;p=openpower-isa.git sv_binutils: simplify array syntax --- diff --git a/src/openpower/sv/sv_binutils.py b/src/openpower/sv/sv_binutils.py index c5ce0e11..1c0e4106 100644 --- a/src/openpower/sv/sv_binutils.py +++ b/src/openpower/sv/sv_binutils.py @@ -1,5 +1,6 @@ import abc as _abc import argparse as _argparse +import builtins as _builtins import dataclasses as _dataclasses import enum as _enum @@ -39,6 +40,10 @@ class CTypeMeta(type): return cls + def __getitem__(cls, size): + name = f"{cls.__name__}[{'' if size is Ellipsis else size}]" + return type(name, (Array,), {}, type=cls, size=size) + @property def c_typedef(cls): return cls.__typedef @@ -51,12 +56,45 @@ class CTypeMeta(type): yield f"{prefix}{cls.c_typedef} {name}{suffix}" +class ArrayMeta(CTypeMeta): + def __new__(metacls, name, bases, attrs, type, size): + cls = super().__new__(metacls, name, bases, attrs) + cls.__type = type + cls.__ellipsis = (size is Ellipsis) + cls.__size = 0 if cls.__ellipsis else size + + return cls + + def __len__(cls): + return cls.__size + + @property + def c_type(cls): + return cls.__type + + def c_decl(cls): + size = "" if cls.__ellipsis else f"{cls.__size}" + yield f"{cls.c_type.c_typedef}[{size}]" + + def c_var(cls, name, prefix="", suffix=""): + size = "" if cls.__ellipsis else f"{cls.__size}" + yield f"{prefix}{cls.c_type.c_typedef} {name}[{size}]{suffix}" + + class CType(metaclass=CTypeMeta): @_abc.abstractmethod def c_value(self, prefix="", suffix=""): yield from () +class Array(CType, tuple, metaclass=ArrayMeta, type=CType, size=0): + def c_value(self, prefix="", suffix=""): + yield f"{prefix}{{" + for (index, item) in enumerate(self): + yield from indent(item.c_value(prefix=f"[{index}] = ", suffix=",")) + yield f"}}{suffix}" + + class EnumMeta(_enum.EnumMeta, CTypeMeta): def __call__(metacls, name, entries, tag=None, **kwargs): if isinstance(entries, type) and issubclass(entries, _enum.Enum): @@ -168,42 +206,6 @@ class Size(Integer, typedef="size_t"): pass -class ArrayMeta(CTypeMeta): - def __new__(metacls, name, bases, attrs, type=CType, size=0): - cls = super().__new__(metacls, name, bases, attrs) - cls.__type = type - cls.__size = size - - return cls - - def __call__(cls, type, size): - name = f"{cls.__name__}[{type.__name__}]" - return ArrayMeta.__new__(ArrayMeta, name, (cls,), {}, type=type, size=size) - - def __len__(cls): - return cls.__size - - @property - def c_type(cls): - return cls.__type - - def c_decl(cls): - count = f"{cls.__size}" if cls.__size else "" - yield f"{cls.c_type.c_typedef}[{count}]" - - def c_var(cls, name, prefix="", suffix=""): - count = f"{cls.__size}" if cls.__size else "" - yield f"{prefix}{cls.c_type.c_typedef} {name}[{count}]{suffix}" - - -class Array(CType, tuple, metaclass=ArrayMeta): - def c_value(self, prefix="", suffix=""): - items = [] - for item in map(self.__class__.c_type, self): - items.extend(item.c_value()) - yield f"{prefix}{{{', '.join(items)}}}{suffix}" - - class Name(CType, str): def __repr__(self): escaped = self.replace("\"", "\\\"")