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

nik at codespeak.net nik at codespeak.net
Mon Mar 6 16:56:45 CET 2006


Author: nik
Date: Mon Mar  6 16:56:44 2006
New Revision: 24025

Modified:
   pypy/dist/pypy/translator/squeak/gensqueak.py
   pypy/dist/pypy/translator/squeak/test/test_squeaktrans.py
Log:
devised some hackish way to have code generated by GenSqueak actually run
on a squeak vm. got a very basic test passing. need to think a lot now
about how to proceed.


Modified: pypy/dist/pypy/translator/squeak/gensqueak.py
==============================================================================
--- pypy/dist/pypy/translator/squeak/gensqueak.py	(original)
+++ pypy/dist/pypy/translator/squeak/gensqueak.py	Mon Mar  6 16:56:44 2006
@@ -95,6 +95,7 @@
         self.pendingmethods = []
         self.classes = [] 
         self.methods = [] 
+        self.function_container = False
 
         t = self.translator
         graph = t.graphs[0]
@@ -106,7 +107,8 @@
             self.translator.view()
 
         self.nameof(graph) #add to pending
-        file = self.sqdir.join('%s.st' % graph.name).open('w')
+        self.filename = '%s.st' % graph.name
+        file = self.sqdir.join(self.filename).open('w')
         self.gen_source(file)
         file.close()
 
@@ -240,16 +242,29 @@
                         yield "    %s" % line
                     yield "]"
 
+        if not self.function_container:
+            self.gen_function_container(f)
+            self.function_container = True
+
         start = graph.startblock
         args = [expr(arg) for arg in start.inputargs]
+        print >> f, "!PyFunctions class methodsFor: 'functions'" \
+                " stamp: 'pypy 1/1/2000 00:00'!"
         print >> f, '%s' % signature(self.nameof(graph), args)
-    
+ 
         loops = LoopFinder(start).loops
 
         for line in render_block(start):
             print >> f, '       %s' % line
         print >> f
 
+    def gen_function_container(self, f):
+        print >> f, """Object subclass: #PyFunctions
+            instanceVariableNames: ''
+            classVariableNames: ''
+            poolDictionaries: ''
+            category: 'PyPy'!"""
+        
     def nameof(self, obj):
         key = Constant(obj).key
         try:

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	Mon Mar  6 16:56:44 2006
@@ -1,3 +1,5 @@
+import os
+import py
 from pypy.tool.udir import udir
 from pypy.translator.test import snippet
 from pypy.translator.squeak.gensqueak import GenSqueak
@@ -10,27 +12,80 @@
         while j > 0:
             j -= 1
 
-class TestSqueakTrans:
+def build_sqfunc(func):
+    try: func = func.im_func
+    except AttributeError: pass
+    t = TranslationContext()
+    graph = t.buildflowgraph(func)
+    t._prebuilt_graphs[func] = graph
+    gen = GenSqueak(udir, t)
+    return gen
 
-    def build_sqfunc(self, func):
-        try: func = func.im_func
-        except AttributeError: pass
-        t = TranslationContext()
-        graph = t.buildflowgraph(func)
-        t._prebuilt_graphs[func] = graph
-        self.gen = GenSqueak(udir, t)
+class TestSqueakTrans:
 
     def test_simple_func(self):
-        self.build_sqfunc(snippet.simple_func)
+        build_sqfunc(snippet.simple_func)
 
     def test_if_then_else(self):
-        self.build_sqfunc(snippet.if_then_else)
+        build_sqfunc(snippet.if_then_else)
 
     def test_two_plus_two(self):
-        self.build_sqfunc(snippet.two_plus_two)
+        build_sqfunc(snippet.two_plus_two)
 
     def test_my_gcd(self):
-        self.build_sqfunc(snippet.my_gcd)
+        build_sqfunc(snippet.my_gcd)
 
     def test_looping(self):
-        self.build_sqfunc(looping)
+        build_sqfunc(looping)
+
+
+# For now use pipes to communicate with squeak. This is very flaky
+# and only works for posix systems. At some later point we'll
+# probably need a socket based solution for this.
+startup_script = """
+| stdout src function result |
+src := Smalltalk getSystemAttribute: 3.
+FileStream fileIn: src.
+function := Smalltalk getSystemAttribute: 4.
+result := Compiler new evaluate: ('PyFunctions ' , function) in: nil to: nil.
+stdout := StandardFileStream fileNamed: '/dev/stdout'.
+stdout nextPutAll: result asString.
+Smalltalk snapshot: false andQuit: true.
+"""
+
+class TestGenSqueak:
+
+    def setup_class(self):
+        self.startup_st = udir.join("startup.st")
+        f = self.startup_st.open("w")
+        f.write(startup_script)
+        f.close()
+
+    def run_on_squeak(self, function):
+        try:
+            import posix
+        except ImportError:
+            py.skip("Squeak tests only work on Unix right now.")
+        try:
+            py.path.local.sysfind("squeak")
+        except py.error.ENOENT:
+            py.skip("Squeak is not on your path.")
+        if os.getenv("SQUEAK_IMAGE") is None:
+            py.skip("Squeak tests expect the SQUEAK_IMAGE environment "
+                    "variable to point to an image.")
+        gen_squeak = build_sqfunc(function)
+        squeak_process = os.popen("squeak -headless -- %s %s %s"
+                % (self.startup_st, udir.join(gen_squeak.filename),
+                   # HACK XXX. Only works for functions without arguments.
+                   # Need to really rethink how selectors are assigned 
+                   # to functions.
+                   function.__name__))
+        result = squeak_process.read()
+        assert squeak_process.close() is None # exit status was 0
+        return result
+
+    def test_theanswer(self):
+        def theanswer():
+            return 42
+        assert self.run_on_squeak(theanswer) == "42"
+



More information about the Pypy-commit mailing list