(NOTE: you should first read the FAQ entries about Using the PyPy translation tool chain. This document is a quick introduction to the interactive way to compile your own RPython code. Keep in mind though that if you write a larger RPython program, the best and most flexible way to compile it is not as described below, but by writing a target file as described in the FAQ entries.)
First, see the note above. Next, understand the restrictions on RPython code. Pay close attention to the description of tuples and dicts.
Take this example program:
import os def main(argv): os.write(1, "Hello world!\n") return 0
To compile:
from pypy.translator.interactive import Translation t = Translation(main, standalone=True, gc='ref') t.source(backend='c') path = t.compile() print path
The path is the location of the executable.
To see the translation in motion, try removing the argv argument to main, or the return 0.
Type inference happens in the Annotator. Keep this in mind as you write RPython code. After annotation the low level code generation (the implementation of the types) happens in the RTyper.
These steps can be spelled out explicitly:
t.annotate() t.rtype() t.source(backend='c') path = t.compile()
After the annotate() or rtype() call you can view the resulting flow graph with a pygame/dot based graphing tool:
t.annotate() t.view() t.rtype() t.view()
Here are some debugging tips:
RPython is tricky!
Take this example:
def abs(num): if num < 0: num = -num return num
If you want to use this function with different argument types (eg. int and float) the translation will fail. In order to generate a different function for each argument type we need to set an attribute:
abs._annspecialcase_ = "specialize:argtype(0)"
As another example:
def sum(l): total = 0 for v in l: total += v return total sum._annspecialcase_ = "specialize:argtype(0)"
Now we can sum with different kinds of lists, eg. sum([1,2,3]) and sum([1.0,2.0,3.0]).
Here is an example of using rctypes:
import ctypes from ctypes import c_int, c_char_p import pypy.rpython.rctypes.implementation libc = ctypes.cdll.LoadLibrary('libc.so.6') write = libc.write write.argtypes = [c_int, c_char_p, c_int] write.restype = c_int def main(argv): msg = "Hello world!\n" write(1, msg, len(msg)) return 0
PyPy implements the ctypes semantics as the corresponding native c-code equivalents.