1
0
mirror of https://github.com/myhdl/myhdl.git synced 2024-12-14 07:44:38 +08:00

Make enum type implementation more explicit

This commit is contained in:
Jan Decaluwe 2008-09-19 20:38:07 +02:00
parent 43f69f1e80
commit 5f3b1aa469
2 changed files with 25 additions and 23 deletions

View File

@ -38,27 +38,25 @@ class EnumItemType(object):
raise TypeError("class EnumItemType is only intended for type checking on subclasses") raise TypeError("class EnumItemType is only intended for type checking on subclasses")
def enum(*args, **kwargs): def enum(*names, **kwargs):
# args = args # args = args
encoding = kwargs.get('encoding', 'binary') encoding = kwargs.get('encoding', 'binary')
argdict = {}
codedict = {} codedict = {}
if encoding == "binary": if encoding == "binary":
nrbits = len(bin(len(args)-1)) nrbits = len(bin(len(names)-1))
elif encoding in ("one_hot", "one_cold"): elif encoding in ("one_hot", "one_cold"):
nrbits = len(args) nrbits = len(names)
else: else:
raise ValueError("Unsupported enum encoding: %s \n Supported encodings:" + \ raise ValueError("Unsupported enum encoding: %s \n Supported encodings:" + \
" 'binary', 'one_hot', 'one_cold'" % encoding) " 'binary', 'one_hot', 'one_cold'" % encoding)
i = 0 i = 0
for arg in args: for name in names:
if not isinstance(arg, StringType): if not isinstance(name, StringType):
raise TypeError() raise TypeError()
if codedict.has_key(arg): if codedict.has_key(name):
raise ValueError("enum literals should be unique") raise ValueError("enum literals should be unique")
argdict[i] = arg
if encoding == "binary": if encoding == "binary":
code = bin(i, nrbits) code = bin(i, nrbits)
elif encoding == "one_hot": elif encoding == "one_hot":
@ -67,19 +65,20 @@ def enum(*args, **kwargs):
code = bin(~(1<<i), nrbits) code = bin(~(1<<i), nrbits)
if len(code) > nrbits: if len(code) > nrbits:
code = code[-nrbits:] code = code[-nrbits:]
codedict[arg] = code codedict[name] = code
i += 1 i += 1
class EnumItem(EnumItemType): class EnumItem(EnumItemType):
def __init__(self, index, arg, type): def __init__(self, index, name, val, type):
self._index = index self._index = index
self._name = arg self._name = name
self._val = codedict[arg] self._val = val
self._nrbits = nrbits self._nrbits = type._nrbits
self._nritems = len(args) self._nritems = type._nritems
self._type = type self._type = type
def __repr__(self): def __repr__(self):
return argdict[self._index] return self._name
__str__ = __repr__
def __hex__(self): def __hex__(self):
return hex(int(self._val, 2)) return hex(int(self._val, 2))
__str__ = __repr__ __str__ = __repr__
@ -99,17 +98,20 @@ def enum(*args, **kwargs):
return self return self
class Enum(EnumType): class Enum(EnumType):
def __init__(self): def __init__(self, names, codedict, nrbits):
for index, slot in enumerate(args): self.__dict__['_names'] = names
self.__dict__[slot] = EnumItem(index, slot, self)
self.__dict__['_nrbits'] = nrbits self.__dict__['_nrbits'] = nrbits
self.__dict__['_declared'] = False self.__dict__['_declared'] = False
self.__dict__['_nritems'] = len(names)
for index, name in enumerate(names):
val = codedict[name]
self.__dict__[name] = EnumItem(index, name, val, self)
def __setattr__(self, attr, val): def __setattr__(self, attr, val):
raise AttributeError("Cannot assign to enum attributes") raise AttributeError("Cannot assign to enum attributes")
def __len__(self): def __len__(self):
return len(args) return len(self.names)
def __repr__(self): def __repr__(self):
return "<Enum: %s>" % ", ".join(args) return "<Enum: %s>" % ", ".join(names)
__str__ = __repr__ __str__ = __repr__
def _isDeclared(self): def _isDeclared(self):
return self._declared return self._declared
@ -123,12 +125,12 @@ def enum(*args, **kwargs):
self.__dict__['_name'] = typename self.__dict__['_name'] = typename
# XXX name generation # XXX name generation
str = "type %s is (\n " % typename str = "type %s is (\n " % typename
str += ",\n ".join(args) str += ",\n ".join(self._names)
str += "\n);" str += "\n);"
return str return str
return Enum() return Enum(names, codedict, nrbits)

View File

@ -800,7 +800,7 @@ class _AnalyzeVisitor(_ConversionMixin):
if len(node.args) < nr: if len(node.args) < nr:
self.raiseError(node, _error.FormatString, "not enough arguments") self.raiseError(node, _error.FormatString, "not enough arguments")
if len(node.args) > nr: if len(node.args) > nr:
self.raispoeError(node, _error.FormatString, "too many arguments") self.raiseError(node, _error.FormatString, "too many arguments")
self.visitChildNodes(node, *args) self.visitChildNodes(node, *args)
visitPrint = visitPrintnl visitPrint = visitPrintnl