Author: Manuel Jacob
Branch: rpython-doc
Changeset: r61682:833074049d18
Date: 2013-02-23 15:37 +0100
http://bitbucket.org/pypy/pypy/changeset/833074049d18/

Log:    Separate RPython section from pypy/doc/coding-guide.rst.

diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst
--- a/pypy/doc/coding-guide.rst
+++ b/pypy/doc/coding-guide.rst
@@ -172,296 +172,6 @@
 enables the code generator to emit efficient machine level replacements
 for pure integer objects, for instance.
 
-RPython
-=================
-
-RPython Definition
-------------------
-
-RPython is a restricted subset of Python that is amenable to static analysis.
-Although there are additions to the language and some things might surprisingly
-work, this is a rough list of restrictions that should be considered. Note
-that there are tons of special cased restrictions that you'll encounter
-as you go. The exact definition is "RPython is everything that our translation
-toolchain can accept" :)
-
-.. _`wrapped object`: coding-guide.html#wrapping-rules
-
-Flow restrictions
--------------------------
-
-**variables**
-
-  variables should contain values of at most one type as described in
-  `Object restrictions`_ at each control flow point, that means for
-  example that joining control paths using the same variable to
-  contain both a string and a int must be avoided.  It is allowed to
-  mix None (basically with the role of a null pointer) with many other
-  types: `wrapped objects`, class instances, lists, dicts, strings, etc.
-  but *not* with int, floats or tuples.
-
-**constants**
-
-  all module globals are considered constants.  Their binding must not
-  be changed at run-time.  Moreover, global (i.e. prebuilt) lists and
-  dictionaries are supposed to be immutable: modifying e.g. a global
-  list will give inconsistent results.  However, global instances don't
-  have this restriction, so if you need mutable global state, store it
-  in the attributes of some prebuilt singleton instance.
-
-
-
-**control structures**
-
-  all allowed, ``for`` loops restricted to builtin types, generators
-  very restricted.
-
-**range**
-
-  ``range`` and ``xrange`` are identical. ``range`` does not necessarily 
create an array,
-  only if the result is modified. It is allowed everywhere and completely
-  implemented. The only visible difference to CPython is the inaccessibility
-  of the ``xrange`` fields start, stop and step.
-
-**definitions**
-
-  run-time definition of classes or functions is not allowed.
-
-**generators**
-
-  generators are supported, but their exact scope is very limited. you can't
-  merge two different generator in one control point.
-
-**exceptions**
-
-+ fully supported
-+ see below `Exception rules`_ for restrictions on exceptions raised by 
built-in operations
-
-
-Object restrictions
--------------------------
-
-We are using
-
-**integer, float, boolean**
-
-  works.
-
-**strings**
-
-  a lot of, but not all string methods are supported and those that are
-  supported, not necesarilly accept all arguments.  Indexes can be
-  negative.  In case they are not, then you get slightly more efficient
-  code if the translator can prove that they are non-negative.  When
-  slicing a string it is necessary to prove that the slice start and
-  stop indexes are non-negative. There is no implicit str-to-unicode cast
-  anywhere. Simple string formatting using the ``%`` operator works, as long
-  as the format string is known at translation time; the only supported
-  formatting specifiers are ``%s``, ``%d``, ``%x``, ``%o``, ``%f``, plus
-  ``%r`` but only for user-defined instances. Modifiers such as conversion
-  flags, precision, length etc. are not supported. Moreover, it is forbidden
-  to mix unicode and strings when formatting.
-
-**tuples**
-
-  no variable-length tuples; use them to store or return pairs or n-tuples of
-  values. Each combination of types for elements and length constitute
-  a separate and not mixable type.
-
-**lists**
-
-  lists are used as an allocated array.  Lists are over-allocated, so 
list.append()
-  is reasonably fast. However, if you use a fixed-size list, the code
-  is more efficient. Annotator can figure out most of the time that your
-  list is fixed-size, even when you use list comprehension.
-  Negative or out-of-bound indexes are only allowed for the
-  most common operations, as follows:
-
-  - *indexing*:
-    positive and negative indexes are allowed. Indexes are checked when 
requested
-    by an IndexError exception clause.
-  
-  - *slicing*:
-    the slice start must be within bounds. The stop doesn't need to, but it 
must
-    not be smaller than the start.  All negative indexes are disallowed, 
except for
-    the [:-1] special case.  No step.  Slice deletion follows the same rules.
-    
-  - *slice assignment*:
-    only supports ``lst[x:y] = sublist``, if ``len(sublist) == y - x``.
-    In other words, slice assignment cannot change the total length of the 
list,
-    but just replace items.
-
-  - *other operators*:
-    ``+``, ``+=``, ``in``, ``*``, ``*=``, ``==``, ``!=`` work as expected.
-
-  - *methods*:
-    append, index, insert, extend, reverse, pop.  The index used in pop() 
follows
-    the same rules as for *indexing* above.  The index used in insert() must 
be within
-    bounds and not negative.
-
-**dicts**
-
-  dicts with a unique key type only, provided it is hashable. Custom
-  hash functions and custom equality will not be honored.
-  Use ``rpython.rlib.objectmodel.r_dict`` for custom hash functions.
-
-
-**list comprehensions**
-
-  May be used to create allocated, initialized arrays.
-
-**functions**
-
-+ statically called functions may use defaults and a variable number of
-  arguments (which may be passed as a list instead of a tuple, so write code
-  that does not depend on it being a tuple).
-
-+ dynamic dispatch enforces the use of signatures that are equal for all
-  possible called function, or at least "compatible enough".  This
-  concerns mainly method calls, when the method is overridden or in any
-  way given different definitions in different classes.  It also concerns
-  the less common case of explicitly manipulated function objects.
-  Describing the exact compatibility rules is rather involved (but if you
-  break them, you should get explicit errors from the rtyper and not
-  obscure crashes.)
-
-**builtin functions**
-
-  A number of builtin functions can be used.  The precise set can be
-  found in `rpython/annotator/builtin.py`_ (see ``def builtin_xxx()``).
-  Some builtin functions may be limited in what they support, though.
-
-  ``int, float, str, ord, chr``... are available as simple conversion
-  functions.  Note that ``int, float, str``... have a special meaning as
-  a type inside of isinstance only.
-
-**classes**
-
-+ methods and other class attributes do not change after startup
-+ single inheritance is fully supported
-+ simple mixins work too, but the mixed in class needs a ``_mixin_ = True``
-  class attribute
-
-+ classes are first-class objects too
-
-**objects**
-
-  Normal rules apply. Special methods are not honoured, except ``__init__``,
-  ``__del__`` and ``__iter__``.
-
-This layout makes the number of types to take care about quite limited.
-
-
-Integer Types
--------------------------
-
-While implementing the integer type, we stumbled over the problem that
-integers are quite in flux in CPython right now. Starting with Python 2.4,
-integers mutate into longs on overflow.  In contrast, we need
-a way to perform wrap-around machine-sized arithmetic by default, while still
-being able to check for overflow when we need it explicitly.  Moreover, we need
-a consistent behavior before and after translation.
-
-We use normal integers for signed arithmetic.  It means that before
-translation we get longs in case of overflow, and after translation we get a
-silent wrap-around.  Whenever we need more control, we use the following
-helpers (which live in `rpython/rlib/rarithmetic.py`_):
-
-**ovfcheck()**
-
-  This special function should only be used with a single arithmetic operation
-  as its argument, e.g. ``z = ovfcheck(x+y)``.  Its intended meaning is to
-  perform the given operation in overflow-checking mode.
-
-  At run-time, in Python, the ovfcheck() function itself checks the result
-  and raises OverflowError if it is a ``long``.  But the code generators use
-  ovfcheck() as a hint: they replace the whole ``ovfcheck(x+y)`` expression
-  with a single overflow-checking addition in C.
-
-**intmask()**
-
-  This function is used for wrap-around arithmetic.  It returns the lower bits
-  of its argument, masking away anything that doesn't fit in a C "signed long 
int".
-  Its purpose is, in Python, to convert from a Python ``long`` that resulted 
from a
-  previous operation back to a Python ``int``.  The code generators ignore
-  intmask() entirely, as they are doing wrap-around signed arithmetic all the 
time
-  by default anyway.  (We have no equivalent of the "int" versus "long int"
-  distinction of C at the moment and assume "long ints" everywhere.)
-
-**r_uint**
-
-  In a few cases (e.g. hash table manipulation), we need machine-sized unsigned
-  arithmetic.  For these cases there is the r_uint class, which is a pure
-  Python implementation of word-sized unsigned integers that silently wrap
-  around.  ("word-sized" and "machine-sized" are used equivalently and mean
-  the native size, which you get using "unsigned long" in C.)
-  The purpose of this class (as opposed to helper functions as above)
-  is consistent typing: both Python and the annotator will propagate r_uint
-  instances in the program and interpret all the operations between them as
-  unsigned.  Instances of r_uint are special-cased by the code generators to
-  use the appropriate low-level type and operations.
-  Mixing of (signed) integers and r_uint in operations produces r_uint that
-  means unsigned results.  To convert back from r_uint to signed integers, use
-  intmask().
-
-
-Exception rules
----------------------
-
-Exceptions are by default not generated for simple cases.::
-
-    #!/usr/bin/python
-
-        lst = [1,2,3,4,5]
-        item = lst[i]    # this code is not checked for out-of-bound access
-
-        try:
-            item = lst[i]
-        except IndexError:
-            # complain
-
-Code with no exception handlers does not raise exceptions (after it has been
-translated, that is.  When you run it on top of CPython, it may raise
-exceptions, of course). By supplying an exception handler, you ask for error
-checking. Without, you assure the system that the operation cannot fail.
-This rule does not apply to *function calls*: any called function is
-assumed to be allowed to raise any exception.
-
-For example::
-
-    x = 5.1
-    x = x + 1.2       # not checked for float overflow
-    try:
-        x = x + 1.2
-    except OverflowError:
-        # float result too big
-
-But::
-
-    z = some_function(x, y)    # can raise any exception
-    try:
-        z = some_other_function(x, y)
-    except IndexError:
-        # only catches explicitly-raised IndexErrors in some_other_function()
-        # other exceptions can be raised, too, and will not be caught here.
-
-The ovfcheck() function described above follows the same rule: in case of
-overflow, it explicitly raise OverflowError, which can be caught anywhere.
-
-Exceptions explicitly raised or re-raised will always be generated.
-
-PyPy is debuggable on top of CPython
-------------------------------------
-
-PyPy has the advantage that it is runnable on standard
-CPython.  That means, we can run all of PyPy with all exception
-handling enabled, so we might catch cases where we failed to
-adhere to our implicit assertions.
-
-.. _`wrapping rules`:
-.. _`wrapped`:
-
-
 
 Wrapping rules
 ==============
diff --git a/rpython/doc/rpython.rst b/rpython/doc/rpython.rst
new file mode 100644
--- /dev/null
+++ b/rpython/doc/rpython.rst
@@ -0,0 +1,283 @@
+=======
+RPython
+=======
+
+RPython Definition
+------------------
+
+RPython is a restricted subset of Python that is amenable to static analysis.
+Although there are additions to the language and some things might surprisingly
+work, this is a rough list of restrictions that should be considered. Note
+that there are tons of special cased restrictions that you'll encounter
+as you go. The exact definition is "RPython is everything that our translation
+toolchain can accept" :)
+
+
+Flow restrictions
+-------------------------
+
+**variables**
+
+  variables should contain values of at most one type as described in
+  `Object restrictions`_ at each control flow point, that means for
+  example that joining control paths using the same variable to
+  contain both a string and a int must be avoided.  It is allowed to
+  mix None (basically with the role of a null pointer) with many other
+  types: wrapped objects, class instances, lists, dicts, strings, etc.
+  but *not* with int, floats or tuples.
+
+**constants**
+
+  all module globals are considered constants.  Their binding must not
+  be changed at run-time.  Moreover, global (i.e. prebuilt) lists and
+  dictionaries are supposed to be immutable: modifying e.g. a global
+  list will give inconsistent results.  However, global instances don't
+  have this restriction, so if you need mutable global state, store it
+  in the attributes of some prebuilt singleton instance.
+
+**control structures**
+
+  all allowed, ``for`` loops restricted to builtin types, generators
+  very restricted.
+
+**range**
+
+  ``range`` and ``xrange`` are identical. ``range`` does not necessarily 
create an array,
+  only if the result is modified. It is allowed everywhere and completely
+  implemented. The only visible difference to CPython is the inaccessibility
+  of the ``xrange`` fields start, stop and step.
+
+**definitions**
+
+  run-time definition of classes or functions is not allowed.
+
+**generators**
+
+  generators are supported, but their exact scope is very limited. you can't
+  merge two different generator in one control point.
+
+**exceptions**
+
++ fully supported
++ see below `Exception rules`_ for restrictions on exceptions raised by 
built-in operations
+
+
+Object restrictions
+-------------------------
+
+We are using
+
+**integer, float, boolean**
+
+  works.
+
+**strings**
+
+  a lot of, but not all string methods are supported and those that are
+  supported, not necesarilly accept all arguments.  Indexes can be
+  negative.  In case they are not, then you get slightly more efficient
+  code if the translator can prove that they are non-negative.  When
+  slicing a string it is necessary to prove that the slice start and
+  stop indexes are non-negative. There is no implicit str-to-unicode cast
+  anywhere. Simple string formatting using the ``%`` operator works, as long
+  as the format string is known at translation time; the only supported
+  formatting specifiers are ``%s``, ``%d``, ``%x``, ``%o``, ``%f``, plus
+  ``%r`` but only for user-defined instances. Modifiers such as conversion
+  flags, precision, length etc. are not supported. Moreover, it is forbidden
+  to mix unicode and strings when formatting.
+
+**tuples**
+
+  no variable-length tuples; use them to store or return pairs or n-tuples of
+  values. Each combination of types for elements and length constitute
+  a separate and not mixable type.
+
+**lists**
+
+  lists are used as an allocated array.  Lists are over-allocated, so 
list.append()
+  is reasonably fast. However, if you use a fixed-size list, the code
+  is more efficient. Annotator can figure out most of the time that your
+  list is fixed-size, even when you use list comprehension.
+  Negative or out-of-bound indexes are only allowed for the
+  most common operations, as follows:
+
+  - *indexing*:
+    positive and negative indexes are allowed. Indexes are checked when 
requested
+    by an IndexError exception clause.
+  
+  - *slicing*:
+    the slice start must be within bounds. The stop doesn't need to, but it 
must
+    not be smaller than the start.  All negative indexes are disallowed, 
except for
+    the [:-1] special case.  No step.  Slice deletion follows the same rules.
+    
+  - *slice assignment*:
+    only supports ``lst[x:y] = sublist``, if ``len(sublist) == y - x``.
+    In other words, slice assignment cannot change the total length of the 
list,
+    but just replace items.
+
+  - *other operators*:
+    ``+``, ``+=``, ``in``, ``*``, ``*=``, ``==``, ``!=`` work as expected.
+
+  - *methods*:
+    append, index, insert, extend, reverse, pop.  The index used in pop() 
follows
+    the same rules as for *indexing* above.  The index used in insert() must 
be within
+    bounds and not negative.
+
+**dicts**
+
+  dicts with a unique key type only, provided it is hashable. Custom
+  hash functions and custom equality will not be honored.
+  Use ``rpython.rlib.objectmodel.r_dict`` for custom hash functions.
+
+**list comprehensions**
+
+  May be used to create allocated, initialized arrays.
+
+**functions**
+
++ statically called functions may use defaults and a variable number of
+  arguments (which may be passed as a list instead of a tuple, so write code
+  that does not depend on it being a tuple).
+
++ dynamic dispatch enforces the use of signatures that are equal for all
+  possible called function, or at least "compatible enough".  This
+  concerns mainly method calls, when the method is overridden or in any
+  way given different definitions in different classes.  It also concerns
+  the less common case of explicitly manipulated function objects.
+  Describing the exact compatibility rules is rather involved (but if you
+  break them, you should get explicit errors from the rtyper and not
+  obscure crashes.)
+
+**builtin functions**
+
+  A number of builtin functions can be used.  The precise set can be
+  found in `rpython/annotator/builtin.py`_ (see ``def builtin_xxx()``).
+  Some builtin functions may be limited in what they support, though.
+
+  ``int, float, str, ord, chr``... are available as simple conversion
+  functions.  Note that ``int, float, str``... have a special meaning as
+  a type inside of isinstance only.
+
+**classes**
+
++ methods and other class attributes do not change after startup
++ single inheritance is fully supported
++ simple mixins work too, but the mixed in class needs a ``_mixin_ = True``
+  class attribute
+
++ classes are first-class objects too
+
+**objects**
+
+  Normal rules apply. Special methods are not honoured, except ``__init__``,
+  ``__del__`` and ``__iter__``.
+
+This layout makes the number of types to take care about quite limited.
+
+
+Integer Types
+-------------------------
+
+While implementing the integer type, we stumbled over the problem that
+integers are quite in flux in CPython right now. Starting with Python 2.4,
+integers mutate into longs on overflow.  In contrast, we need
+a way to perform wrap-around machine-sized arithmetic by default, while still
+being able to check for overflow when we need it explicitly.  Moreover, we need
+a consistent behavior before and after translation.
+
+We use normal integers for signed arithmetic.  It means that before
+translation we get longs in case of overflow, and after translation we get a
+silent wrap-around.  Whenever we need more control, we use the following
+helpers (which live in `rpython/rlib/rarithmetic.py`_):
+
+**ovfcheck()**
+
+  This special function should only be used with a single arithmetic operation
+  as its argument, e.g. ``z = ovfcheck(x+y)``.  Its intended meaning is to
+  perform the given operation in overflow-checking mode.
+
+  At run-time, in Python, the ovfcheck() function itself checks the result
+  and raises OverflowError if it is a ``long``.  But the code generators use
+  ovfcheck() as a hint: they replace the whole ``ovfcheck(x+y)`` expression
+  with a single overflow-checking addition in C.
+
+**intmask()**
+
+  This function is used for wrap-around arithmetic.  It returns the lower bits
+  of its argument, masking away anything that doesn't fit in a C "signed long 
int".
+  Its purpose is, in Python, to convert from a Python ``long`` that resulted 
from a
+  previous operation back to a Python ``int``.  The code generators ignore
+  intmask() entirely, as they are doing wrap-around signed arithmetic all the 
time
+  by default anyway.  (We have no equivalent of the "int" versus "long int"
+  distinction of C at the moment and assume "long ints" everywhere.)
+
+**r_uint**
+
+  In a few cases (e.g. hash table manipulation), we need machine-sized unsigned
+  arithmetic.  For these cases there is the r_uint class, which is a pure
+  Python implementation of word-sized unsigned integers that silently wrap
+  around.  ("word-sized" and "machine-sized" are used equivalently and mean
+  the native size, which you get using "unsigned long" in C.)
+  The purpose of this class (as opposed to helper functions as above)
+  is consistent typing: both Python and the annotator will propagate r_uint
+  instances in the program and interpret all the operations between them as
+  unsigned.  Instances of r_uint are special-cased by the code generators to
+  use the appropriate low-level type and operations.
+  Mixing of (signed) integers and r_uint in operations produces r_uint that
+  means unsigned results.  To convert back from r_uint to signed integers, use
+  intmask().
+
+
+Exception rules
+---------------------
+
+Exceptions are by default not generated for simple cases.::
+
+    #!/usr/bin/python
+
+        lst = [1,2,3,4,5]
+        item = lst[i]    # this code is not checked for out-of-bound access
+
+        try:
+            item = lst[i]
+        except IndexError:
+            # complain
+
+Code with no exception handlers does not raise exceptions (after it has been
+translated, that is.  When you run it on top of CPython, it may raise
+exceptions, of course). By supplying an exception handler, you ask for error
+checking. Without, you assure the system that the operation cannot fail.
+This rule does not apply to *function calls*: any called function is
+assumed to be allowed to raise any exception.
+
+For example::
+
+    x = 5.1
+    x = x + 1.2       # not checked for float overflow
+    try:
+        x = x + 1.2
+    except OverflowError:
+        # float result too big
+
+But::
+
+    z = some_function(x, y)    # can raise any exception
+    try:
+        z = some_other_function(x, y)
+    except IndexError:
+        # only catches explicitly-raised IndexErrors in some_other_function()
+        # other exceptions can be raised, too, and will not be caught here.
+
+The ovfcheck() function described above follows the same rule: in case of
+overflow, it explicitly raise OverflowError, which can be caught anywhere.
+
+Exceptions explicitly raised or re-raised will always be generated.
+
+
+PyPy is debuggable on top of CPython
+------------------------------------
+
+PyPy has the advantage that it is runnable on standard
+CPython.  That means, we can run all of PyPy with all exception
+handling enabled, so we might catch cases where we failed to
+adhere to our implicit assertions.
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to