[pypy-svn] r14263 - in pypy/branch/dist-2.4.1: lib-python/modified-2.3.4 lib-python/modified-2.3.4/test pypy/documentation pypy/interpreter pypy/interpreter/astcompiler pypy/interpreter/pyparser pypy/interpreter/pyparser/test pypy/interpreter/pyparser/test/samples pypy/interpreter/stablecompiler pypy/interpreter/test pypy/lib pypy/objspace/std pypy/objspace/std/test pypy/tool pypy/translator/goal pypy/translator/llvm2 pypy/translator/llvm2/test

arigo at codespeak.net arigo at codespeak.net
Tue Jul 5 12:03:40 CEST 2005


Author: arigo
Date: Tue Jul  5 12:03:38 2005
New Revision: 14263

Added:
   pypy/branch/dist-2.4.1/lib-python/modified-2.3.4/binhex.py
      - copied unchanged from r14261, pypy/dist/lib-python/modified-2.3.4/binhex.py
   pypy/branch/dist-2.4.1/lib-python/modified-2.3.4/test/test_binhex.py
      - copied unchanged from r14261, pypy/dist/lib-python/modified-2.3.4/test/test_binhex.py
   pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/test/samples/snippet_multiline.py
      - copied unchanged from r14261, pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_multiline.py
   pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/test/samples/snippet_only_one_comment.py
      - copied unchanged from r14261, pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_only_one_comment.py
   pypy/branch/dist-2.4.1/pypy/interpreter/stablecompiler/   (props changed)
      - copied from r14261, pypy/dist/pypy/interpreter/stablecompiler/
   pypy/branch/dist-2.4.1/pypy/interpreter/stablecompiler/__init__.py
      - copied unchanged from r14261, pypy/dist/pypy/interpreter/stablecompiler/__init__.py
   pypy/branch/dist-2.4.1/pypy/interpreter/stablecompiler/ast.py
      - copied unchanged from r14261, pypy/dist/pypy/interpreter/stablecompiler/ast.py
   pypy/branch/dist-2.4.1/pypy/interpreter/stablecompiler/consts.py
      - copied unchanged from r14261, pypy/dist/pypy/interpreter/stablecompiler/consts.py
   pypy/branch/dist-2.4.1/pypy/interpreter/stablecompiler/future.py
      - copied unchanged from r14261, pypy/dist/pypy/interpreter/stablecompiler/future.py
   pypy/branch/dist-2.4.1/pypy/interpreter/stablecompiler/misc.py
      - copied unchanged from r14261, pypy/dist/pypy/interpreter/stablecompiler/misc.py
   pypy/branch/dist-2.4.1/pypy/interpreter/stablecompiler/pyassem.py
      - copied unchanged from r14261, pypy/dist/pypy/interpreter/stablecompiler/pyassem.py
   pypy/branch/dist-2.4.1/pypy/interpreter/stablecompiler/pycodegen.py
      - copied unchanged from r14261, pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py
   pypy/branch/dist-2.4.1/pypy/interpreter/stablecompiler/symbols.py
      - copied unchanged from r14261, pypy/dist/pypy/interpreter/stablecompiler/symbols.py
   pypy/branch/dist-2.4.1/pypy/interpreter/stablecompiler/syntax.py
      - copied unchanged from r14261, pypy/dist/pypy/interpreter/stablecompiler/syntax.py
   pypy/branch/dist-2.4.1/pypy/interpreter/stablecompiler/transformer.py
      - copied unchanged from r14261, pypy/dist/pypy/interpreter/stablecompiler/transformer.py
   pypy/branch/dist-2.4.1/pypy/interpreter/stablecompiler/visitor.py
      - copied unchanged from r14261, pypy/dist/pypy/interpreter/stablecompiler/visitor.py
   pypy/branch/dist-2.4.1/pypy/translator/llvm2/atomic.py
      - copied unchanged from r14261, pypy/dist/pypy/translator/llvm2/atomic.py
Removed:
   pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/test/samples/snippet_only_one_comment.DISABLED
Modified:
   pypy/branch/dist-2.4.1/pypy/documentation/ext-functions-draft.txt
   pypy/branch/dist-2.4.1/pypy/interpreter/astcompiler/transformer.py
   pypy/branch/dist-2.4.1/pypy/interpreter/pycompiler.py
   pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/   (props changed)
   pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/__init__.py   (props changed)
   pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/automata.py   (props changed)
   pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/ebnfparse.py
   pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/grammar.py
   pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/pythonlexer.py
   pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/pythonparse.py
   pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/pythonutil.py
   pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/pytokenize.py   (contents, props changed)
   pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/test/test_lookahead.py   (props changed)
   pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/test/test_samples.py
   pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/tuplebuilder.py
   pypy/branch/dist-2.4.1/pypy/interpreter/test/test_compiler.py
   pypy/branch/dist-2.4.1/pypy/interpreter/test/test_interpreter.py
   pypy/branch/dist-2.4.1/pypy/lib/binascii.py
   pypy/branch/dist-2.4.1/pypy/lib/struct.py
   pypy/branch/dist-2.4.1/pypy/objspace/std/longobject.py
   pypy/branch/dist-2.4.1/pypy/objspace/std/test/test_longobject.py
   pypy/branch/dist-2.4.1/pypy/tool/option.py
   pypy/branch/dist-2.4.1/pypy/translator/goal/targetparser.py
   pypy/branch/dist-2.4.1/pypy/translator/llvm2/arraynode.py
   pypy/branch/dist-2.4.1/pypy/translator/llvm2/build_llvm_module.py
   pypy/branch/dist-2.4.1/pypy/translator/llvm2/codewriter.py
   pypy/branch/dist-2.4.1/pypy/translator/llvm2/database.py
   pypy/branch/dist-2.4.1/pypy/translator/llvm2/funcnode.py
   pypy/branch/dist-2.4.1/pypy/translator/llvm2/genllvm.py
   pypy/branch/dist-2.4.1/pypy/translator/llvm2/pyxwrapper.py
   pypy/branch/dist-2.4.1/pypy/translator/llvm2/structnode.py
   pypy/branch/dist-2.4.1/pypy/translator/llvm2/test/test_genllvm.py
Log:
merged the trunk into r14261
  svn merge -r14183:14261 http://codespeak.net/svn/pypy/dist



Modified: pypy/branch/dist-2.4.1/pypy/documentation/ext-functions-draft.txt
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/documentation/ext-functions-draft.txt	(original)
+++ pypy/branch/dist-2.4.1/pypy/documentation/ext-functions-draft.txt	Tue Jul  5 12:03:38 2005
@@ -15,8 +15,10 @@
 
 * rtyper will replace the calls with for testing or dummy lowlevel
   functions (ll_os_open for os.open), specified somehow trough the
-  table (issue: how to annotate these helper calls avoiding making
-  copies as in the usual case, so that the backends can recognize them)
+  table. The usual specialisation for low-level helpers will happem
+  but the original function will be attached as _callable to the
+  function pointer such that backends can recognize the original
+  function as from the table.
 
 * the backends will have implementations for these helper functions
   (to allow writing such implementations we will need a way to assign

Modified: pypy/branch/dist-2.4.1/pypy/interpreter/astcompiler/transformer.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/interpreter/astcompiler/transformer.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/interpreter/astcompiler/transformer.py	Tue Jul  5 12:03:38 2005
@@ -89,7 +89,7 @@
             print nodes[kind], len(args), args
             raise
     else:
-        raise WalkerEror, "Can't find appropriate Node type: %s" % str(args)
+        raise WalkerError, "Can't find appropriate Node type: %s" % str(args)
         #return apply(ast.Node, args)
 
 class Transformer:
@@ -165,7 +165,7 @@
         if n == symbol.classdef:
             return self.classdef(node[1:])
 
-        raise WalkerEror, ('unexpected node type', n)
+        raise WalkerError, ('unexpected node type', n)
 
     def single_input(self, node):
         ### do we want to do anything about being "interactive" ?
@@ -314,31 +314,31 @@
         return Stmt(stmts)
 
     def parameters(self, nodelist):
-        raise WalkerEror
+        raise WalkerError
 
     def varargslist(self, nodelist):
-        raise WalkerEror
+        raise WalkerError
 
     def fpdef(self, nodelist):
-        raise WalkerEror
+        raise WalkerError
 
     def fplist(self, nodelist):
-        raise WalkerEror
+        raise WalkerError
 
     def dotted_name(self, nodelist):
-        raise WalkerEror
+        raise WalkerError
 
     def comp_op(self, nodelist):
-        raise WalkerEror
+        raise WalkerError
 
     def trailer(self, nodelist):
-        raise WalkerEror
+        raise WalkerError
 
     def sliceop(self, nodelist):
-        raise WalkerEror
+        raise WalkerError
 
     def argument(self, nodelist):
-        raise WalkerEror
+        raise WalkerError
 
     # --------------------------------------------------------------
     #

Modified: pypy/branch/dist-2.4.1/pypy/interpreter/pycompiler.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/interpreter/pycompiler.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/interpreter/pycompiler.py	Tue Jul  5 12:03:38 2005
@@ -68,7 +68,7 @@
             if not err2.match(space, space.w_SyntaxError):
                 raise
 
-        if space.eq_w(err1.w_value, err2.w_value):
+        if mode != 'single' and space.eq_w(err1.w_value, err2.w_value):
             raise     # twice the same error, re-raise
 
         return None   # two different errors, expect more
@@ -169,14 +169,12 @@
 
 
 ########
-# from compiler.transformer import Transformer
-from compiler.pycodegen import ModuleCodeGenerator
-from compiler.pycodegen import InteractiveCodeGenerator
-from compiler.pycodegen import ExpressionCodeGenerator
-from pyparser.pythonparse import parse_python_source, PYTHON_PARSER
-from pyparser.tuplebuilder import TupleBuilder
+from pypy.interpreter import stablecompiler
+from pypy.interpreter.stablecompiler.pycodegen import ModuleCodeGenerator
+from pypy.interpreter.stablecompiler.pycodegen import InteractiveCodeGenerator
+from pypy.interpreter.stablecompiler.pycodegen import ExpressionCodeGenerator
+from pypy.interpreter.stablecompiler.transformer import Transformer
 from pyparser.pythonutil import ast_from_input
-import compiler
 
 class PythonCompiler(CPythonCompiler):
     """Uses the stdlib's python implementation of compiler
@@ -190,8 +188,9 @@
         flags |= __future__.generators.compiler_flag   # always on (2.2 compat)
         space = self.space
         try:
-            tree = ast_from_input(source, mode)
-            compiler.misc.set_filename(filename, tree)
+            transformer = Transformer()
+            tree = ast_from_input(source, mode, transformer)
+            stablecompiler.misc.set_filename(filename, tree)
             if mode == 'exec':
                 codegenerator = ModuleCodeGenerator(tree)
             elif mode == 'single':

Modified: pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/ebnfparse.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/ebnfparse.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/ebnfparse.py	Tue Jul  5 12:03:38 2005
@@ -8,7 +8,10 @@
 
 punct=['>=', '<>', '!=', '<', '>', '<=', '==', '\\*=',
        '//=', '%=', '^=', '<<=', '\\*\\*=', '\\', '=',
-       '\\+=', '>>=', '=', '&=', '/=', '-=', '\n,', '^', '>>', '&', '\\+', '\\*', '-', '/', '\\.', '\\*\\*', '%', '<<', '//', '\\', '', '\n\\)', '\\(', ';', ':', '@', '\\[', '\\]', '`', '\\{', '\\}']
+       '\\+=', '>>=', '=', '&=', '/=', '-=', '\n,', '^',
+       '>>', '&', '\\+', '\\*', '-', '/', '\\.', '\\*\\*',
+       '%', '<<', '//', '\\', '', '\n\\)', '\\(', ';', ':',
+       '@', '\\[', '\\]', '`', '\\{', '\\}']
 
 py_punct = re.compile(r"""
 >=|<>|!=|<|>|<=|==|~|
@@ -77,17 +80,16 @@
         self.items = []
         self.terminals['NAME'] = NameToken()
 
-    def new_name( self ):
+    def new_name(self):
         rule_name = ":%s_%s" % (self.current_rule, self.current_subrule)
         self.current_subrule += 1
         return rule_name
 
-    def new_item( self, itm ):
-        self.items.append( itm )
+    def new_item(self, itm):
+        self.items.append(itm)
         return itm
     
-    def visit_grammar( self, node ):
-        # print "Grammar:"
+    def visit_grammar(self, node):
         for rule in node.nodes:
             rule.visit(self)
         # the rules are registered already
@@ -103,23 +105,23 @@
         # XXX .keywords also contains punctuations
         self.terminals['NAME'].keywords = self.tokens.keys()
 
-    def visit_rule( self, node ):
+    def visit_rule(self, node):
         symdef = node.nodes[0].value
         self.current_rule = symdef
         self.current_subrule = 0
         alt = node.nodes[1]
         rule = alt.visit(self)
-        if not isinstance( rule, Token ):
+        if not isinstance(rule, Token):
             rule.name = symdef
         self.rules[symdef] = rule
         
-    def visit_alternative( self, node ):
-        items = [ node.nodes[0].visit(self) ]
+    def visit_alternative(self, node):
+        items = [node.nodes[0].visit(self)]
         items += node.nodes[1].visit(self)        
         if len(items) == 1 and items[0].name.startswith(':'):
             return items[0]
-        alt = Alternative( self.new_name(), items )
-        return self.new_item( alt )
+        alt = Alternative(self.new_name(), items)
+        return self.new_item(alt)
 
     def visit_sequence( self, node ):
         """ """
@@ -181,11 +183,14 @@
             rule_name = self.new_name()
             tok = star_opt.nodes[0].nodes[0]
             if tok.value == '+':
-                return self.new_item( KleenStar( rule_name, _min=1, rule = myrule ) )
+                item = KleenStar(rule_name, _min=1, rule=myrule)
+                return self.new_item(item)
             elif tok.value == '*':
-                return self.new_item( KleenStar( rule_name, _min=0, rule = myrule ) )
+                item = KleenStar(rule_name, _min=0, rule=myrule)
+                return self.new_item(item)
             else:
-                raise SyntaxError("Got symbol star_opt with value='%s'" % tok.value )
+                raise SyntaxError("Got symbol star_opt with value='%s'"
+                                  % tok.value)
         return myrule
 
 rules = None

Modified: pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/grammar.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/grammar.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/grammar.py	Tue Jul  5 12:03:38 2005
@@ -78,8 +78,9 @@
 class BaseGrammarBuilder(object):
     """Base/default class for a builder"""
     def __init__(self, rules=None, debug=0):
-        self.rules = rules or {} # a dictionary of grammar rules for debug/reference
-        # XXX This attribute is here for convenience
+        # a dictionary of grammar rules for debug/reference
+        self.rules = rules or {}
+        # This attribute is here for convenience
         self.source_encoding = None
         self.debug = debug
         self.stack = []
@@ -166,8 +167,8 @@
         """
         if not USE_LOOKAHEAD:
             return self._match(source, builder, level)
-        pos1 = -1 # XXX make the annotator happy
-        pos2 = -1 # XXX make the annotator happy
+        pos1 = -1 # make the annotator happy
+        pos2 = -1 # make the annotator happy
         token = source.peek()
         if self._trace:
             pos1 = source.get_pos()
@@ -242,9 +243,10 @@
     def debug_return(self, ret, *args ):
         # FIXME: use a wrapper of match() methods instead of debug_return()
         #        to prevent additional indirection
-        if ret and DEBUG>0:
+        if ret and DEBUG > 0:
             sargs = ",".join( [ str(i) for i in args ] )
-            print "matched %s (%s): %s" % (self.__class__.__name__, sargs, self.display() )
+            print "matched %s (%s): %s" % (self.__class__.__name__,
+                                           sargs, self.display() )
         return ret
 
     
@@ -268,8 +270,9 @@
         return other in self.first_set
 
     def reorder_rule(self):
-        """Called after the computation of first set to allow rules to be reordered
-        to avoid ambiguities"""
+        """Called after the computation of first set to allow rules to be
+        reordered to avoid ambiguities
+        """
         pass
 
 class Alternative(GrammarElement):
@@ -285,7 +288,7 @@
         """If any of the rules in self.args matches
         returns the object built from the first rules that matches
         """
-        if DEBUG>1:
+        if DEBUG > 1:
             print "try alt:", self.display()
         tok = source.peek()
         # Here we stop at the first match we should
@@ -304,7 +307,7 @@
         return 0
 
     def display(self, level=0):
-        if level==0:
+        if level == 0:
             name =  self.name + " -> "
         elif not self.name.startswith(":"):
             return self.name
@@ -344,12 +347,13 @@
                 # a same alternative
                 for token in rule.first_set:
                     if token is not EmptyToken and token in tokens_set:
-                        print "Warning, token %s in\n\t%s's first set is part " \
-                              "of a previous rule's first set in alternative\n\t" \
-                              "%s" % (token, rule, self)
+                        print "Warning, token %s in\n\t%s's first set is " \
+                            " part of a previous rule's first set in " \
+                            " alternative\n\t%s" % (token, rule, self)
                     tokens_set.append(token)
         if len(empty_set) > 1 and not self._reordered:
-            print "Warning: alternative %s has more than one rule matching Empty" % self
+            print "Warning: alternative %s has more than one rule " \
+                "matching Empty" % self
             self._reordered = True
         self.args[:] = not_empty_set
         self.args.extend( empty_set )
@@ -365,7 +369,7 @@
 
     def _match(self, source, builder, level=0):
         """matches all of the symbols in order"""
-        if DEBUG>1:
+        if DEBUG > 1:
             print "try seq:", self.display()
         ctx = source.context()
         bctx = builder.context()
@@ -381,7 +385,7 @@
         return self.debug_return( ret )
 
     def display(self, level=0):
-        if level == 0:
+        if level ==  0:
             name = self.name + " -> "
         elif not self.name.startswith(":"):
             return self.name
@@ -431,9 +435,11 @@
             # self.first_set[EmptyToken] = 1
 
     def _match(self, source, builder, level=0):
-        """matches a number of times self.args[0]. the number must be comprised
-        between self._min and self._max inclusive. -1 is used to represent infinity"""
-        if DEBUG>1:
+        """matches a number of times self.args[0]. the number must be
+        comprised between self._min and self._max inclusive. -1 is used to
+        represent infinity
+        """
+        if DEBUG > 1:
             print "try kle:", self.display()
         ctx = source.context()
         bctx = builder.context()
@@ -507,7 +513,6 @@
         """
         ctx = source.context()
         tk = source.next()
-        # XXX: match_token
         if tk.name == self.name:
             if self.value is None:
                 ret = builder.token( tk.name, tk.value, source )
@@ -515,7 +520,7 @@
             elif self.value == tk.value:
                 ret = builder.token( tk.name, tk.value, source )
                 return self.debug_return( ret, tk.name, tk.value )
-        if DEBUG>1:
+        if DEBUG > 1:
             print "tried tok:", self.display()
         source.restore( ctx )
         return 0
@@ -534,9 +539,6 @@
            must be equal
          - a tuple, such as those yielded by the Python lexer, in which case
            the comparison algorithm is similar to the one in match()
-           XXX:
-             1/ refactor match and __eq__ ?
-             2/ make source.next and source.peek return a Token() instance
         """
         if not isinstance(other, Token):
             raise RuntimeError("Unexpected token type %r" % other)

Modified: pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/pythonlexer.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/pythonlexer.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/pythonlexer.py	Tue Jul  5 12:03:38 2005
@@ -2,8 +2,9 @@
 it obeys the TokenSource interface defined for the grammar
 analyser in grammar.py
 """
+import symbol
 
-from grammar import TokenSource, Token
+from pypy.interpreter.pyparser.grammar import TokenSource, Token
 # Don't import string for that ...
 NAMECHARS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_'
 NUMCHARS = '0123456789'
@@ -72,10 +73,13 @@
 
 class TokenError(SyntaxError):
     """Raised when EOF is found prematuerly"""
-    def __init__(self, msg, strstart, token_stack):
+    def __init__(self, msg, line, strstart, token_stack):
         self.lineno, self.offset = strstart
-        self.text = "XXX"
-        self.msg = "TokenError at pos (%d, %d)" % (self.lineno, self.offset)
+        self.text = line
+        self.errlabel = msg
+        self.msg = "TokenError at pos (%d, %d) in %r" % (self.lineno,
+                                                         self.offset,
+                                                         line)
         self.token_stack = token_stack
 
 def generate_tokens(lines):
@@ -109,17 +113,20 @@
     last_comment = ''
     encoding = None
     strstart = (0, 0)
+    # make the annotator happy
     pos = -1
     lines.append('') # XXX HACK probably not needed
-    endDFA = automata.DFA([], []) # XXX Make the translator happy
-    line = ''                 # XXX Make the translator happy
+    # make the annotator happy
+    endDFA = automata.DFA([], [])
+    # make the annotator happy
+    line = ''
     for line in lines:
         lnum = lnum + 1
         pos, max = 0, len(line)
 
         if contstr:                            # continued string
             if not line:
-                raise TokenError("EOF in multi-line string", strstart,
+                raise TokenError("EOF in multi-line string", line, strstart,
                                  token_list)
             endmatch = endDFA.recognize(line)
             if -1 != endmatch:
@@ -169,9 +176,6 @@
                     last_comment = ''
                 # XXX Skip NL and COMMENT Tokens
                 # token_list.append((tok, line, lnum, pos))
-                # token_list.append(((NL, COMMENT)[line[pos] == '#'],
-                #                    line[pos:],
-                #                    (lnum, pos), (lnum, len(line)), line))
                 continue
 
             if column > indents[-1]:           # count indents or dedents
@@ -179,17 +183,15 @@
                 tok = token_from_values(tokenmod.INDENT, line[:pos])
                 token_list.append((tok, line, lnum, pos))
                 last_comment = ''
-                # token_list.append((INDENT, line[:pos],(lnum, 0),(lnum,pos),line))
             while column < indents[-1]:
                 indents = indents[:-1]
                 tok = token_from_values(tokenmod.DEDENT, '')
                 token_list.append((tok, line, lnum, pos))
                 last_comment = ''
-                # token_list.append((DEDENT, '', (lnum, pos),(lnum,pos),line))
-
         else:                                  # continued statement
             if not line:
-                raise TokenError("EOF in multi-line statement", (lnum, 0), token_list)
+                raise TokenError("EOF in multi-line statement", line,
+                                 (lnum, 0), token_list)
             continued = 0
 
         while pos < max:
@@ -209,7 +211,6 @@
                     tok = token_from_values(tokenmod.NUMBER, token)
                     token_list.append((tok, line, lnum, pos))
                     last_comment = ''
-                    # token_list.append((NUMBER, token, spos, epos, line))
                 elif initial in '\r\n':
                     if parenlev > 0:
                         tok = token_from_values(tokenmod.NL, token)
@@ -221,7 +222,6 @@
                         tok.value = last_comment
                         token_list.append((tok, line, lnum, pos))
                         last_comment = ''
-                    # token_list.append((parenlev > 0 and NL or NEWLINE, token, spos, epos, line))
                 elif initial == '#':
                     tok = token_from_values(tokenmod.COMMENT, token)
                     last_comment = token
@@ -240,7 +240,6 @@
                         tok = token_from_values(tokenmod.STRING, token)
                         token_list.append((tok, line, lnum, pos))
                         last_comment = ''
-                        # token_list.append((STRING, token, spos, (lnum, pos), line))
                     else:
                         strstart = (lnum, start)           # multiple lines
                         contstr = line[start:]
@@ -265,36 +264,34 @@
                     tok = token_from_values(tokenmod.NAME, token)
                     token_list.append((tok, line, lnum, pos))
                     last_comment = ''
-                    # token_list.append((NAME, token, spos, epos, line))
                 elif initial == '\\':                      # continued stmt
                     continued = 1
                 else:
-                    if initial in '([{': parenlev = parenlev + 1
-                    elif initial in ')]}': parenlev = parenlev - 1
+                    if initial in '([{':
+                        parenlev = parenlev + 1
+                    elif initial in ')]}':
+                        parenlev = parenlev - 1
                     tok = token_from_values(tokenmod.OP, token)
                     token_list.append((tok, line, lnum, pos)) 
                     last_comment = ''
-                    # token_list.append((OP, token, spos, epos, line))
             else:
                 tok = token_from_values(tokenmod.ERRORTOKEN, line[pos])
                 token_list.append((tok, line, lnum, pos))
                 last_comment = ''
-                # token_list.append((ERRORTOKEN, line[pos],
-                #                    (lnum, pos), (lnum, pos+1), line))
                 pos = pos + 1
 
-    last_comment = ''
+    lnum -= 1
     for indent in indents[1:]:                 # pop remaining indent levels
         tok = token_from_values(tokenmod.DEDENT, '')
         token_list.append((tok, line, lnum, pos))
-        # token_list.append((DEDENT, '', (lnum, 0), (lnum, 0), ''))
-
-    ## <XXX> adim
-    token_list.append((Token('NEWLINE', ''), line, lnum, 0))
+        
+    ## <XXX> adim: this can't be (only) that, can it ?
+    if token_list and token_list[-1] != symbol.file_input:
+        token_list.append((Token('NEWLINE', ''), '\n', lnum, 0))
     ## </XXX>
     tok = token_from_values(tokenmod.ENDMARKER, '',)
     token_list.append((tok, line, lnum, pos))
-    # token_list.append((ENDMARKER, '', (lnum, 0), (lnum, 0), ''))
+
     return token_list, encoding
 
 class PythonSource(TokenSource):
@@ -324,6 +321,10 @@
         """Returns the current line being parsed"""
         return self._current_line
 
+    def current_lineno(self):
+        """Returns the current lineno"""
+        return self._lineno
+
     def context(self):
         """Returns an opaque context object for later restore"""
         return self.stack_pos
@@ -362,11 +363,11 @@
         return (self._current_line, self._lineno)
         # return 'line %s : %s' % ('XXX', self._current_line)
 
-NONE_LIST = [tokenmod.ENDMARKER, tokenmod.INDENT, tokenmod.DEDENT,]
-NAMED_LIST = [tokenmod.OP, ]
+NONE_LIST = [tokenmod.ENDMARKER, tokenmod.INDENT, tokenmod.DEDENT]
+NAMED_LIST = [tokenmod.OP]
 
 def token_from_values(tok_type, tok_string):
-    """XXX Compatibility layer between both parsers"""
+    """Compatibility layer between both parsers"""
     if tok_type in NONE_LIST:
         return Token(tokenmod.tok_name[tok_type], None)
     if tok_type in NAMED_LIST:

Modified: pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/pythonparse.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/pythonparse.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/pythonparse.py	Tue Jul  5 12:03:38 2005
@@ -6,29 +6,107 @@
 using file_input, single_input and eval_input targets
 """
 from pypy.interpreter.error import OperationError, debug_print
+from pypy.tool.option import Options
 
 from pythonlexer import Source
 import ebnfparse
 import sys
 import os
 import grammar
+import symbol
 
-# parse the python grammar corresponding to our CPython version
-_ver = ".".join([str(i) for i in sys.version_info[:2]])
-PYTHON_GRAMMAR = os.path.join( os.path.dirname(__file__), "data", "Grammar" + _ver )
+class PythonParser(object):
+    """Wrapper class for python grammar"""
+    def __init__(self, grammar_builder):
+        self.items = grammar_builder.items
+        self.rules = grammar_builder.rules
+        # Build first sets for each rule (including anonymous ones)
+        grammar.build_first_sets(self.items)
+
+    def parse_source(self, textsrc, goal, builder=None):
+        """Parse a python source according to goal"""
+        lines = [line + '\n' for line in textsrc.split('\n')]
+        if textsrc == '\n':
+            lines.pop()
+        else:
+            last_line = lines[-1]
+            lines[-1] = last_line[:-1]
+        return self.parse_lines(lines, goal, builder)
+
+    def parse_lines(self, lines, goal, builder=None):
+        target = self.rules[goal]
+        src = Source(lines)
+        
+        if builder is None:
+            builder = grammar.BaseGrammarBuilder(debug=False, rules=self.rules)
+        result = target.match(src, builder)
+        # <HACK> XXX find a clean way to process encoding declarations
+        builder.source_encoding = src.encoding
+        # </HACK>
+        if not result:
+            # raising a SyntaxError here is not annotable, and it can
+            # probably be handled in an other way
+            line, lineno = src.debug()
+            raise BuilderError(line, lineno)
+            # return None
+        return builder
+
+PYTHON_VERSION = ".".join([str(i) for i in sys.version_info[:2]])
+def get_grammar_file( version ):
+    """returns the python grammar corresponding to our CPython version"""
+    if version == "native":
+        _ver = PYTHON_VERSION
+    elif version in ("2.3","2.4"):
+        _ver = version
+    return os.path.join( os.path.dirname(__file__), "data", "Grammar" + _ver ), _ver
 
-def python_grammar():
-    """returns a """
+# unfortunately the command line options are not parsed yet
+PYTHON_GRAMMAR, PYPY_VERSION = get_grammar_file( Options.version )
+
+def python_grammar(fname):
+    """returns a PythonParser build from the specified grammar file"""
     level = grammar.DEBUG
     grammar.DEBUG = 0
-    gram = ebnfparse.parse_grammar( file(PYTHON_GRAMMAR) )
+    gram = ebnfparse.parse_grammar( file(fname) )
     grammar.DEBUG = level
-    # Build first sets for each rule (including anonymous ones)
-    grammar.build_first_sets(gram.items)
-    return gram
+    return PythonParser(gram)
 
 debug_print( "Loading grammar %s" % PYTHON_GRAMMAR )
-PYTHON_PARSER = python_grammar()
+PYTHON_PARSER = python_grammar( PYTHON_GRAMMAR )
+_symbols = symbol.sym_name.keys()
+_symbols.sort()
+
+def add_symbol( sym ):
+    if not hasattr(symbol, sym):
+        nextval = _symbols[-1] + 1
+        setattr(symbol, sym, nextval)
+        _symbols.append(nextval)
+        symbol.sym_name[nextval] = sym
+        return nextval
+    return 0
+
+def reload_grammar( version ):
+    """helper function to test with pypy different grammars"""
+    global PYTHON_GRAMMAR, PYTHON_PARSER, PYPY_VERSION
+    PYTHON_GRAMMAR, PYPY_VERSION = get_grammar_file( version )
+    debug_print( "Reloading grammar %s" % PYTHON_GRAMMAR )
+    PYTHON_PARSER = python_grammar( PYTHON_GRAMMAR )
+    for rule in PYTHON_PARSER.rules:
+        add_symbol( rule )
+    
+
+for rule in PYTHON_PARSER.rules:
+    add_symbol( rule )
+
+
+SYMBOLS = {}
+# copies the numerical mapping between symbol name and symbol value
+# into SYMBOLS
+for k, v in symbol.sym_name.items():
+    SYMBOLS[v] = k
+SYMBOLS['UNKNOWN'] = -1
+
+
 
 class BuilderError(SyntaxError):
     def __init__(self, line, lineno):
@@ -38,32 +116,14 @@
         self.offset = -1
         self.msg = "SyntaxError at line %d: %r" % (self.lineno, self.line)
 
-def parse_python_source(textsrc, gram, goal, builder=None):
-    """Parse a python source according to goal"""
-    target = gram.rules[goal]
-    src = Source(textsrc)
-    if builder is None:
-        builder = grammar.BaseGrammarBuilder(debug=False, rules=gram.rules)
-    result = target.match(src, builder)
-    # <HACK> XXX find a clean way to process encoding declarations
-    builder.source_encoding = src.encoding
-    # </HACK>
-    if not result:
-        # raising a SyntaxError here is not annotable, and it can
-        # probably be handled in an other way
-        line, lineno = src.debug()
-        raise BuilderError(line, lineno)
-        # return None
-    return builder
-
 def parse_file_input(pyf, gram, builder=None):
     """Parse a python file"""
-    return parse_python_source( pyf.read(), gram, "file_input", builder )
+    return gram.parse_source( pyf.read(), "file_input", builder )
     
 def parse_single_input(textsrc, gram, builder=None):
     """Parse a python single statement"""
-    return parse_python_source( textsrc, gram, "single_input", builder )
+    return gram.parse_source( textsrc, "single_input", builder )
 
 def parse_eval_input(textsrc, gram, builder=None):
     """Parse a python expression"""
-    return parse_python_source( textsrc, gram, "eval_input", builder )
+    return gram.parse_source( textsrc, "eval_input", builder )

Modified: pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/pythonutil.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/pythonutil.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/pythonutil.py	Tue Jul  5 12:03:38 2005
@@ -1,7 +1,6 @@
 __all__ = ["python_parse", "pypy_parse", "ast_single_input", "ast_file_input",
-           "ast_eval_input" ]
+           "ast_eval_input"]
 
-from compiler.transformer import Transformer
 import parser
 import symbol
 
@@ -12,7 +11,7 @@
 TARGET_DICT = {
     'exec'   : "file_input",
     'eval'   : "eval_input",
-    'single' : "single_input",
+    'single' : "file_input",
     }
 
 ## convenience functions around CPython's parser functions
@@ -28,11 +27,11 @@
     """parse python source using CPython's parser module and return
     nested tuples
     """
-    if mode == 'exec':
-        tp = parser.suite(source)
-    else:
+    if mode == 'eval':
         tp = parser.expr(source)
-    return tp.totuple()
+    else:
+        tp = parser.suite(source)
+    return parser.ast2tuple(tp, line_info=lineno)
 
 ## convenience functions around recparser functions
 def pypy_parsefile(filename, lineno=False):
@@ -63,24 +62,11 @@
     nested tuples
     """
     builder = TupleBuilder(PYTHON_PARSER.rules, lineno=False)
-    # make the annotator life easier (don't use str.splitlines())
-    strings = [line + '\n' for line in source.split('\n')]
-    # finalize the last line 
-    if not source.endswith('\n'):
-        last_line = strings[-1]
-        strings[-1] = last_line[:-1]
-    else:
-        strings.pop()
     target_rule = TARGET_DICT[mode]
-    pythonparse.parse_python_source(strings, PYTHON_PARSER,
-                                    target_rule, builder)
-##     if builder.error_occured():
-##         line, lineno, offset, filename = builder.get_error()
-##         raise SyntaxError(line, lineno, offset, filename)
-##     # stack_element is a tuplerbuilder.StackElement's instance
+    PYTHON_PARSER.parse_source(source, target_rule, builder)
     stack_element = builder.stack[-1]
-    # convert the stack element into nested tuples
-    # XXX : the annotator can't follow this call
+    # convert the stack element into nested tuples (caution, the annotator
+    # can't follow this call)
     nested_tuples = stack_element.as_tuple(lineno)
     if builder.source_encoding is not None:
         return (symbol.encoding_decl, nested_tuples, builder.source_encoding)
@@ -88,14 +74,23 @@
         return nested_tuples
 
 ## convenience functions for computing AST objects using recparser
-def ast_from_input(input, mode):
+def ast_from_input(input, mode, transformer):
+    """converts a source input into an AST
+
+     - input : the source to be converted
+     - mode : 'exec', 'eval' or 'single'
+     - transformer : the transfomer instance to use to convert
+                     the nested tuples into the AST
+     XXX: transformer could be instantiated here but we don't want
+          here to explicitly import compiler or stablecompiler or
+          etc. This is to be fixed in a clean way
+    """
     tuples = pypy_parse(input, mode, True)
-    transformer = Transformer()
     ast = transformer.compile_node(tuples)
     return ast
 
 ## TARGET FOR ANNOTATORS #############################################
-def annotateme(strings):
+def annotateme(source):
     """This function has no other role than testing the parser's annotation
 
     annotateme() is basically the same code that pypy_parse(), but with the
@@ -108,7 +103,7 @@
 
     """
     builder = TupleBuilder(PYTHON_PARSER.rules, lineno=False)
-    pythonparse.parse_python_source(strings, PYTHON_PARSER, 'file_input', builder)
+    PYTHON_PARSER.parse_source(source, 'file_input', builder)
     nested_tuples = builder.stack[-1]
     if builder.source_encoding is not None:
         return (symbol.encoding_decl, nested_tuples, builder.source_encoding)

Modified: pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/pytokenize.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/pytokenize.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/pytokenize.py	Tue Jul  5 12:03:38 2005
@@ -13,23 +13,21 @@
 expressions have been replaced with hand built DFA's using the
 basil.util.automata module.
 
-XXX This now assumes that the automata module is in the Python path.
-
 $Id: pytokenize.py,v 1.3 2003/10/03 16:31:53 jriehl Exp $
 """
 # ______________________________________________________________________
 
 from __future__ import generators
-import automata
+from pypy.interpreter.pyparser import automata
 
 # ______________________________________________________________________
 # COPIED:
-from token import *
-
 import token
 __all__ = [x for x in dir(token) if x[0] != '_'] + ["COMMENT", "tokenize",
            "generate_tokens", "NL"]
 del x
+N_TOKENS = token.N_TOKENS
+tok_name = token.tok_name
 del token
 
 COMMENT = N_TOKENS

Deleted: /pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/test/samples/snippet_only_one_comment.DISABLED
==============================================================================
--- /pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/test/samples/snippet_only_one_comment.DISABLED	Tue Jul  5 12:03:38 2005
+++ (empty file)
@@ -1 +0,0 @@
-# only one comment

Modified: pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/test/test_samples.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/test/test_samples.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/test/test_samples.py	Tue Jul  5 12:03:38 2005
@@ -9,8 +9,19 @@
     pypy_parsefile, python_parse, pypy_parse
 from pypy.interpreter.pyparser import grammar
 from pypy.interpreter.pyparser.pythonlexer import TokenError
+from pypy.interpreter.pyparser.pythonparse import PYTHON_VERSION, PYPY_VERSION
 grammar.DEBUG = False
 
+
+# these samples are skipped if the native version of Python does not match
+# the version of the grammar we use
+GRAMMAR_MISMATCH = PYTHON_VERSION != PYPY_VERSION
+SKIP_IF_NOT_NATIVE = [
+    "snippet_samples.py",
+    "snippet_import_statements.py",
+]
+
+
 def name(elt):
     return "%s[%s]"% (sym_name.get(elt,elt),elt)
 
@@ -50,11 +61,14 @@
 
 def test_samples():
     samples_dir = osp.join(osp.dirname(__file__), 'samples')
+    # samples_dir = osp.dirname(os.__file__)
     for use_lookahead in (True, False):
         grammar.USE_LOOKAHEAD = use_lookahead
         for fname in os.listdir(samples_dir):
             if not fname.endswith('.py'):
-            # if fname != 'snippet_simple_assignment.py':
+                continue
+            if GRAMMAR_MISMATCH and fname in SKIP_IF_NOT_NATIVE:
+                print "Skipping", fname
                 continue
             abspath = osp.join(samples_dir, fname)
             yield check_parse, abspath
@@ -78,9 +92,9 @@
     _check_tuples_equality(pypy_tuples, python_tuples, filepath)
 
 
-def check_parse_input(snippet, mode):
-    pypy_tuples = pypy_parse(snippet, mode)
-    python_tuples = python_parse(snippet, mode)
+def check_parse_input(snippet, mode, lineno=False):
+    pypy_tuples = pypy_parse(snippet, mode, lineno)
+    python_tuples = python_parse(snippet, mode, lineno)
     _check_tuples_equality(pypy_tuples, python_tuples, snippet)
 
 def test_eval_inputs():
@@ -90,7 +104,8 @@
         'True and False',
         ]
     for snippet in snippets:
-        yield check_parse_input, snippet, 'eval'
+        yield check_parse_input, snippet, 'eval', True
+        yield check_parse_input, snippet, 'eval', False
 
 def test_exec_inputs():
     snippets = [
@@ -98,8 +113,16 @@
         'print 6*7', 'if 1:\n  x\n',
         ]
     for snippet in snippets:
-        yield check_parse_input, snippet, 'exec'
+        yield check_parse_input, snippet, 'exec', True
+        yield check_parse_input, snippet, 'exec', False        
+
+def test_single_inputs():
+    snippets = ['a=1', 'True', 'def f(a):\n    return a+1\n\n']
+    for snippet in snippets:
+        yield check_parse_input, snippet, 'single', True
+        yield check_parse_input, snippet, 'single', False        
 
+    
 def test_bad_inputs():
     inputs = ['x = (', 'x = (\n', 'x = (\n\n']
     for inp in inputs:

Modified: pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/tuplebuilder.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/tuplebuilder.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/interpreter/pyparser/tuplebuilder.py	Tue Jul  5 12:03:38 2005
@@ -1,6 +1,7 @@
 
 from grammar import BaseGrammarBuilder
-from syntaxtree import TOKEN_MAP, SYMBOLS # , NT_OFFSET
+from syntaxtree import TOKEN_MAP # , NT_OFFSET
+from pythonparse import SYMBOLS
 
 class StackElement:
     """wraps TupleBuilder's tuples"""
@@ -87,14 +88,11 @@
 
     def token(self, name, value, source):
         num = TOKEN_MAP.get(name, -1)
-        lineno = source.current_line()
+        lineno = source.current_lineno()
         if value is None:
             if name not in ("NEWLINE", "INDENT", "DEDENT", "ENDMARKER"):
                 value = name
             else:
                 value = ''
-        if self.lineno:
-            self.stack.append( Terminal(num, value, lineno) )
-        else:
-            self.stack.append( Terminal(num, value, -1) )
+        self.stack.append( Terminal(num, value, lineno) )
         return True

Modified: pypy/branch/dist-2.4.1/pypy/interpreter/test/test_compiler.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/interpreter/test/test_compiler.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/interpreter/test/test_compiler.py	Tue Jul  5 12:03:38 2005
@@ -48,6 +48,16 @@
         flags2 = self.compiler.getcodeflags(code2)
         assert flags == flags2
 
+    def test_interactivemode(self):
+        code = self.compiler.compile('a = 1', '<hello>', 'single', 0)
+        assert isinstance(code, PyCode)
+        assert code.co_filename == '<hello>'
+        space = self.space
+        w_globals = space.newdict([])
+        code.exec_code(space, w_globals, w_globals)
+        w_a = space.getitem(w_globals, space.wrap('a'))
+        assert space.int_w(w_a) == 1
+
 
 class TestECCompiler(BaseTestCompiler):
     def setup_method(self, method):
@@ -64,3 +74,4 @@
 class SkippedForNowTestPyPyCompiler(BaseTestCompiler):
     def setup_method(self, method):
         self.compiler = PyPyCompiler(self.space)
+

Modified: pypy/branch/dist-2.4.1/pypy/interpreter/test/test_interpreter.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/interpreter/test/test_interpreter.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/interpreter/test/test_interpreter.py	Tue Jul  5 12:03:38 2005
@@ -1,4 +1,6 @@
 import py 
+import sys
+from pypy.interpreter.pycompiler import PythonCompiler
 
 class TestInterpreter: 
     def codetest(self, source, functionname, args):
@@ -13,7 +15,6 @@
         w = space.wrap
         w_code = space.builtin.call('compile', 
                 w(source), w('<string>'), w('exec'), w(0), w(0))
-        ec = executioncontext.ExecutionContext(space)
 
         tempmodule = module.Module(space, w("__temp__"))
         w_glob = tempmodule.w_dict
@@ -226,6 +227,20 @@
         assert self.codetest(code, 'g', [12, {}]) ==    ()
         assert self.codetest(code, 'g', [12, {3:1}]) == (3,)
 
+class TestPyPyInterpreter(TestInterpreter):
+    """Runs the previous test with the pypy parser"""
+    def setup_class(klass):
+        sys.setrecursionlimit(10000)
+
+    def setup_method(self,arg):
+        ec = self.space.getexecutioncontext() 
+        self.saved_compiler = ec.compiler
+        ec.compiler = PythonCompiler(self.space)
+
+    def teardown_method(self,arg):
+        ec = self.space.getexecutioncontext() 
+        ec.compiler = self.saved_compiler
+
 class AppTestInterpreter: 
     def test_trivial(self):
         x = 42
@@ -258,3 +273,4 @@
     def test_identity(self):
         def f(x): return x
         assert f(666) == 666
+

Modified: pypy/branch/dist-2.4.1/pypy/lib/binascii.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/lib/binascii.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/lib/binascii.py	Tue Jul  5 12:03:38 2005
@@ -1,64 +1,66 @@
 class Error(Exception):
     pass
 
+class Apa(Exception):
+    pass
+
 class Incomplete(Exception):
     pass
 
 def a2b_uu(s):
     length = (ord(s[0]) - 0x20) % 64
-    a = quadruplets(s[1:].rstrip())
+
+    def quadruplets_gen(s):
+        while s:
+            try:
+                yield ord(s[0]), ord(s[1]), ord(s[2]), ord(s[3])
+            except IndexError:
+                s += '   '
+                yield ord(s[0]), ord(s[1]), ord(s[2]), ord(s[3])
+                return
+            s = s[4:]
+
     try:
         result = [''.join(
             [chr((A - 0x20) << 2 | (((B - 0x20) >> 4) & 0x3)),
-            chr(((B - 0x20) & 0xF) << 4 | (((C - 0x20) >> 2) & 0xF)),
-            chr(((C - 0x20) & 0x3) << 6 | ((D - 0x20) & 0x3F))
-            ]) for A, B, C, D in a]
+            chr(((B - 0x20) & 0xf) << 4 | (((C - 0x20) >> 2) & 0xf)),
+            chr(((C - 0x20) & 0x3) << 6 | ((D - 0x20) & 0x3f))
+            ]) for A, B, C, D in quadruplets_gen(s[1:].rstrip())]
     except ValueError:
-        raise Error, 'Illegal char'
+        raise Error('Illegal char')
     result = ''.join(result)
     trailingdata = result[length:]
     if trailingdata.strip('\x00'):
-        raise Error, 'Trailing garbage'
+        raise Error('Trailing garbage')
     result = result[:length]
     if len(result) < length:
         result += ((length - len(result)) * '\x00')
     return result
 
-def quadruplets(s):
-    while s:
-        try:
-            a, b, c, d = s[0], s[1], s[2], s[3]
-        except IndexError:
-            s += '   '
-            yield ord(s[0]), ord(s[1]), ord(s[2]), ord(s[3])
-            return
-        s = s[4:]
-        yield ord(a), ord(b), ord(c), ord(d)
                                
 def b2a_uu(s):
     length = len(s)
     if length > 45:
-        raise Error, 'At most 45 bytes at once'
+        raise Error('At most 45 bytes at once')
+
+    def triples_gen(s):
+        while s:
+            try:
+                yield ord(s[0]), ord(s[1]), ord(s[2])
+            except IndexError:
+                s += '\0\0'
+                yield ord(s[0]), ord(s[1]), ord(s[2])
+                return
+            s = s[3:]
 
-    a = triples(s)
     result = [''.join(
         [chr(0x20 + (( A >> 2                    ) & 0x3F)),
          chr(0x20 + (((A << 4) | ((B >> 4) & 0xF)) & 0x3F)),
          chr(0x20 + (((B << 2) | ((C >> 6) & 0x3)) & 0x3F)),
-         chr(0x20 + (( C                         ) & 0x3F))]) for A, B, C in a]
+         chr(0x20 + (( C                         ) & 0x3F))])
+              for A, B, C in triples_gen(s)]
     return chr(ord(' ') + (length & 077)) + ''.join(result) + '\n'
 
-def triples(s):
-    while s:
-        try:
-            a, b, c = s[0], s[1], s[2]
-        except IndexError:
-            s += '\0\0'
-            yield ord(s[0]), ord(s[1]), ord(s[2])
-            return
-        s = s[3:]
-        yield ord(a), ord(b), ord(c)
-
 
 table_a2b_base64 = {
     'A': 0,
@@ -127,11 +129,6 @@
     '/': 63,
 }
 
-def quadruplets_base64(s):
-    while s:
-        a, b, c, d = table_a2b_base64[s[0]], table_a2b_base64[s[1]], table_a2b_base64[s[2]], table_a2b_base64[s[3]]
-        s = s[4:]
-        yield a, b, c, d
 
 def a2b_base64(s):
     s = s.rstrip()
@@ -145,12 +142,19 @@
     if len(s) % 4:
         s = s + ('=' * (4 - len(s) % 4))
      
-    a = quadruplets_base64(s[:-4])
+    def quadruplets_gen(s):
+        while s:
+            yield (table_a2b_base64[s[0]],
+                   table_a2b_base64[s[1]],
+                   table_a2b_base64[s[2]],
+                   table_a2b_base64[s[3]])
+            s = s[4:]
+
     result = [
         chr(A << 2 | ((B >> 4) & 0x3)) + 
-        chr((B & 0xF) << 4 | ((C >> 2 ) & 0xF)) + 
+        chr((B & 0xf) << 4 | ((C >> 2 ) & 0xf)) + 
         chr((C & 0x3) << 6 | D )
-        for A, B, C, D in a]
+        for A, B, C, D in quadruplets_gen(s[:-4])]
 
     if s:
         final = s[-4:]
@@ -163,14 +167,14 @@
             B = table_a2b_base64[final[1]]
             C = table_a2b_base64[final[2]]
             snippet =  chr(A << 2 | ((B >> 4) & 0x3)) + \
-                    chr((B & 0xF) << 4 | ((C >> 2 ) & 0xF))
+                    chr((B & 0xf) << 4 | ((C >> 2 ) & 0xf))
         else:
             A = table_a2b_base64[final[0]]
             B = table_a2b_base64[final[1]]
             C = table_a2b_base64[final[2]]
             D = table_a2b_base64[final[3]]
             snippet =  chr(A << 2 | ((B >> 4) & 0x3)) + \
-                    chr((B & 0xF) << 4 | ((C >> 2 ) & 0xF)) + \
+                    chr((B & 0xf) << 4 | ((C >> 2 ) & 0xf)) + \
                     chr((C & 0x3) << 6 | D )
         result.append(snippet)
 
@@ -182,8 +186,19 @@
 def b2a_base64(s):
     length = len(s)
     final_length = length % 3
+
+    def triples_gen(s):
+        while s:
+            try:
+                yield ord(s[0]), ord(s[1]), ord(s[2])
+            except IndexError:
+                s += '\0\0'
+                yield ord(s[0]), ord(s[1]), ord(s[2])
+                return
+            s = s[3:]
+
     
-    a = triples(s[ :length - final_length])
+    a = triples_gen(s[ :length - final_length])
 
     result = [''.join(
         [table_b2a_base64[( A >> 2                    ) & 0x3F],
@@ -278,19 +293,20 @@
     else:
         sign = ''
     arr = []
-    for nibble in hexgen(n):
+
+    def hex_gen(n):
+        """ Yield a nibble at a time. """
+        while n:
+            yield n % 0x10
+            n = n / 0x10
+
+    for nibble in hex_gen(n):
         arr = [hex_numbers[nibble]] + arr
     return sign + ''.join(arr)
 
 def two_hex_digits(n):
     return hex_numbers[n / 0x10] + hex_numbers[n % 0x10]
     
-def hexgen(n):
-    """ Yield a nibble at a time. """
-    while n:
-        remainder = n % 0x10
-        n = n / 0x10
-        yield remainder
 
 def strhex_to_int(s):
     i = 0
@@ -299,46 +315,115 @@
     return i
 
 hqx_encoding = '!"#$%&\'()*+,-012345689 at ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr'
-# Make a fast lookup dictionary for decoding hqx
-hqx_decoding = {}
-for i, c in enumerate(hqx_encoding):
-    hqx_decoding[c] = i
+
+DONE = 0x7f
+SKIP = 0x7e
+FAIL = 0x7d
     
-def unpadded_quadruples(s):
-    while s:
-        yield s[:4]
-        s = s[4:]
+table_a2b_hqx = [
+    #^@    ^A    ^B    ^C    ^D    ^E    ^F    ^G   
+    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+    #\b    \t    \n    ^K    ^L    \r    ^N    ^O   
+    FAIL, FAIL, SKIP, FAIL, FAIL, SKIP, FAIL, FAIL,
+    #^P    ^Q    ^R    ^S    ^T    ^U    ^V    ^W   
+    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+    #^X    ^Y    ^Z    ^[    ^\    ^]    ^^    ^_   
+    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+    #      !     "     #     $     %     &     '   
+    FAIL, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+    #(     )     *     +     ,     -     .     /   
+    0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, FAIL, FAIL,
+    #0     1     2     3     4     5     6     7   
+    0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, FAIL,
+    #8     9     :     ;     <     =     >     ?   
+    0x14, 0x15, DONE, FAIL, FAIL, FAIL, FAIL, FAIL,
+    #@     A     B     C     D     E     F     G   
+    0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
+    #H     I     J     K     L     M     N     O   
+    0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, FAIL,
+    #P     Q     R     S     T     U     V     W   
+    0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, FAIL,
+    #X     Y     Z     [     \     ]     ^     _   
+    0x2C, 0x2D, 0x2E, 0x2F, FAIL, FAIL, FAIL, FAIL,
+    #`     a     b     c     d     e     f     g   
+    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, FAIL,
+    #h     i     j     k     l     m     n     o   
+    0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, FAIL, FAIL,
+    #p     q     r     s     t     u     v     w   
+    0x3D, 0x3E, 0x3F, FAIL, FAIL, FAIL, FAIL, FAIL,
+    #x     y     z     {     |     }     ~    ^?   
+    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
+]
 
 def a2b_hqx(s):
-    decoded = []
-    for c in s:
-        decoded.append(hqx_decoding[c])
-    gen = unpadded_quadruples(decoded)
     result = []
-    for snippet in gen:
-        length = len(snippet)
-        if length == 4:
-            result.append(chr((snippet[0] << 2) | (snippet[1] >> 6))) 
-            result.append(chr((snippet[1] << 4) | (snippet[2] >> 4))) 
-            result.append(chr((snippet[2] << 6) | (snippet[3]))) 
-        elif length == 3:
-            result.append(chr((snippet[0] << 2) | (snippet[1] >> 6))) 
-            result.append(chr((snippet[1] << 4) | (snippet[2] >> 4))) 
-        elif length == 2:
-            result.append(chr((snippet[0] << 2) | (snippet[1] >> 6))) 
-        else:
-            raise TypeError('Wrong number of characters.')
-    return ''.join(result)
 
-def unpadded_triples(s):
-    while s:
-        yield [ord(c) for c in s[:3]]
-        s = s[3:]
+    def quadruples_gen(s):
+        t = []
+        for c in s:
+            res = table_a2b_hqx[ord(c)]
+            if res == SKIP:
+                continue
+            elif res == FAIL:
+                raise Error('Illegal character')
+            elif res == DONE:
+                yield t
+                print 'raising'
+                raise Apa
+            else:
+                t.append(res)
+            if len(t) == 4:
+                yield t
+                t = []
+        yield t
+        
+    done = 0
+    try:
+        for snippet in quadruples_gen(s):
+            length = len(snippet)
+            if length == 4:
+                result.append(chr(((snippet[0] & 0x3f) << 2) | (snippet[1] >> 4))) 
+                result.append(chr(((snippet[1] & 0x0f) << 4) | (snippet[2] >> 2))) 
+                result.append(chr(((snippet[2] & 0x03) << 6) | (snippet[3]))) 
+            elif length == 3:
+                result.append(chr(((snippet[0] & 0x3f) << 2) | (snippet[1] >> 4))) 
+                result.append(chr(((snippet[1] & 0x0f) << 4) | (snippet[2] >> 2))) 
+            elif length == 2:
+                result.append(chr(((snippet[0] & 0x3f) << 2) | (snippet[1] >> 4))) 
+    except Apa:
+        done = 1
+    except Error:
+        raise
+    return (''.join(result), done)
 
 def b2a_hqx(s):
     result =[]
-    gen = unpadded_triples(s)
-    for snippet in gen:
+
+    def triples_gen(s):
+        while s:
+            try:
+                yield ord(s[0]), ord(s[1]), ord(s[2])
+            except IndexError:
+                yield tuple([ord(c) for c in s])
+            s = s[3:]
+
+    for snippet in triples_gen(s):
         length = len(snippet)
         if length == 3:
             result.append(
@@ -399,11 +484,16 @@
 
 def crc_hqx(s, crc):
     for c in s:
-        crc=((crc << 8) & 0xff00) ^ crctab_hqx[((crc >> 8) & 0xff) ^ c]
+        crc = ((crc << 8) & 0xff00) ^ crctab_hqx[((crc >> 8) & 0xff) ^ ord(c)]
 
     return crc
 
 def rlecode_hqx(s):
+    """
+    Run length encoding for binhex4.
+    The CPython implementation does not do run length encoding
+    of \x90 characters. This implementation does.
+    """
     result = []
     prev = s[0]
     count = 1
@@ -558,16 +648,14 @@
     def pairs_gen(s):
         while s:
             try:
-                a, b = s[0], s[1]
+                yield table_hex[ord(s[0])], table_hex[ord(s[1])]
             except IndexError:
                 if len(s):
                     raise TypeError('Odd-length string')
                 return
             s = s[2:]
-            yield table_hex[ord(a)], table_hex[ord(b)]
 
-    pairs = pairs_gen(t)
-    for a, b in pairs:
+    for a, b in pairs_gen(t):
         if a < 0 or b < 0:
             raise TypeError('Non-hexadecimal digit found')
         result.append(chr((a << 4) + b))

Modified: pypy/branch/dist-2.4.1/pypy/lib/struct.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/lib/struct.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/lib/struct.py	Tue Jul  5 12:03:38 2005
@@ -108,7 +108,7 @@
     if not isinstance(number, (int,long)):
         raise StructError,"argument for i,I,l,L,q,Q,h,H must be integer"
     if number > 2**(8*size-1)-1 or number < -1*2**(8*size-1):
-        raise OverflowError,"Number:%i to large to convert" % number
+        raise OverflowError,"Number:%i too large to convert" % number
     return pack_int(number,size,le)
 
 def pack_unsigned_int(number,size,le):
@@ -117,7 +117,7 @@
     if number < 0:
         raise TypeError,"can't convert negative long to unsigned"
     if number > 2**(8*size)-1:
-        raise OverflowError,"Number:%i to large to convert" % number
+        raise OverflowError,"Number:%i too large to convert" % number
     return pack_int(number,size,le)
     
 def pack_char(char,size,le):

Modified: pypy/branch/dist-2.4.1/pypy/objspace/std/longobject.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/objspace/std/longobject.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/objspace/std/longobject.py	Tue Jul  5 12:03:38 2005
@@ -91,9 +91,9 @@
     return W_LongObject(w_intobj.space, digits, sign)
 
 # long-to-float delegation
-def delegate_Long2Float(w_longobj): #YYYYYY
+def delegate_Long2Float(w_longobj):
     try:
-        return W_FloatObject(w_longobj.space, float(w_longobj.longval()))
+        return W_FloatObject(w_longobj.space, _AsDouble(w_longobj))
     except OverflowError:
         raise OperationError(w_longobj.space.w_OverflowError,
                              w_longobj.space.wrap("long int too large to convert to float"))
@@ -127,9 +127,9 @@
     #subtypes of long are converted to long!
     return long__Long(space, w_value)
 
-def float__Long(space, w_longobj): #YYYYYY
+def float__Long(space, w_longobj):
     try:
-        return space.newfloat(float(w_longobj.longval()))
+        return space.newfloat(_AsDouble(w_longobj))
     except OverflowError:
         raise OperationError(space.w_OverflowError,
                              space.wrap("long int too large to convert to float"))
@@ -253,30 +253,16 @@
     result.sign = w_long1.sign * w_long2.sign
     return result
 
-def truediv__Long_Long(space, w_long1, w_long2): #YYYYYY
-    x = w_long1.longval()
-    y = w_long2.longval()
-    if not y:
-        raise OperationError(space.w_ZeroDivisionError,
-                             space.wrap("long division"))
-    try:
-        z = operator.truediv(x, y)
-    except OverflowError:
-        raise OperationError(space.w_OverflowError,
-                             space.wrap("long/long too large for a float"))
-    return space.newfloat(float(z))
-
-def floordiv__Long_Long(space, w_long1, w_long2): #YYYYYY
-    x = w_long1.longval()
-    y = w_long2.longval()
-    if not y:
-        raise OperationError(space.w_ZeroDivisionError,
-                             space.wrap("long division"))
-    z = x // y
-    return W_LongObject(space, *args_from_long(z))
+def truediv__Long_Long(space, w_long1, w_long2):
+    div = _long_true_divide(space, w_long1, w_long2)
+    return space.newfloat(div)
+
+def floordiv__Long_Long(space, w_long1, w_long2):
+    div, rem = _divrem(space, w_long1, w_long2)
+    return div
 
 old_style_div = 1 / 2 == 1 // 2
-def div__Long_Long(space, w_long1, w_long2): #YYYYYY
+def div__Long_Long(space, w_long1, w_long2):
     # Select the proper div
     if old_style_div:
         return floordiv__Long_Long(space, w_long1, w_long2)
@@ -284,25 +270,13 @@
         return truediv__Long_Long(space, w_long1, w_long2)
 
 
-def mod__Long_Long(space, w_long1, w_long2): #YYYYYY
-    x = w_long1.longval()
-    y = w_long2.longval()
-    if not y:
-        raise OperationError(space.w_ZeroDivisionError,
-                             space.wrap("long modulo"))
-    z = x % y
-    return W_LongObject(space, *args_from_long(z))
+def mod__Long_Long(space, w_long1, w_long2):
+    div, rem = _divrem(space, w_long1, w_long2)
+    return rem
 
-def divmod__Long_Long(space, w_long1, w_long2): #YYYYYY
-    x = w_long1.longval()
-    y = w_long2.longval()
-    if not y:
-        raise OperationError(space.w_ZeroDivisionError,
-                             space.wrap("long modulo"))
-    z1, z2 = divmod(x, y)
-    w_result1 = W_LongObject(space, *args_from_long(z1))
-    w_result2 = W_LongObject(space, *args_from_long(z2))
-    return space.newtuple([w_result1, w_result2])
+def divmod__Long_Long(space, w_long1, w_long2):
+    div, rem = _divrem(space, w_long1, w_long2)
+    return space.newtuple([div, rem])
 
 # helper for pow()  #YYYYYY: still needs longval if second argument is negative
 def _impl_long_long_pow(space, lv, lw, lz=None):
@@ -429,7 +403,7 @@
     w_result._normalize()
     return w_result
 
-def rshift__Long_Long(space, w_long1, w_long2): #YYYYYY
+def rshift__Long_Long(space, w_long1, w_long2):
     if w_long2.sign < 0:
         raise OperationError(space.w_ValueError,
                              space.wrap("negative shift count"))
@@ -847,46 +821,120 @@
     return a, rem
 
 
-##def _divrem(a, b)
-##    size_a = len(a.digits) * 2
-##    size_b = len(b.digits) * 2
-##    PyLongObject *z;
-##
-##    if (size_b == 0) {
-##        PyErr_SetString(PyExc_ZeroDivisionError,
-##                "long division or modulo by zero");
-##        return -1;
-##    }
-##    if (size_a < size_b ||
-##        (size_a == size_b &&
-##         a->ob_digit[size_a-1] < b->ob_digit[size_b-1])) {
-##        /* |a| < |b|. */
-##        *pdiv = _PyLong_New(0);
-##        Py_INCREF(a);
-##        *prem = (PyLongObject *) a;
-##        return 0;
-##    }
-##    if (size_b == 1) {
-##        digit rem = 0;
-##        z = divrem1(a, b->ob_digit[0], &rem);
-##        if (z == NULL)
-##            return -1;
-##        *prem = (PyLongObject *) PyLong_FromLong((long)rem);
-##    }
-##    else {
-##        z = x_divrem(a, b, prem);
-##        if (z == NULL)
-##            return -1;
-##    }
-##    /* Set the signs.
-##       The quotient z has the sign of a*b;
-##       the remainder r has the sign of a,
-##       so a = b*z + r. */
-##    if ((a->ob_size < 0) != (b->ob_size < 0))
-##        z->ob_size = -(z->ob_size);
-##    if (a->ob_size < 0 && (*prem)->ob_size != 0)
-##        (*prem)->ob_size = -((*prem)->ob_size);
-##    *pdiv = z;
-##    return 0;
+def _divrem(space, a, b):
+    """ Long division with remainder, top-level routine """
+    size_a = len(a.digits) * 2
+    size_b = len(b.digits) * 2
+    if a._getshort(size_a-1) == 0:
+        size_a -= 1
+    if b._getshort(size_b-1) == 0:
+        size_b -= 1
 
-## XXXX
+    if size_b == 0:
+        raise OperationError(w_longobj.space.w_ZeroDivisionError,
+                             w_longobj.space.wrap("long division or modulo by zero"))
+
+    if (size_a < size_b or
+        (size_a == size_b and
+         a._getshort(size_a-1) < b._getshort(size_b-1))):
+        # |a| < |b|
+        z = W_LongObject(space, [r_uint(0)], 0)
+        rem = a
+        return z, rem
+    if size_b == 1:
+        z, urem = _divrem1(space, a, b._getshort(0))
+        rem = W_LongObject(space, [urem], int(urem != 0))
+    else:
+        z, rem = _x_divrem(space, a, b)
+    # Set the signs.
+    # The quotient z has the sign of a*b;
+    # the remainder r has the sign of a,
+    # so a = b*z + r.
+    if a.sign != b.sign:
+        z.sign = - z.sign
+    if z.sign < 0 and rem.sign != 0:
+        rem.sign = - rem.sign
+    return z, rem
+
+# ______________ conversions to double _______________
+
+def _AsScaledDouble(v):
+    """
+    NBITS_WANTED should be > the number of bits in a double's precision,
+    but small enough so that 2**NBITS_WANTED is within the normal double
+    range.  nbitsneeded is set to 1 less than that because the most-significant
+    Python digit contains at least 1 significant bit, but we don't want to
+    bother counting them (catering to the worst case cheaply).
+
+    57 is one more than VAX-D double precision; I (Tim) don't know of a double
+    format with more precision than that; it's 1 larger so that we add in at
+    least one round bit to stand in for the ignored least-significant bits.
+    """
+    NBITS_WANTED = 57
+    multiplier = float(1 << SHORT_BIT)
+    if v.sign == 0:
+        return 0.0, 0
+    i = len(v.digits) * 2 - 1
+    if v._getshort(i) == 0:
+        i -= 1
+    sign = v.sign
+    x = float(v._getshort(i))
+    nbitsneeded = NBITS_WANTED - 1
+    # Invariant:  i Python digits remain unaccounted for.
+    while i > 0 and nbitsneeded > 0:
+        i -= 1
+        x = x * multiplier + float(v._getshort(i))
+        nbitsneeded -= SHORT_BIT
+    # There are i digits we didn't shift in.  Pretending they're all
+    # zeroes, the true value is x * 2**(i*SHIFT).
+    exponent = i
+    assert x > 0.0
+    return x * sign, exponent
+
+# XXX make ldexp and isinf a builtin float support function
+
+def isinf(x):
+    return x*2 == x
+
+def ldexp(x, exp):
+    assert type(x) is float
+    lb1 = LONG_BIT - 1
+    multiplier = float(r_uint(1) << lb1)
+    while exp >= lb1:
+        x *= multiplier
+        exp -= lb1
+    if exp:
+        x *= float(r_uint(1) << exp)
+    return x
+
+def _AsDouble(v):
+    """ Get a C double from a long int object. """
+    x, e = _AsScaledDouble(v)
+    if e <= sys.maxint / SHORT_BIT:
+        x = ldexp(x, e * SHORT_BIT)
+        if not isinf(x):
+            return x
+    raise OverflowError# sorry, "long int too large to convert to float"
+
+def _long_true_divide(space, a, b):
+    try:
+        ad, aexp = _AsScaledDouble(a)
+        bd, bexp = _AsScaledDouble(b)
+        if bd == 0.0:
+            raise OperationError(space.w_ZeroDivisionError,
+                                 space.wrap("long division or modulo by zero"))
+
+        # True value is very close to ad/bd * 2**(SHIFT*(aexp-bexp))
+        ad /= bd   # overflow/underflow impossible here
+        aexp -= bexp
+        if aexp > sys.maxint / SHORT_BIT:
+            raise OverflowError
+        elif aexp < -(sys.maxint / SHORT_BIT):
+            return 0.0 # underflow to 0
+        ad = ldexp(ad, aexp * SHORT_BIT)
+        if isinf(ad):   # ignore underflow to 0.0
+            raise OverflowError
+        return ad
+    except OverflowError:
+        raise OperationError(space.w_OverflowError,
+                             space.wrap("long/long too large for a float"))

Modified: pypy/branch/dist-2.4.1/pypy/objspace/std/test/test_longobject.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/objspace/std/test/test_longobject.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/objspace/std/test/test_longobject.py	Tue Jul  5 12:03:38 2005
@@ -68,6 +68,50 @@
         div, rem = lobj._divrem1(self.space, f1, f2)
         assert (div.longval(), rem) == divmod(x, y)
 
+    def test__muladd1(self):
+        x = 1238585838347L
+        y = 3
+        z = 42
+        f1 = lobj.W_LongObject(self.space, *lobj.args_from_long(x))
+        f2 = r_uint(y)
+        f3 = r_uint(z)
+        prod = lobj._muladd1(self.space, f1, f2, f3)
+        assert prod.longval() == x * y + z
+
+    def test__x_divrem(self):
+        x = 12345678901234567890L
+        for i in range(100):
+            y = long(randint(0, 1 << 30))
+            y <<= 30
+            y += randint(0, 1 << 30)
+            f1 = lobj.W_LongObject(self.space, *lobj.args_from_long(x))
+            f2 = lobj.W_LongObject(self.space, *lobj.args_from_long(y))
+            div, rem = lobj._x_divrem(self.space, f1, f2)
+            assert div.longval(), rem.longval() == divmod(x, y)
+
+    def test__divrem(self):
+        x = 12345678901234567890L
+        for i in range(100):
+            y = long(randint(0, 1 << 30))
+            y <<= 30
+            y += randint(0, 1 << 30)
+            for sx, sy in (1, 1), (1, -1), (-1, -1), (-1, 1):
+                sx *= x
+                sy *= y
+                f1 = lobj.W_LongObject(self.space, *lobj.args_from_long(sx))
+                f2 = lobj.W_LongObject(self.space, *lobj.args_from_long(sy))
+                div, rem = lobj._x_divrem(self.space, f1, f2)
+                assert div.longval(), rem.longval() == divmod(sx, sy)
+
+    def test__AsDouble(self):
+        x = 12345678901234567890L ** 10
+        f1 = lobj.W_LongObject(self.space, *lobj.args_from_long(x))
+        d = lobj._AsDouble(f1)
+        assert d == float(x)
+        x = x ** 100
+        f1 = lobj.W_LongObject(self.space, *lobj.args_from_long(x))
+        assert raises(OverflowError, lobj._AsDouble, f1)
+
     def test_eq(self):
         x = 5858393919192332223L
         y = 585839391919233111223311112332L
@@ -220,10 +264,18 @@
     def test_sub(self):
         assert int(58543L - 12332L) == 58543 - 12332
         assert 237123838281233L * 12 == 237123838281233L * 12L
-        
+
     def test_mul(self):
         assert 363L * 2 ** 40 == 363L << 40
 
+    def test_truediv(self):
+        exec "from __future__ import division; a = 31415926L / 10000000L"
+        assert a == 3.1415926
+
+    def test_floordiv(self):
+        a = 31415926L // 10000000L
+        assert a == 3L
+
     def test_conversion(self):
         class long2(long):
             pass

Modified: pypy/branch/dist-2.4.1/pypy/tool/option.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/tool/option.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/tool/option.py	Tue Jul  5 12:03:38 2005
@@ -15,6 +15,7 @@
     compiler = "cpython" # "cpython"
                          # "pyparse" pypy parser, cpython compiler
                          # "pycomp" pypy parser and compiler (TBD)
+    version = "2.4" # "native" / "2.3" / "2.4"
 
 def run_tb_server(option, opt, value, parser):
     from pypy.tool import tb_server
@@ -51,6 +52,11 @@
         '--parsermodule', action="store",type="string", dest="useparsermodule",
         help="select the parser module to use",
         metavar="[cpython|recparser|parser]"))
+## for this to work the option module need to be loaded before the grammar!
+##     options.append(make_option(
+##         '--version', action="store",type="string", dest="version",
+##         help="select the Python version to emulate",
+##         metavar="[native|2.3|2.4]"))
 
     return options
 

Modified: pypy/branch/dist-2.4.1/pypy/translator/goal/targetparser.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/goal/targetparser.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/translator/goal/targetparser.py	Tue Jul  5 12:03:38 2005
@@ -14,8 +14,7 @@
 
 # _____ Define and setup target ___
 def target():
-    s_list_of_strings = SomeList(ListDef(None, SomeString()))
-    return entry_point, [s_list_of_strings]
+    return entry_point, [str]
 
 # _____ Run translated _____
 def run(c_entry_point):

Modified: pypy/branch/dist-2.4.1/pypy/translator/llvm2/arraynode.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/llvm2/arraynode.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/translator/llvm2/arraynode.py	Tue Jul  5 12:03:38 2005
@@ -2,23 +2,31 @@
 from pypy.rpython import lltype
 from pypy.translator.llvm2.log import log
 from pypy.translator.llvm2.node import LLVMNode
+from pypy.objspace.flow.model import Constant
 import itertools  
 log = log.structnode
 
 count = itertools.count().next 
 
+def wrapstr(s):
+    return '"%s"' % s
+
 class ArrayTypeNode(LLVMNode):
     _issetup = False
     def __init__(self, db, array):
         self.db = db
         assert isinstance(array, lltype.Array)
         self.array = array
-        ref_template = "%%array.%s." % array.OF
         c = count()
-        self.ref = ref_template + str(c)
-        self.constructor_ref = "%%new.array.%s" % c 
-        self.constructor_decl = "%s * %s(int %%len)" % (
-                    self.ref, self.constructor_ref)
+        ref_template = wrapstr("%%array.%s." + str(c))
+
+        self.ref = ref_template % array.OF
+        self.constructor_ref = wrapstr("%%new.array.%s" % c)
+        self.constructor_decl = "%s * %s(int %%len)" % \
+                                (self.ref, self.constructor_ref)
+
+    def __str__(self):
+        return "<ArrayTypeNode %r>" % self.ref
         
     def writedecl(self, codewriter): 
         # declaration for constructor
@@ -38,6 +46,8 @@
            store int %len, int* %arraylength 
            ret %array* %result
         }"""
+        from pypy.translator.llvm2.atomic import is_atomic
+
         log.writeimpl(self.ref)
         codewriter.openfunc(self.constructor_decl)
         indices = [("uint", 1), ("int", "%len")]
@@ -45,16 +55,13 @@
                                  "null", *indices)
         fromtype = self.db.repr_arg_type(self.array.OF) 
         codewriter.cast("%usize", fromtype + "*", "%size", "uint")
-        codewriter.malloc("%ptr", "sbyte", "%usize")
+        codewriter.malloc("%ptr", "sbyte", "%usize", atomic=is_atomic(self))
         codewriter.cast("%result", "sbyte*", "%ptr", self.ref+"*")
         codewriter.getelementptr("%arraylength", self.ref+"*", "%result", ("uint", 0))
         codewriter.store("int", "%len", "%arraylength")
         codewriter.ret(self.ref+"*", "%result")
         codewriter.closefunc()
 
-    def __str__(self):
-        return "<ArrayTypeNode %r>" % self.ref
-
     def setup(self):
         self.db.prepare_repr_arg_type(self.array.OF)
         self._issetup = True
@@ -75,8 +82,8 @@
 
     def __init__(self, db, value):
         self.db = db
-        self.name = "%s.%s" % (value._TYPE.OF, ArrayNode.array_counter)
-        self.ref = "%%stinstance.%s" % self.name
+        name = '"%%arrayinstance.%s.%s"' % (value._TYPE.OF, ArrayNode.array_counter)
+        self.ref = name
         self.value = value
         ArrayNode.array_counter += 1
 
@@ -87,14 +94,15 @@
         T = self.value._TYPE.OF
         for item in self.value.items:
             if not isinstance(T, lltype.Primitive):
-                value = getattr(self.value, name)
                 # Create a dummy constant hack XXX
-                c = Constant(value, T)
+                c = Constant(item, T)
                 self.db.prepare_arg(c)
 
         self._issetup = True
 
-    def get_values(self):
+    def getall(self):
+        arraylen = len(self.value.items)
+
         res = []
 
         T = self.value._TYPE.OF
@@ -107,11 +115,17 @@
                 value = repr(value)
             res.append((typval, value))
 
-        return ", ".join(["%s %s" % (t, v) for t, v in res])
+        arrayvalues = ", ".join(["%s %s" % (t, v) for t, v in res])
 
+        type_ = "{ int, [%s x %s] }" % (len(self.value.items),
+                                        self.db.repr_arg_type(self.value._TYPE.OF))
+        
+        value = "int %s, [%s x %s] [ %s ]" % (arraylen,
+                                              arraylen,
+                                              typval,
+                                              arrayvalues)
+        return type_, value
+    
     def writeglobalconstants(self, codewriter):
-        lenitems = len(self.value.items)
-        lenstr = ".%s" % lenitems
-        codewriter.globalinstance(self.ref,
-                                  self.db.repr_arg_type() + lenstr,
-                                  self.get_values())
+        type_, values = self.getall()
+        codewriter.globalinstance(self.ref, type_, values)

Modified: pypy/branch/dist-2.4.1/pypy/translator/llvm2/build_llvm_module.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/llvm2/build_llvm_module.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/translator/llvm2/build_llvm_module.py	Tue Jul  5 12:03:38 2005
@@ -33,7 +33,7 @@
                 libraries = %(library_files)s,
                 extra_objects = %(object_files)s)])
         ''' % locals())))
-    cmd = "python %s_setup.py build_ext --inplace" % module
+    cmd = "python %s_setup.py build_ext --inplace --force" % module
     if debug: print cmd
     cmdexec(cmd)
 

Modified: pypy/branch/dist-2.4.1/pypy/translator/llvm2/codewriter.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/llvm2/codewriter.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/translator/llvm2/codewriter.py	Tue Jul  5 12:03:38 2005
@@ -10,7 +10,6 @@
 class CodeWriter(object): 
     def __init__(self): 
         self._lines = []
-        self.append('declare sbyte* %GC_malloc(uint)')
 
     def append(self, line): 
         if show_line_numbers:
@@ -94,12 +93,16 @@
         self.indent("%(targetvar)s = cast %(fromtype)s "
                         "%(fromvar)s to %(targettype)s" % locals())
 
-    def malloc(self, targetvar, type_, size=1):
+    def malloc(self, targetvar, type_, size=1, atomic=False):
         if use_boehm_gc:
             cnt = count()
-            self.indent("%%malloc.Size.%(cnt)d = getelementptr %(type_)s* null, int %(size)d" % locals())
+            if atomic:
+                atomicString = '_atomic'
+            else:
+                atomicString = ''
+            self.indent("%%malloc.Size.%(cnt)d = getelementptr %(type_)s* null, uint %(size)s" % locals())
             self.indent("%%malloc.SizeU.%(cnt)d = cast %(type_)s* %%malloc.Size.%(cnt)d to uint" % locals())
-            self.indent("%%malloc.Ptr.%(cnt)d = call sbyte* %%GC_malloc(uint %%malloc.SizeU.%(cnt)d)" % locals())
+            self.indent("%%malloc.Ptr.%(cnt)d = call sbyte* %%GC_malloc%(atomicString)s(uint %%malloc.SizeU.%(cnt)d)" % locals())
             self.indent("%(targetvar)s = cast sbyte* %%malloc.Ptr.%(cnt)d to %(type_)s*" % locals())
         else:
             self.indent("%(targetvar)s = malloc %(type_)s, uint %(size)s" % locals())

Modified: pypy/branch/dist-2.4.1/pypy/translator/llvm2/database.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/llvm2/database.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/translator/llvm2/database.py	Tue Jul  5 12:03:38 2005
@@ -1,6 +1,7 @@
 from pypy.translator.llvm2.log import log 
 from pypy.translator.llvm2.funcnode import FuncNode, FuncTypeNode
-from pypy.translator.llvm2.structnode import StructNode, StructTypeNode, StructVarsizeTypeNode
+from pypy.translator.llvm2.structnode import StructNode, StructVarsizeNode, \
+     StructTypeNode, StructVarsizeTypeNode
 from pypy.translator.llvm2.arraynode import ArrayNode, ArrayTypeNode
 from pypy.rpython import lltype
 from pypy.objspace.flow.model import Block, Constant, Variable
@@ -82,7 +83,11 @@
                     value = value._obj
 
                 if isinstance(ct, lltype.Struct):
-                    self.addpending(const_or_var, StructNode(self, value))
+                    if ct._arrayfld:
+                        assert False, "HERE"
+                        self.addpending(const_or_var, StructVarsizeNode(self, value))
+                    else:
+                        self.addpending(const_or_var, StructNode(self, value))
 
                 elif isinstance(ct, lltype.Array):
                     self.addpending(const_or_var, ArrayNode(self, value))
@@ -141,7 +146,6 @@
             if subset_types is None or isinstance(v, subset_types):
                 res.append(v)
         return res
-
         
     # __________________________________________________________
     # Representing variables and constants in LLVM source code 

Modified: pypy/branch/dist-2.4.1/pypy/translator/llvm2/funcnode.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/llvm2/funcnode.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/translator/llvm2/funcnode.py	Tue Jul  5 12:03:38 2005
@@ -5,6 +5,7 @@
 from pypy.translator.backendoptimization import remove_same_as 
 from pypy.translator.unsimplify import remove_double_links                     
 from pypy.translator.llvm2.node import LLVMNode
+from pypy.translator.llvm2.atomic import is_atomic
 from pypy.translator.llvm2.log import log 
 log = log.funcnode
 
@@ -251,8 +252,9 @@
         assert (isinstance(arg, Constant) and 
                 isinstance(arg.value, lltype.Struct))
         #XXX unclean
-        type = self.db.obj2node[arg.value].ref
-        self.codewriter.malloc(targetvar, type) 
+        node  = self.db.obj2node[arg.value]
+        type_ = node.ref
+        self.codewriter.malloc(targetvar, type_, atomic=is_atomic(node)) 
 
     def malloc_varsize(self, op):
         targetvar = self.db.repr_arg(op.result)
@@ -273,18 +275,16 @@
         typevar = self.db.repr_arg(op.args[0])
         fieldnames = list(op.args[0].concretetype.TO._names)
         index = fieldnames.index(op.args[1].value)
-        self.codewriter.getelementptr(tmpvar, typ, typevar, ("uint", index))
-        
+        self.codewriter.getelementptr(tmpvar, typ, typevar, ("uint", index))        
         targetvar = self.db.repr_arg(op.result)
         targettype = self.db.repr_arg_type(op.result)
         assert targettype != "void"
-        #XXX This doesnt work - yet
-        #if isinstance(op.result.concretetype, lltype.Ptr):        
-        #    self.codewriter.cast(targetvar, targettype, tmpvar, targettype)
-        #else:
-            # Moving to correct result variable
-            #self.codewriter.load(targetvar, targettype, tmpvar)
-        self.codewriter.load(targetvar, targettype, tmpvar)    
+        if isinstance(op.result.concretetype, lltype.ContainerType):
+            # noop
+            self.codewriter.cast(targetvar, targettype, tmpvar, targettype)
+        else:
+            self.codewriter.load(targetvar, targettype, tmpvar)
+
     getsubstruct = getfield
 
     def setfield(self, op): 
@@ -304,20 +304,16 @@
         vartype = self.db.repr_arg_type(op.args[0])
         index = self.db.repr_arg(op.args[1])
         indextype = self.db.repr_arg_type(op.args[1])
-
         tmpvar = self.db.repr_tmpvar()
         self.codewriter.getelementptr(tmpvar, vartype, var,
                                       ("uint", 1), (indextype, index))
-
         targetvar = self.db.repr_arg(op.result)
         targettype = self.db.repr_arg_type(op.result)
-
-        # Ditto see getfield
-        if not isinstance(op.result.concretetype, lltype.Ptr):        
-            self.codewriter.load(targetvar, targettype, tmpvar)
-        else:
-            # XXX noop
+        if isinstance(op.result.concretetype, lltype.ContainerType):
+            # noop
             self.codewriter.cast(targetvar, targettype, tmpvar, targettype)
+        else:
+            self.codewriter.load(targetvar, targettype, tmpvar)
 
     def setarrayitem(self, op):
         array = self.db.repr_arg(op.args[0])

Modified: pypy/branch/dist-2.4.1/pypy/translator/llvm2/genllvm.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/llvm2/genllvm.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/translator/llvm2/genllvm.py	Tue Jul  5 12:03:38 2005
@@ -1,5 +1,5 @@
 from os.path import exists
-use_boehm_gc = exists('/usr/lib/libgc.so')
+use_boehm_gc = exists('/usr/lib/libgc.so') or exists('/usr/lib/libgc.a')
 
 import py
 from pypy.translator.llvm2 import build_llvm_module
@@ -13,6 +13,8 @@
 from pypy.translator.llvm2.codewriter import CodeWriter
 from pypy.translator.backendoptimization import remove_void
 
+function_count = {}
+
 def genllvm(translator):
     remove_void(translator)
     func = translator.entrypoint
@@ -37,6 +39,10 @@
         typ_decl.writeglobalconstants(codewriter)
 
     nl(); comment("Function Prototypes") ; nl()
+    if use_boehm_gc: 
+        codewriter.declare('sbyte* %GC_malloc(uint)')
+        codewriter.declare('sbyte* %GC_malloc_atomic(uint)')
+        codewriter.declare('sbyte* %GC_realloc(sbyte*, uint)')
     for typ_decl in db.getobjects():
         typ_decl.writedecl(codewriter)
 
@@ -47,21 +53,27 @@
         typ_decl.writeimpl(codewriter)
 
     comment("End of file") ; nl()
+
+    if func.func_name in function_count:
+        postfix = '_%d' % function_count[func.func_name]
+        function_count[func.func_name] += 1
+    else:
+        postfix = ''
+        function_count[func.func_name] = 1
     
     targetdir = udir
-    llvmsource = targetdir.join(func.func_name).new(ext='.ll')
+    llvmsource = targetdir.join(func.func_name+postfix).new(ext='.ll')
     content = str(codewriter) 
     llvmsource.write(content) 
     log.source(content)
   
     if not llvm_is_on_path(): 
         py.test.skip("llvm not found")  # XXX not good to call py.test.skip here
-         
-    pyxsource = llvmsource.new(basename=llvmsource.purebasename+'_wrapper'+'.pyx')
+
+    pyxsource = llvmsource.new(basename=llvmsource.purebasename+'_wrapper'+postfix+'.pyx')
     write_pyx_wrapper(entrynode, pyxsource)    
     
-    mod = build_llvm_module.make_module_from_llvm(llvmsource, pyxsource)
-    return getattr(mod, func.func_name + "_wrapper")
+    return build_llvm_module.make_module_from_llvm(llvmsource, pyxsource)
 
 def llvm_is_on_path():
     try:

Modified: pypy/branch/dist-2.4.1/pypy/translator/llvm2/pyxwrapper.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/llvm2/pyxwrapper.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/translator/llvm2/pyxwrapper.py	Tue Jul  5 12:03:38 2005
@@ -1,5 +1,6 @@
 from pypy.translator.llvm2.log import log 
 from pypy.rpython import lltype 
+from pypy.translator.llvm2.genllvm import use_boehm_gc
 log = log.pyrex 
 
 PRIMITIVES_TO_C = {lltype.Signed: "int",
@@ -23,6 +24,11 @@
     inputargs = funcgen.db.repr_arg_multi(funcgen.graph.startblock.inputargs)
     inputargs = [x.strip("%") for x in inputargs]
     append("cdef extern " + c_declaration())
+    if use_boehm_gc:
+	append("cdef extern int GC_get_heap_size()")
+	append("")
+	append("def GC_get_heap_size_wrapper():")
+	append("    return GC_get_heap_size()")
     append("")
     append("def %s_wrapper(%s):" % (funcgen.ref.strip("%"), ", ".join(inputargs)))
     append("    return %s(%s)" % (funcgen.ref.strip("%"), ", ".join(inputargs)))

Modified: pypy/branch/dist-2.4.1/pypy/translator/llvm2/structnode.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/llvm2/structnode.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/translator/llvm2/structnode.py	Tue Jul  5 12:03:38 2005
@@ -42,18 +42,23 @@
         super(StructVarsizeTypeNode, self).__init__(db, struct)
         new_var_name = "%%new.st.var.%s" % self.name
         self.constructor_name = "%s * %s(int %%len)" % (self.ref, new_var_name)
+
+    def __str__(self):
+        return "<StructVarsizeTypeNode %r>" %(self.ref,)
         
     def writedecl(self, codewriter): 
         # declaration for constructor
         codewriter.declare(self.constructor_name)
 
     def writeimpl(self, codewriter):
+        from pypy.translator.llvm2.atomic import is_atomic
+
         log.writeimpl(self.ref)
         codewriter.openfunc(self.constructor_name)
         codewriter.label("block0")
         indices_to_array = [("int", 0)]
         s = self.struct
-        while isintance(s, lltypes.Struct):
+        while isinstance(s, lltype.Struct):
             last_pos = len(self.struct._names_without_voids()) - 1
             indices_to_array.append(("uint", last_pos))
             s = s._flds.values()[-1]
@@ -65,7 +70,7 @@
 
         #XXX is this ok for 64bit?
         codewriter.cast("%sizeu", arraytype + "*", "%size", "uint")
-        codewriter.malloc("%resulttmp", "sbyte", "uint", "%sizeu")
+        codewriter.malloc("%resulttmp", "sbyte", "%sizeu", atomic=is_atomic(self))
         codewriter.cast("%result", "sbyte*", "%resulttmp", self.ref + "*")
 
         # remember the allocated length for later use.
@@ -79,14 +84,22 @@
         codewriter.ret(self.ref + "*", "%result")
         codewriter.closefunc()
 
+
+def cast_global(toptr, from_, name):
+    s = "cast(%s* getelementptr (%s* %s, int 0) to %s)" % (from_,
+                                                           from_,
+                                                           name,
+                                                           toptr)
+    return s
+
 class StructNode(LLVMNode):
     _issetup = False 
     struct_counter = 0
 
     def __init__(self, db, value):
         self.db = db
-        self.name = "%s.%s" % (value._TYPE._name, StructNode.struct_counter)
-        self.ref = "%%stinstance.%s" % self.name
+        name = "%s.%s" % (value._TYPE._name, StructNode.struct_counter)
+        self.ref = "%%stinstance.%s" % name
         self.value = value
         StructNode.struct_counter += 1
 
@@ -105,9 +118,40 @@
                 
         self._issetup = True
 
-    def get_values(self):
+    def getall(self):
         res = []
-        for name in self.value._TYPE._names_without_voids():
+        type_ = self.value._TYPE
+        for name in type_._names_without_voids():
+            T = type_._flds[name]
+            value = getattr(self.value, name)
+            if not isinstance(T, lltype.Primitive):
+                # Create a dummy constant hack XXX
+                c = Constant(value, T)
+                x = self.db.obj2node[c]
+                value = self.db.repr_arg(c)
+                t, v = x.getall()
+                value = cast_global(self.db.repr_arg_type(T), t, value)
+                
+            else:
+                value = str(value)
+            res.append((self.db.repr_arg_type(T), value))
+                
+        typestr = self.db.repr_arg_type(type_)
+        values = ", ".join(["%s %s" % (t, v) for t, v in res])
+        return typestr, values
+    
+    def writeglobalconstants(self, codewriter):
+        type_, values = self.getall()
+        codewriter.globalinstance(self.ref, type_, values)
+                
+class StructVarsizeNode(StructNode):
+    def __str__(self):
+        return "<StructVarsizeNode %r>" %(self.ref,)
+
+    def getall(self):
+
+        res = []
+        for name in self.value._TYPE._names_without_voids()[:-1]:
             T = self.value._TYPE._flds[name]
             value = getattr(self.value, name)
             if not isinstance(T, lltype.Primitive):
@@ -116,10 +160,18 @@
             else:
                 value = str(value)
             res.append((self.db.repr_arg_type(T), value))
-        return ", ".join(["%s %s" % (t, v) for t, v in res])
-
-    def writeglobalconstants(self, codewriter):
-        codewriter.globalinstance(self.ref,
-                                  self.db.repr_arg_type(self.value._TYPE),
-                                  self.get_values())
 
+        # Special case for varsized arrays
+        self.value._TYPE._names_without_voids()[-1]
+        x = self.db.obj2node[Constant(value, T)]
+        t, v = x.get_values() 
+        res.append((t, "{%s}" % v))
+
+        s = self.value._TYPE
+        fields = [getattr(s, name) for name in s._names_without_voids()[-1]] 
+        l = [self.db.repr_arg_type(field) for field in fields]
+        l += t
+        typestr = "{ %s }" % ", ".join(l)
+        values = ", ".join(["%s %s" % (t, v) for t, v in res])
+        return typestr, values
+    

Modified: pypy/branch/dist-2.4.1/pypy/translator/llvm2/test/test_genllvm.py
==============================================================================
--- pypy/branch/dist-2.4.1/pypy/translator/llvm2/test/test_genllvm.py	(original)
+++ pypy/branch/dist-2.4.1/pypy/translator/llvm2/test/test_genllvm.py	Tue Jul  5 12:03:38 2005
@@ -19,7 +19,7 @@
 ## def setup_module(mod):
 ##     mod.llvm_found = is_on_path("llvm-as")
 
-def compile_function(function, annotate, view=False):
+def compile_module(function, annotate, view=False):
     t = Translator(function)
     a = t.annotate(annotate)
     t.specialize()
@@ -28,23 +28,37 @@
         t.view()
     return genllvm(t)
 
+def compile_function(function, annotate, view=False):
+    mod = compile_module(function, annotate, view)
+    return getattr(mod, function.func_name + "_wrapper")
+
+def compile_module_function(function, annotate, view=False):
+    mod = compile_module(function, annotate, view)
+    f = getattr(mod, function.func_name + "_wrapper")
+    return mod, f
+
 def test_GC_malloc(): 
     if not use_boehm_gc:
         py.test.skip("test_GC_malloc skipped because Boehm collector library was not found")
         return
-    py.test.skip("test_GC_malloc skipped because test not yet correct (Boehm collector IS used anyway)")
-    return
     def tuple_getitem(n): 
-        x = 0
+        x = 666
         i = 0
         while i < n:
-            l = (1,2,i,234,23,23,23,234,234,234,234)
+            l = (1,2,i,4,5,6,7,8,9,10,11)
             x += l[2]
             i += 1
         return x
-    f = compile_function(tuple_getitem, [int])
-    t = 1024*1024*100
-    f(t) #assert f(t) == t
+    mod,f = compile_module_function(tuple_getitem, [int])
+    n = 5000
+    result = tuple_getitem(n)
+    assert f(n) == result
+    get_heap_size = getattr(mod, "GC_get_heap_size_wrapper")
+    heap_size_start = get_heap_size()
+    for i in range(0,25):
+        assert f(n) == result
+        heap_size_inc = get_heap_size() - heap_size_start
+        assert heap_size_inc < 500000
 
 def test_return1():
     def simple1():
@@ -196,15 +210,15 @@
         if m == 0:
             return ackermann(n - 1, 1)
         return ackermann(n - 1, ackermann(n, m - 1))
-    f = compile_function(call_ackermann, [int, int], view=False)
+    f = compile_function(call_ackermann, [int, int])
     assert f(0, 2) == 3
     
 def test_tuple_getitem(): 
     def tuple_getitem(i): 
-        l = (1,2,i)
+        l = (4,5,i)
         return l[1]
     f = compile_function(tuple_getitem, [int])
-    assert f(1) == 2 
+    assert f(1) == tuple_getitem(1)
 
 def test_nested_tuple():
     def nested_tuple(i): 
@@ -228,7 +242,7 @@
     assert f(-1) == 3
     assert f(0) == 5
 
-def DONOT_test_simple_chars():
+def Xtest_simple_chars():
      def char_constant2(s):
          s = s + s + s
          return len(s + '.')
@@ -246,6 +260,29 @@
     assert f(1) == 2
     assert f(2) == 3
 
+def test_list_list_getitem(): 
+    def list_list_getitem(): 
+        l = [[1]]
+        return l[0][0]
+    f = compile_function(list_list_getitem, [])
+    assert f() == 1
+
+def test_list_getitem_pbc(): 
+    l = [1,2]
+    def list_getitem_pbc(i): 
+        return l[i]
+    f = compile_function(list_getitem_pbc, [int])
+    assert f(0) == 1
+    assert f(1) == 2
+
+def test_list_list_getitem_pbc(): 
+    l = [[0, 1], [0, 1]]
+    def list_list_getitem_pbc(i): 
+        return l[i][i]
+    f = compile_function(list_list_getitem_pbc, [int])
+    assert f(0) == 0
+    assert f(1) == 1
+
 def test_list_basic_ops(): 
     def list_basic_ops(i, j): 
         l = [1,2,3]



More information about the Pypy-commit mailing list