[pypy-svn] r8630 - pypy/dist/pypy/translator
tismer at codespeak.net
tismer at codespeak.net
Thu Jan 27 11:52:25 CET 2005
Author: tismer
Date: Thu Jan 27 11:52:25 2005
New Revision: 8630
Modified:
pypy/dist/pypy/translator/geninterplevel.py
Log:
adapted geninterplevel to the additional local
names preserving feature. Also made it so that
function names are kept. The functions just
appear with a different name in the globals.
Still not ready to create exceptions.
Modified: pypy/dist/pypy/translator/geninterplevel.py
==============================================================================
--- pypy/dist/pypy/translator/geninterplevel.py (original)
+++ pypy/dist/pypy/translator/geninterplevel.py Thu Jan 27 11:52:25 2005
@@ -142,6 +142,19 @@
else:
localnames[v.name] = ret = "v%d" % len(localnames)
return ret
+ scorepos = n.rfind("_")
+ print n, scorepos
+ if scorepos >= 0 and n[scorepos+1:].isdigit():
+ name = n[:scorepos]
+ ret = localnames.get(v.name)
+ if not ret:
+ if wrapped:
+ fmt = "w_%s_%d"
+ else:
+ fmt = "%s_%d"
+ localnames[v.name] = ret = fmt % (name, len(localnames))
+ print ret
+ return ret
elif isinstance(v, Constant):
return self.nameof(v.value,
debug=('Constant in the graph of', self.currentfunc))
@@ -164,7 +177,7 @@
fmt = ("_tup = space.newtuple([%(args)s])\n"
"%(res)s = space.call(%(func)s, _tup)")
# see if we can optimize for a fast call.
- # we justdo the very simple ones.
+ # we just do the very simple ones.
if self.use_fast_call and (isinstance(v, Constant)
and exv.startswith('gfunc_')):
func = v.value
@@ -276,6 +289,15 @@
else:
return self.uniquename('%s_%d' % (basename, n))
+ def uniquelocalname(self, basename, seennames):
+ basename = basename.translate(C_IDENTIFIER)
+ n = seennames.get(basename, 0)
+ seennames[basename] = n+1
+ if n == 0:
+ return basename
+ else:
+ return self.uniquelocalname('%s_%d' % (basename, n), seennames)
+
def nameof_object(self, value):
if type(value) is not object:
#raise Exception, "nameof(%r) in %r" % (value, self.currentfunc)
@@ -302,7 +324,9 @@
if value >= 0:
name = 'gi_%d' % value
else:
- name = 'gim_%d' % abs(value)
+ # make sure that the type ident is completely described by
+ # the prefixbefore the initial '_' for easy postprocessing
+ name = 'gi_minus_%d' % abs(value)
name = self.uniquename(name)
self.initcode.append('m.%s = space.newint(%d)' % (name, value))
return name
@@ -319,7 +343,9 @@
if value >= 0:
name = 'glong_%s' % s
else:
- name = 'glongm_%d' % abs(value)
+ # mae sure that the type ident is completely described by
+ # the prefix before the initial '_'
+ name = 'glong_minus_%d' % abs(value)
name = self.uniquename(name)
self.initcode.append('m.%s = space.wrap(%s) # XXX implement long!' % (name, s))
return name
@@ -425,10 +451,15 @@
content.sort()
for key, value in content:
if self.should_translate_attr(instance, key):
- yield 'space.setattr(%s, %s, %s)' % (
- name, self.nameof(key), self.nameof(value))
+ try:
+ yield 'space.setattr(%s, %s, %s)' % (
+ name, self.nameof(key), self.nameof(value))
+ except:
+ print >>sys.stderr, "Problem while generating %s of %r" % (
+ name, instance)
+ raise
if isinstance(instance, Exception):
- # specialcase for exception instances: wrap them directly
+ # special-case for exception instances: wrap them directly
self.initcode.append('_ins = %s()\n'
'm.%s = space.wrap(_ins)' % (
instance.__class__.__name__, name))
@@ -746,6 +777,21 @@
pass # self.initcode.append('# REGISTER_GLOBAL(%s)' % (name,))
del g[:]
+
+ def render_docstr(self, func, indent_str, q='"""', redo=True):
+ doc = func.__doc__
+ if doc is None:
+ return []
+ doc2 = ""
+ if q in doc and redo:
+ doc2 = self.render_docstr(func, indent_str, "'''", False)
+ doc = indent_str + q + doc.replace(q, "\\"+q) + q
+ if not redo:
+ return doc # recursion case
+ doc = (doc, doc2)[len(doc2) < len(doc)]
+ assert func.__doc__ == eval(doc, {}), "check geninterplevel!!"
+ return [line for line in doc.split('\n')]
+
def gen_rpyfunction(self, func):
f = self.f
@@ -764,6 +810,7 @@
self.gen_global_declarations()
# print header
+ doc_lines = self.render_docstr(func, " ")
cname = self.nameof(func)
assert cname.startswith('gfunc_')
f_name = 'f_' + cname[6:]
@@ -794,13 +841,15 @@
fast_set = dict(zip(fast_args, fast_args))
# create function declaration
- name = func.__name__
+ name = self.trans_funcname(func.__name__) # for <lambda>
argstr = ", ".join(fast_args)
fast_function_header = ('def %s(space, %s):'
- % (fast_name, argstr))
+ % (name, argstr))
- print >> f, 'def %s(space, *args_w):' % (f_name,)
- kwlist = ['"%s"' % name for name in
+ print >> f, 'def %s(space, *args_w):' % (name,)
+ for line in doc_lines:
+ print >> f, line
+ kwlist = ['"%s"' % var for var in
func.func_code.co_varnames[:func.func_code.co_argcount]]
print >> f, ' kwlist = [%s]' % (', '.join(kwlist),)
@@ -825,7 +874,7 @@
print >> f, ' defaults_w = (%s)' % tupstr(name_of_defaults)
theargs = [arg for arg in fast_args if arg != varname]
- txt = ('from pypy.translator.genrpy import PyArg_ParseMini\n'
+ txt = ('from pypy.translator.geninterplevel import PyArg_ParseMini\n'
'm.PyArg_ParseMini = PyArg_ParseMini\n'
'from pypy.interpreter.error import OperationError\n'
'm.OperationError = OperationError')
@@ -839,9 +888,12 @@
txt = ' PyArg_ParseMini(space, funcname, %d, %d, _args_w, defaults_w)'
print >>f, txt % (min_number_of_args, len(positional_args))
print >> f, ' return %s(space, %s)' % (fast_name, ', '.join(fast_args))
+ print >> f, '%s = globals().pop("%s")' % (f_name, name)
print >> f
print >> f, fast_function_header
+ for line in doc_lines:
+ print >> f, line
fast_locals = [arg for arg in localnames if arg not in fast_set]
if fast_locals:
@@ -855,6 +907,7 @@
# print the body
for line in body:
print >> f, line
+ print >> f, '%s = globals().pop("%s")' % (fast_name, name)
print >> f
# print the PyMethodDef
@@ -1044,6 +1097,26 @@
def somefunc(arg):
pass
+# XXX problem with local functions:
+def randint(low, high, seed = 1234567): # really not a real random
+ return (seed % (high-low)) + low
+
+def small_loop():
+ ''' this is a test for small loops.
+ How would we generate small blocks which call
+ each other? Hey, and """ is a doc string test """
+ '''
+ #from random import randint
+ # does not work. flowspace really complains on random.
+ # XXX we also seem to have problems with local functions
+ #def randint(low, high, seed = 1234567): # really not a real random
+ # return (seed % (high-low)) + low
+
+ for i in range(10000):
+ r = randint(0, 10000)
+ if r > 9000:
+ return r
+
def f(a,b):
## print "start"
a = []
@@ -1066,6 +1139,10 @@
class TestClass:pass
def ff(a, b, c=3,*rest):
+ """ this is
+ some
+ docstring
+"""
try:
try:
if rest:
@@ -1147,11 +1224,17 @@
res2 = struct.unpack('f', struct.pack('f',1.23))
return res1, res2
+def test_exceptions():
+ from pypy.appspace import _exceptions
+ _exceptions.Exception()
+ #return [thing for thing in _exceptions.__dict__.values()]
+
def all_entries():
res = [func() for func in entry_points[:-1]]
return res
-entry_points = (lambda: f(2, 3),
+entry_points = (small_loop,
+ lambda: f(2, 3),
lambda: ff(2, 3, 5),
fff,
lambda: app_str_decode__String_ANY_ANY("hugo"),
@@ -1161,7 +1244,8 @@
test_iter,
test_strutil,
test_struct,
- all_entries)
+ test_exceptions,
+ all_entries)
entry_point = entry_points[-2]
if __name__ == "__main__":
More information about the Pypy-commit
mailing list