[pypy-svn] r18637 - in pypy/dist/pypy/translator/squeak: . test

bert at codespeak.net bert at codespeak.net
Sat Oct 15 17:17:58 CEST 2005


Author: bert
Date: Sat Oct 15 17:17:58 2005
New Revision: 18637

Added:
   pypy/dist/pypy/translator/squeak/test/test_oo.py   (contents, props changed)
Modified:
   pypy/dist/pypy/translator/squeak/gensqueak.py
Log:
generate classes in backend, placeholders for methods

Modified: pypy/dist/pypy/translator/squeak/gensqueak.py
==============================================================================
--- pypy/dist/pypy/translator/squeak/gensqueak.py	(original)
+++ pypy/dist/pypy/translator/squeak/gensqueak.py	Sat Oct 15 17:17:58 2005
@@ -9,6 +9,8 @@
 selectormap = {
     'setitem:with:': 'at:put:',
     'getitem:':      'at:',
+    'new':        'new',
+    'sameAs':        'yourself',
 }
 
 def camel_case(str):
@@ -80,6 +82,9 @@
 	}
         self.seennames = {}
         self.pendingfunctions = []
+        self.pendingclasses = []
+        self.pendingmethods = []
+	self.classes = [] 
 	self.methods = [] 
 
 	t = self.translator
@@ -98,9 +103,40 @@
 
 
     def gen_source(self, file):
-        while self.pendingfunctions:
-            func = self.pendingfunctions.pop()
-            self.gen_sqfunction(func, file)
+	while self.pendingfunctions or self.pendingclasses or self.pendingmethods:
+	    while self.pendingfunctions:
+		func = self.pendingfunctions.pop()
+		self.gen_sqfunction(func, file)
+	    while self.pendingclasses:
+		inst = self.pendingclasses.pop()
+		self.gen_sqclass(inst, file)
+	    while self.pendingmethods:
+		(inst, meth) = self.pendingmethods.pop()
+		self.gen_sqmethod(inst, meth, file)
+
+    def gen_sqclass(self, inst, f):
+	self.classes.append(inst)
+	print >> f, """%s subclass: #%s
+	instanceVariableNames: '%s'
+	classVariableNames: ''
+	poolDictionaries: ''
+	category: 'PyPy-Test'!
+	""" % (
+	    self.nameof_Instance(inst._superclass), 
+	    self.nameof_Instance(inst),
+	    ' '.join(inst._fields.iterkeys()))
+
+    def gen_sqmethod(self, inst, meth, f):
+	if (inst, meth) in self.methods:
+	    return
+	self.methods.append((inst, meth))
+	print >> f, "!%s methodsFor: 'methods' stamp: 'pypy 1/1/2000 00:00'!" % (
+            self.nameof_Instance(inst))
+	print >> f, "%s" % meth
+	print >> f, '	"XXX methods not generated yet"'
+	print >> f, "! !"
+	print >> f
+
 
     def gen_sqfunction(self, func, f):
 
@@ -114,17 +150,21 @@
 
 	def oper(op):
 	    args = [expr(arg) for arg in op.args]
-	    name = 'py_'+op.opname
-	    receiver = args[0]
-	    args = args[1:]
+	    if op.opname == "oosend":
+		name = args[0]
+		receiver = args[1]
+		args = args[2:]
+		self.note_meth(op.args[1].concretetype, name)
+	    else:
+		name = op.opname
+		receiver = args[0]
+		args = args[1:]
 	    argnames = ['with'] * len(args)
 	    if argnames:
 		argnames[0] = ''
 	    sel = selector(name, argnames)
-	    try:
-		sel = selectormap[sel]
-	    except KeyError:
-		pass
+	    if op.opname != "oosend":
+		sel = selectormap.get(sel, sel)
 	    return "%s := %s %s." % (expr(op.result), receiver, signature(sel, args))
 
 	def render_return(args):
@@ -140,26 +180,13 @@
 
 	def render_link(link):
 	    block = link.target
-#	    if len(block.exits) == 0:
-#		#short-cut return block
-#		for line in render_return(link.args):
-#		    yield line
-#		return
 	    if link.args:
-#		yield '| %s |' % repr(block.inputargs[0])
 		for i in range(len(link.args)):
 		    yield '%s := %s.' % (expr(block.inputargs[i]), expr(link.args[i]))
 	    for line in render_block(block):
 		yield line
 
 	def render_block(block):
-            #yield '"%s"' % repr(block)
-#	    temps = []
-#	    for op in block.operations:
-#		if isinstance(op.result, Variable):
-#		    temps.append(expr(op.result))
-#	    if temps:
-#		yield "| %s | " % ' '.join(temps)
 	    if loops.has_key(block):
 		if not loops[block]:
 		    yield '"skip1"'
@@ -206,7 +233,7 @@
 	loops = LoopFinder(start).loops
 
 	for line in render_block(start):
-	    print >> f, '    %s' % line
+	    print >> f, '	%s' % line
 	print >> f
 
     def nameof(self, obj):
@@ -214,28 +241,27 @@
         try:
             return self.sqnames[key]
         except KeyError:
-            if (type(obj).__module__ != '__builtin__' and
-                not isinstance(obj, type)):   # skip user-defined metaclasses
-                # assume it's a user defined thingy
-                name = self.nameof_instance(obj)
-            else:
-                for cls in type(obj).__mro__:
-                    meth = getattr(self,
-                                   'nameof_' + cls.__name__.replace(' ', ''),
-                                   None)
-                    if meth:
-                        break
-                else:
-		    types = ['nameof_'+t.__name__ for t in type(obj).mro()]
-                    raise Exception, "nameof(%r): no method %s" % (obj, types)
-                name = meth(obj)
+	    for cls in type(obj).__mro__:
+		meth = getattr(self,
+			       'nameof_' + cls.__name__.replace(' ', ''),
+			       None)
+		if meth:
+		    break
+	    else:
+		types = ['nameof_'+t.__name__ for t in type(obj).__mro__]
+		raise Exception, "nameof(%r): no method %s" % (obj, types)
+	    name = meth(obj)
             self.sqnames[key] = name
             return name
 
     def nameof_int(self, i):
 	return str(i)
 
+    def nameof_str(self, s):
+	return s
+
     def nameof_function(self, func):
+	#XXX this should actually be a StaticMeth
         printable_name = '(%s:%d) %s' % (
             func.func_globals.get('__name__', '?'),
             func.func_code.co_firstlineno,
@@ -255,6 +281,23 @@
         self.pendingfunctions.append(func)
         return sel
 
+    def nameof_Instance(self, inst):
+	if inst is None:
+	    #empty superclass
+	    return "Object"
+	self.note_Instance(inst)
+	return "Py%s" % inst._name.capitalize()
+
+    def note_Instance(self, inst):
+	if inst not in self.classes:
+	    if inst not in self.pendingclasses:
+		self.pendingclasses.append(inst)
+
+    def note_meth(self, inst, meth):
+        bm = (inst, meth)
+	if bm not in self.methods:
+	    if bm not in self.pendingmethods:
+		self.pendingmethods.append(bm)
 
     def unique_name(self, basename):
         n = self.seennames.get(basename, 0)

Added: pypy/dist/pypy/translator/squeak/test/test_oo.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/squeak/test/test_oo.py	Sat Oct 15 17:17:58 2005
@@ -0,0 +1,37 @@
+from pypy.tool.udir import udir
+from pypy.translator.squeak.gensqueak import GenSqueak
+from pypy.translator.translator import Translator
+from pypy.rpython.ootypesystem.ootype import *
+
+
+def build_sqfunc(func, args=[], view=False):
+   try: func = func.im_func
+   except AttributeError: pass
+   t = Translator(func)
+   t.annotate(args)
+   t.specialize(type_system="ootype")
+   t.simplify()
+   if view:
+      t.view()
+   GenSqueak(udir, t)
+
+
+C = Instance("test", None, {'a': (Signed, 3)})
+M = Meth([Signed], Signed)
+def m_(self, b):
+   return self.a+b
+m = meth(M, _name="m", _callable=m_)
+addMethods(C, {"m": m})
+
+def f_new():
+   return new(C)
+
+def f_meth():
+   c = new(C)
+   return c.m(5)
+
+def test_simple_new():
+   build_sqfunc(f_new)
+
+def test_simple_meth():
+   build_sqfunc(f_meth, view=False)



More information about the Pypy-commit mailing list