X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb/blobdiff_plain/e7abc7ea1c83b671db65884d7f8e4b8c57762083..HEAD:/math/mpgen diff --git a/math/mpgen b/math/mpgen index 7d11bfda..c7dbf889 100644 --- a/math/mpgen +++ b/math/mpgen @@ -28,10 +28,9 @@ from __future__ import with_statement import re as RX import optparse as OP +import sys as SYS; stdout = SYS.stdout import types as TY -from sys import stdout - ###-------------------------------------------------------------------------- ### Random utilities. @@ -65,6 +64,22 @@ def fix_name(name): """Replace non-alphanumeric characters in NAME with underscores.""" return R_IDBAD.sub('_', name) +if SYS.version_info >= (3,): + def func_name(func): return func.__name__ + xrange = range + long = int +else: + def func_name(func): return func.func_name + +def with_metaclass(meta, *supers): + return meta('#' % meta.__name__, + supers or (object,), dict()) + +def load(file, mod): + with open(file) as f: text = f.read() + code = compile(text, file, 'exec') + exec(code, mod) + ###-------------------------------------------------------------------------- ### Determining the appropriate types. @@ -83,7 +98,7 @@ class IntClass (type): except AttributeError: pass return c -class BasicIntType (object): +class BasicIntType (with_metaclass(IntClass)): """ A base class for integer-type classes, providing defaults and protocol. @@ -195,7 +210,7 @@ class TypeChoice (object): ## Load the captured type information. me.ti = TY.ModuleType('typeinfo') - execfile(opts.typeinfo, me.ti.__dict__) + load(opts.typeinfo, me.ti.__dict__) ## Build a map of the available types. tymap = {} @@ -226,14 +241,14 @@ class TypeChoice (object): ## Make sure we've not ended up somewhere really silly. if mpwbits < 16: - raise Exception, "`mpw' type is too small: your C environment is weird" + raise Exception("`mpw' type is too small: your C environment is weird") ## Now figure out suitable types for `mpw' and `mpd'. def find_type(bits, what): for ty in byrank: if ty.bits >= bits: return ty - raise Exception, \ - "failed to find suitable %d-bit type, for %s" % (bits, what) + raise Exception \ + ("failed to find suitable %d-bit type, for %s" % (bits, what)) ## Store our decisions. me.mpwbits = mpwbits @@ -327,7 +342,7 @@ def defmode(func): arguments from the command and are expected to write their output to stdout. """ - name = func.func_name + name = func_name(func) if name.startswith('m_'): name = name[2:] MODEMAP[name] = func return func @@ -483,7 +498,7 @@ class GroupTableClass (type): else: MODEMAP[c.mode] = c.run return c -class GroupTable (object): +class GroupTable (with_metaclass(GroupTableClass)): """ Base class for group tables objects. @@ -568,8 +583,6 @@ class GroupTable (object): ## _slotmap A dictionary mapping slot names to their ## descriptions. - __metaclass__ = GroupTableClass - ## Default values. keyword = 'group' slots = [] @@ -644,7 +657,7 @@ class GroupTable (object): if ff[0] == 'alias': ## An alias. Just remember this. - if len(ff) != 3: raise Exception, "wrong number of alias arguments" + if len(ff) != 3: raise Exception("wrong number of alias arguments") me._flush() me._names.append((ff[1], ff[2])) @@ -654,7 +667,7 @@ class GroupTable (object): ## Check the headline syntax. Headline slots may be set here, or ## later by name. if len(ff) < 2 or len(ff) > 2 + len(me._headslots): - raise Exception, "bad number of headline arguments" + raise Exception("bad number of headline arguments") ## Flush out the previous stanza. me._flush() @@ -670,14 +683,14 @@ class GroupTable (object): elif ff[0] in me._slotmap: ## A slot assignment. Get the slot to store a value. if me.st.name is None: - raise Exception, "no group currently being defined" + raise Exception("no group currently being defined") if len(ff) != 2: - raise Exception, "bad number of values for slot `%s'" % ff[0] + raise Exception("bad number of values for slot `%s'" % ff[0]) me._slotmap[ff[0]].set(me.st, ff[1]) else: ## Something incomprehensible. - raise Exception, "unknown keyword `%s'" % ff[0] + raise Exception("unknown keyword `%s'" % ff[0]) ## End of the input. Write out the final stanza. me._flush() @@ -687,7 +700,7 @@ class GroupTable (object): stdout.write("\nconst %s %s[] = {\n" % (me.entry_t, me.tabname)) for a, n in me._names: if n not in me._defs: - raise Exception, "alias `%s' refers to unknown group `%s'" % (a, n) + raise Exception("alias `%s' refers to unknown group `%s'" % (a, n)) stdout.write(' { "%s", &c_%s },\n' % (a, fix_name(n))) stdout.write(" { 0, 0 }\n};\n\n") @@ -747,7 +760,7 @@ class BaseSlot (object): Store a VALUE for the slot. """ if me._allowp and not me._allowp(st, value): - raise Exception, "slot `%s' not allowed here" % me.name + raise Exception("slot `%s' not allowed here" % me.name) st.d[me] = value def setup(me, st): @@ -755,7 +768,7 @@ class BaseSlot (object): Prepare the slot for output, checking its value and so on. """ if me not in st.d and (not me._omitp or not me._omitp(st)): - raise Exception, "missing slot `%s'" % me.name + raise Exception("missing slot `%s'" % me.name) class EnumSlot (BaseSlot): """ @@ -781,7 +794,7 @@ class EnumSlot (BaseSlot): Check that the VALUE is one of the ones we know. """ if value not in me._values: - raise Exception, "invalid %s value `%s'" % (me.name, value) + raise Exception("invalid %s value `%s'" % (me.name, value)) super(EnumSlot, me).set(st, value) def write(me, st):