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

nik at codespeak.net nik at codespeak.net
Fri Mar 10 18:26:11 CET 2006


Author: nik
Date: Fri Mar 10 18:26:05 2006
New Revision: 24234

Modified:
   pypy/dist/pypy/translator/squeak/gensqueak.py
   pypy/dist/pypy/translator/squeak/test/test_squeaktrans.py
Log:
some quick hacking to make constant instances work for the simple test
cases so far. this is maybe too brittle for the general case. need
to think about a more permanent solution now.


Modified: pypy/dist/pypy/translator/squeak/gensqueak.py
==============================================================================
--- pypy/dist/pypy/translator/squeak/gensqueak.py	(original)
+++ pypy/dist/pypy/translator/squeak/gensqueak.py	Fri Mar 10 18:26:05 2006
@@ -32,6 +32,7 @@
         self.unique_name_mapping = {}
         self.pending_nodes = []
         self.generated_nodes = set()
+        self.constant_insts = {}
 
         if conftest.option.view:
             self.translator.view()
@@ -41,6 +42,8 @@
         self.filename = '%s.st' % graph.name
         file = self.sqdir.join(self.filename).open('w')
         self.gen_source(file)
+        self.pending_nodes.append(SetupNode(self, self.constant_insts)) 
+        self.gen_source(file)
         file.close()
 
     def gen_source(self, file):
@@ -99,8 +102,8 @@
         squeak_class_name = self.unique_name(INSTANCE, class_name)
         return "Py%s" % squeak_class_name
 
-    def nameof__instance(self, inst):
-        return self.nameof_Instance(inst._TYPE)
+    def nameof__class(self, class_):
+        return self.nameof_Instance(class_._INSTANCE)
 
     def nameof__callable(self, callable):
         return self.nameof_function(callable.graph.func)
@@ -182,9 +185,12 @@
 
 class ClassNode(CodeNode):
 
-    def __init__(self, gen, INSTANCE):
+    def __init__(self, gen, INSTANCE, class_vars=None):
         self.gen = gen
         self.INSTANCE = INSTANCE
+        self.class_vars = [] # XXX should probably go away
+        if class_vars is not None:
+            self.class_vars = class_vars
         self.hash_key = INSTANCE
 
     def dependencies(self):
@@ -200,7 +206,7 @@
         fields = [self.unique_field(self.INSTANCE, f) for f in
             self.INSTANCE._fields.iterkeys()]
         yield "    instanceVariableNames: '%s'" % ' '.join(fields)
-        yield "    classVariableNames: ''"
+        yield "    classVariableNames: '%s'" % ' '.join(self.class_vars)
         yield "    poolDictionaries: ''"
         yield "    category: 'PyPy-Test'!"
 
@@ -257,6 +263,11 @@
         if isinstance(v, Variable):
             return camel_case(v.name)
         elif isinstance(v, Constant):
+            if isinstance(v.concretetype, Instance):
+                const_id = self.gen.unique_name(
+                        v, "const_%s" % self.gen.nameof(v.value._TYPE))
+                self.gen.constant_insts[v] = const_id
+                return "(PyConstants getConstant: '%s')" % const_id
             return self.gen.nameof(v.value)
         else:
             raise TypeError, "expr(%r)" % (v,)
@@ -317,6 +328,9 @@
             receiver = self.expr(op.args[0])
             return "%s %s: %s." % (receiver, field_name, field_value)
 
+    def op_oodowncast(self, op):
+        return "%s := %s." % (self.expr(op.result), self.expr(op.args[0]))
+
     def op_direct_call(self, op):
         # XXX not sure if static methods of a specific class should
         # be treated differently.
@@ -457,3 +471,65 @@
         yield "    ^%s" % self.field_name
         yield "! !"
 
+class FieldInitializerNode(CodeNode):
+
+    def __init__(self, gen, INSTANCE):
+        self.gen = gen
+        self.INSTANCE = INSTANCE
+        self.hash_key = ("fieldinit", INSTANCE)
+
+    def dependencies(self):
+        return [ClassNode(self.gen, self.INSTANCE)]
+
+    def render(self):
+        yield self.render_fileout_header(
+                self.gen.nameof_Instance(self.INSTANCE), "initializers")
+        fields = self.INSTANCE._allfields()
+        sel = Selector("field_init", len(fields))
+        arg_names = ["a%s" % i for i in range(len(fields))]
+        yield sel.signature(arg_names)
+        for field_name, arg_name in zip(fields.keys(), arg_names):
+            yield "    %s := %s." % (
+                    self.unique_field(self.INSTANCE, field_name),
+                    arg_name)
+        yield "! !"
+
+class SetupNode(CodeNode):
+
+    CONSTANTS = Instance("Constants", ROOT)
+    
+    def __init__(self, gen, constants):
+        self.gen = gen
+        self.constants = constants
+        self.hash_key = "setup"
+
+    def dependencies(self):
+        # Important: Field initializers for the *runtime* type
+        return [FieldInitializerNode(self.gen, c.value._TYPE)
+            for c in self.constants.iterkeys()] + \
+            [ClassNode(self.gen, self.CONSTANTS, class_vars=["Constants"])]
+
+    def render(self):
+        yield self.render_fileout_header("PyConstants class", "internals")
+        sel = Selector("setupConstants", 0)
+        yield sel.signature([])
+        yield "    Constants := Dictionary new."
+        for const, const_id in self.constants.iteritems():
+            INST = const.value._TYPE
+            class_name = self.gen.nameof(INST)
+            field_names = INST._allfields().keys()
+            field_values = [self.gen.nameof(getattr(const.value, f))
+                    for f in field_names]
+            init_sel = Selector("field_init", len(field_values))
+            yield "    Constants at: '%s' put: (%s new %s)." \
+                    % (const_id, class_name,
+                        init_sel.signature(field_values))
+        yield "! !"
+        yield ""
+
+        yield self.render_fileout_header("PyConstants class", "internals")
+        sel = Selector("getConstant", 1)
+        yield sel.signature(["constId"])
+        yield "    ^ Constants at: constId"
+        yield "! !"
+

Modified: pypy/dist/pypy/translator/squeak/test/test_squeaktrans.py
==============================================================================
--- pypy/dist/pypy/translator/squeak/test/test_squeaktrans.py	(original)
+++ pypy/dist/pypy/translator/squeak/test/test_squeaktrans.py	Fri Mar 10 18:26:05 2006
@@ -18,6 +18,8 @@
     except AttributeError: pass
     t = TranslationContext()
     t.buildannotator().build_types(func, args)
+    if conftest.option.view:
+       t.viewcg()
     t.buildrtyper(type_system="ootype").specialize()
     if conftest.option.view:
        t.viewcg()
@@ -51,6 +53,7 @@
 [(arg := Smalltalk getSystemAttribute: (i := i + 1)) notNil]
     whileTrue: [arguments add: arg asInteger].
 
+PyConstants setupConstants.
 result := (PyFunctions perform: selector withArguments: arguments asArray).
 stdout := StandardFileStream fileNamed: '/dev/stdout'.
 stdout nextPutAll: result asString.
@@ -175,7 +178,7 @@
             return i + a.i_var
         assert self.run_on_squeak(f, 2) == "6"
 
-    def dont_test_classvars(self):
+    def test_classvars(self):
         class A: i = 1
         class B(A): i = 2
         def pick(i):



More information about the Pypy-commit mailing list