1. Pypy
  2. Untitled project
  3. pypy


pypy / pypy / translator / gensupp.py

Armin Rigo e349d42 

Niklaus Haldiman… 819156f 
Armin Rigo e349d42 

Samuele Pedroni 9b70493 
Niklaus Haldiman… 819156f 
Armin Rigo e349d42 

Christian Tismer b23fa9b 

Armin Rigo f0b3fa0 

Armin Rigo e349d42 

Armin Rigo dc94c0b 

Niklaus Haldiman… 819156f 
Christian Tismer b23fa9b 

Armin Rigo e349d42 
Christian Tismer b23fa9b 
Armin Rigo e349d42 

Some support for genxxx implementations of source generators.
Another name could be genEric, but well...

import sys

def uniquemodulename(name, SEEN={}):
    # never reuse the same module name within a Python session!
    i = 0
    while True:
        i += 1
        result = '%s_%d' % (name, i)
        if result not in SEEN:
            SEEN[result] = True
            return result

# a translation table suitable for str.translate() to remove
# non-C characters from an identifier
C_IDENTIFIER = ''.join([(('0' <= chr(i) <= '9' or
                          'a' <= chr(i) <= 'z' or
                          'A' <= chr(i) <= 'Z') and chr(i) or '_')
                        for i in range(256)])

# a name manager knows about all global and local names in the
# program and keeps them disjoint. It provides ways to generate
# shorter local names with and without wrapping prefixes,
# while always keeping all globals visible.

class NameManager(object):
    def __init__(self, global_prefix='', number_sep='_'):
        self.seennames = {}
        self.scope = 0
        self.scopelist = []
        self.global_prefix = global_prefix
        self.number_sep = number_sep

    def make_reserved_names(self, txt):
        """add names to list of known names. If one exists already,
        then we raise an exception. This function should be called
        before generating any new names."""
        for name in txt.split():
            if name in self.seennames:
                raise NameError, "%s has already been seen!"
            self.seennames[name] = 1

    def _ensure_unique(self, basename):
        n = self.seennames.get(basename, 0)
        self.seennames[basename] = n+1
        if n:
            return self._ensure_unique('%s_%d' % (basename, n))
        return basename

    def uniquename(self, basename, with_number=None, bare=False, lenmax=50):
        basename = basename[:lenmax].translate(C_IDENTIFIER)
        n = self.seennames.get(basename, 0)
        self.seennames[basename] = n+1
        if with_number is None:
            with_number = basename in ('v', 'w_')
        fmt = '%%s%s%%d' % self.number_sep
        if with_number and not basename[-1].isdigit():
            fmt = '%s%d'
        if n != 0 or with_number:
            basename = self._ensure_unique(fmt % (basename, n))
        if bare:
            return basename, self.global_prefix + basename
            return self.global_prefix + basename

    def localScope(self, parent=None):
        ret = _LocalScope(self, parent)
        while ret.scope >= len(self.scopelist):
        return ret

class _LocalScope(object):
    """track local names without hiding globals or nested locals"""
    def __init__(self, glob, parent):
        self.glob = glob
        if not parent:
            parent = glob
        self.parent = parent
        self.mapping = {}
        self.usednames = {}
        self.scope = parent.scope + 1

    def uniquename(self, basename):
        basename = basename.translate(C_IDENTIFIER)
        glob = self.glob
        p = self.usednames.get(basename, 0)
        self.usednames[basename] = p+1
        namesbyscope = glob.scopelist[self.scope]
        namelist = namesbyscope.setdefault(basename, [])
        if p == len(namelist):
        return namelist[p]

    def localname(self, name, wrapped=False):
        """modify and mangle local names"""
        if name in self.mapping:
            return self.mapping[name]
        scorepos = name.rfind("_")
        if name.startswith("v") and name[1:].isdigit():
            basename = ('v', 'w_') [wrapped]
        elif scorepos >= 0 and name[scorepos+1:].isdigit():
            basename = name[:scorepos]
            # for wrapped named things, prepend a w_
            # for other named things, prepend a l_.
            # XXX The latter is needed because tcc has a nasty parser bug that
            # produces errors if names co-incide with global typedefs,
            # if the type prefix is itself a typedef reference!
            # XXX report this bug to the tcc maintainer(s)
            # YYY drop this comment afterwards, but keep the code, it's better.
            basename = ("l_", "w_")[wrapped] + basename
            basename = name
        ret = self.uniquename(basename)
        self.mapping[name] = ret
        return ret