[pypy-svn] r34368 - in pypy/dist/pypy: interpreter objspace/flow translator/c/test

arigo at codespeak.net arigo at codespeak.net
Wed Nov 8 14:54:36 CET 2006


Author: arigo
Date: Wed Nov  8 14:54:35 2006
New Revision: 34368

Modified:
   pypy/dist/pypy/interpreter/pyopcode.py
   pypy/dist/pypy/objspace/flow/specialcase.py
   pypy/dist/pypy/translator/c/test/test_standalone.py
Log:
Support for "print" in RPython.

* doesn't support "print >> f".
* uses str() on each item, so inherits str()'s limitations.
* the output is done with os.write(1,...) but it is line-buffered.



Modified: pypy/dist/pypy/interpreter/pyopcode.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyopcode.py	(original)
+++ pypy/dist/pypy/interpreter/pyopcode.py	Wed Nov  8 14:54:35 2006
@@ -305,22 +305,22 @@
     def PRINT_ITEM_TO(f):
         w_stream = f.valuestack.pop()
         w_item = f.valuestack.pop()
-        if w_stream == f.space.w_None:
+        if f.space.is_w(w_stream, f.space.w_None):
             w_stream = sys_stdout(f.space)   # grumble grumble special cases
         print_item_to(f.space, w_item, w_stream)
 
     def PRINT_ITEM(f):
         w_item = f.valuestack.pop()
-        print_item_to(f.space, w_item, sys_stdout(f.space))
+        print_item(f.space, w_item)
 
     def PRINT_NEWLINE_TO(f):
         w_stream = f.valuestack.pop()
-        if w_stream == f.space.w_None:
+        if f.space.is_w(w_stream, f.space.w_None):
             w_stream = sys_stdout(f.space)   # grumble grumble special cases
         print_newline_to(f.space, w_stream)
 
     def PRINT_NEWLINE(f):
-        print_newline_to(f.space, sys_stdout(f.space))
+        print_newline(f.space)
 
     def BREAK_LOOP(f):
         raise pyframe.SBreakLoop
@@ -909,10 +909,18 @@
         file_softspace(stream, True)
     print_item_to._annspecialcase_ = "specialize:argtype(0)"
 
+    def print_item(x):
+        print_item_to(x, sys_stdout())
+    print_item._annspecialcase_ = "flowspace:print_item"
+
     def print_newline_to(stream):
         stream.write("\n")
         file_softspace(stream, False)
 
+    def print_newline():
+        print_newline_to(sys_stdout())
+    print_newline._annspecialcase_ = "flowspace:print_newline"
+
     def file_softspace(file, newflag):
         try:
             softspace = file.softspace
@@ -927,7 +935,9 @@
 
 sys_stdout      = app.interphook('sys_stdout')
 print_expr      = app.interphook('print_expr')
+print_item      = app.interphook('print_item')
 print_item_to   = app.interphook('print_item_to')
+print_newline   = app.interphook('print_newline')
 print_newline_to= app.interphook('print_newline_to')
 file_softspace  = app.interphook('file_softspace')
 

Modified: pypy/dist/pypy/objspace/flow/specialcase.py
==============================================================================
--- pypy/dist/pypy/objspace/flow/specialcase.py	(original)
+++ pypy/dist/pypy/objspace/flow/specialcase.py	Wed Nov  8 14:54:35 2006
@@ -66,6 +66,28 @@
         return dic
     _build = staticmethod(_build)
 
+# _________________________________________________________________________
+# a simplified version of the basic printing routines, for RPython programs
+class StdOutBuffer:
+    linebuf = []
+stdoutbuffer = StdOutBuffer()
+def rpython_print_item(s):
+    buf = stdoutbuffer.linebuf
+    for c in s:
+        buf.append(c)
+    buf.append(' ')
+def rpython_print_newline():
+    buf = stdoutbuffer.linebuf
+    if buf:
+        buf[-1] = '\n'
+        s = ''.join(buf)
+        del buf[:]
+    else:
+        s = '\n'
+    import os
+    os.write(1, s)
+# _________________________________________________________________________
+
 compiled_funcs = FunctionCache()
 
 def sc_applevel(space, app, name, args_w):
@@ -73,6 +95,18 @@
     if not dic:
         return None # signal that this is not RPython
     func = dic[name]
+    if getattr(func, '_annspecialcase_', '').startswith('flowspace:'):
+        # a hack to replace specific app-level helpers with simplified
+        # RPython versions
+        name = func._annspecialcase_[len('flowspace:'):]
+        if name == 'print_item':    # more special cases...
+            w_s = space.do_operation('str', *args_w)
+            args_w = (w_s,)
+        func = globals()['rpython_' + name]
+    else:
+        # otherwise, just call the app-level helper and hope that it
+        # is RPython enough
+        pass
     return space.do_operation('simple_call', Constant(func), *args_w)
 
 def setup(space):

Modified: pypy/dist/pypy/translator/c/test/test_standalone.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_standalone.py	(original)
+++ pypy/dist/pypy/translator/c/test/test_standalone.py	Wed Nov  8 14:54:35 2006
@@ -22,3 +22,28 @@
     cbuilder.compile()
     data = cbuilder.cmdexec('hi there')
     assert data.startswith('''hello world\nargument count: 2\n   'hi'\n   'there'\n''')
+
+def test_print():
+    def entry_point(argv):
+        print "hello simpler world"
+        argv = argv[1:]
+        print "argument count:", len(argv)
+        print "arguments:", argv
+        print "argument lengths:",
+        print [len(s) for s in argv]
+        return 0
+
+    t = TranslationContext()
+    t.buildannotator().build_types(entry_point, [s_list_of_strings])
+    t.buildrtyper().specialize()
+
+    cbuilder = CStandaloneBuilder(t, entry_point)
+    cbuilder.generate_source()
+    cbuilder.compile()
+    data = cbuilder.cmdexec('hi there')
+    assert data.startswith('''hello simpler world\n'''
+                           '''argument count: 2\n'''
+                           '''arguments: [hi, there]\n'''
+                           '''argument lengths: [2, 5]\n''')
+    # NB. RPython has only str, not repr, so str() on a list of strings
+    # gives the strings unquoted in the list



More information about the Pypy-commit mailing list