[pypy-svn] r14995 - in pypy/dist/pypy/interpreter/pyparser: . test

adim at codespeak.net adim at codespeak.net
Mon Jul 25 11:03:09 CEST 2005


Author: adim
Date: Mon Jul 25 11:03:07 2005
New Revision: 14995

Modified:
   pypy/dist/pypy/interpreter/pyparser/astbuilder.py
   pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py
Log:
implemented func calls (+ tests)
The hack for now is to have a ArglistObject (extending ast.Node) class
and to use a temporary instance of this class during Ast building.



Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/astbuilder.py	(original)
+++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py	Mon Jul 25 11:03:07 2005
@@ -107,8 +107,11 @@
     L = get_atoms( builder, nb )
     if len(L) == 1:
         builder.push( L[0] )
+    elif len(L) == 2:
+        arguments, stararg, dstararg = L[1].value
+        builder.push(ast.CallFunc(L[0], arguments, stararg, dstararg))
     elif len(L) == 3:
-        builder.push( ast.Power( [ L[0], L[2] ] ) )
+        builder.push(ast.Power([L[0], L[2]]))
     else:
         raise ValueError, "unexpected tokens: %s" % L
 
@@ -326,11 +329,70 @@
 
 def build_lambdef(builder, nb):
     L = get_atoms(builder, nb)
-    print "L:", L
     code = L[-1]
     names, defaults, flags = parse_arglist(L[1:-2])
     builder.push(ast.Lambda(names, defaults, flags, code))
 
+
+def build_trailer(builder, nb):
+    """trailer: '(' ')' | '(' arglist ')' | '[' subscriptlist ']' | '.' NAME
+    """
+    L = get_atoms(builder, nb)
+    # Case 1 : '(' ...
+    if L[0].name == tok.LPAR:
+        if len(L) == 2: # and L[1].token == tok.RPAR:
+            builder.push(ArglistObject('arglist', ([], None, None), None))
+        elif len(L) == 3: # '(' Arglist ')'
+            # push arglist on the stack
+            builder.push(L[1])
+    else:
+        assert False, "Trailer reducing implementation incomplete !"
+
+def build_arglist(builder, nb):
+    L = get_atoms(builder, nb)
+    builder.push(ArglistObject('arglist', parse_argument(L), None))
+
+
+def parse_argument(tokens):
+    """parses function call arguments"""
+    l = len(tokens)
+    index = 0
+    arguments = []
+    last_token = None
+    building_kw = False
+    kw_built = False
+    stararg_token = None
+    dstararg_token = None
+    while index < l:
+        cur_token = tokens[index]
+        index += 1
+        if not isinstance(cur_token, TokenObject):
+            if not building_kw:
+                arguments.append(cur_token)
+            elif kw_built:
+                raise SyntaxError("non-keyword arg after keyword arg (%s)" % (cur_token))
+            else:
+                last_token = arguments.pop()
+                assert isinstance(last_token, ast.Name) # used by rtyper
+                arguments.append(ast.Keyword(last_token.name, cur_token))
+                building_kw = False
+                kw_built = True
+        elif cur_token.name == tok.COMMA:
+            continue
+        elif cur_token.name == tok.EQUAL:
+            building_kw = True
+            continue
+        elif cur_token.name == tok.STAR or cur_token.name == tok.DOUBLESTAR:
+            if cur_token.name == tok.STAR:
+                stararg_token = tokens[index]
+                index += 1
+                if index >= l:
+                    break
+                index += 2 # Skip COMMA and DOUBLESTAR
+            dstararg_token = tokens[index]
+            break
+    return arguments, stararg_token, dstararg_token
+
 def parse_arglist(tokens):
     """returns names, defaults, flags"""
     l = len(tokens)
@@ -404,6 +466,8 @@
     sym.testlist_gexp : build_testlist_gexp,
     sym.lambdef : build_lambdef,
     sym.varargslist : build_varargslist,
+    sym.trailer : build_trailer,
+    sym.arglist : build_arglist,
     }
 
 class RuleObject(ast.Node):
@@ -430,15 +494,31 @@
         self.col = 0  # src.getcol()
 
     def __str__(self):
-        return "<Token: %s=%s>" % (tok.tok_rpunct.get(self.name,
+        return "<Token: (%s,%s)>" % (tok.tok_rpunct.get(self.name,
                                                       tok.tok_name.get(self.name,str(self.name))),
                                    self.value)
     
     def __repr__(self):
-        return "<Token: %r=%s>" % (tok.tok_rpunct.get(self.name,
+        return "<Token: (%r,%s)>" % (tok.tok_rpunct.get(self.name,
                                                       tok.tok_name.get(self.name,str(self.name))),
                                    self.value)
 
+class ArglistObject(ast.Node):
+    """helper class to build function's arg list"""
+    def __init__(self, name, value, src):
+        self.name = name
+        self.value = value
+        self.count = 0
+        self.line = 0 # src.getline()
+        self.col = 0  # src.getcol()
+
+    def __str__(self):
+        return "<ArgList: (%s, %s, %s)>" % self.value
+    
+    def __repr__(self):
+        return "<ArgList: (%s, %s, %s)>" % self.value
+    
+
 class AstBuilderContext(AbstractContext):
     """specific context management for AstBuidler"""
     def __init__(self, rule_stack):
@@ -484,6 +564,8 @@
                 # print "REDUCING ALTERNATIVE %s" % sym.sym_name[rule.codename]
                 F( self, 1 )
             else:
+                print "No reducing implementation for %s, just push it on stack" % (
+                    sym.sym_name[rule.codename])
                 self.push_rule( rule.codename, 1, source )
         else:
             self.push_rule( rule.codename, 1, source )
@@ -502,6 +584,8 @@
                 # print "REDUCING SEQUENCE %s" % sym.sym_name[rule.codename]
                 F( self, elts_number )
             else:
+                print "No reducing implementation for %s, just push it on stack" % (
+                    sym.sym_name[rule.codename])
                 self.push_rule( rule.codename, elts_number, source )
         else:
             self.push_rule( rule.codename, elts_number, source )

Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py	(original)
+++ pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py	Mon Jul 25 11:03:07 2005
@@ -1,3 +1,4 @@
+import os
 
 from pypy.interpreter.pyparser.pythonparse import PYTHON_PARSER
 from pypy.interpreter.pyparser.astbuilder import AstBuilder
@@ -23,9 +24,18 @@
     "x = a * (1 + c)",
     "x, y, z = 1, 2, 3",
     "x = 'a' 'b' 'c'",
+    "l = func()",
+    "l = func(10)",
+    "l = func(10, 12, a, b=c, *args)",
+    "l = func(10, 12, a, b=c, **kwargs)",
+    "l = func(10, 12, a, b=c, *args, **kwargs)",
+    "l = func(10, 12, a, b=c)",
+    # "l = [i for i in range(10)]",
+    # "l = [i for i in range(10) if i%2 == 0]",
+    # "l = [1, 2, 3]",
 ]
 expression_tests = range(len(expressions))
-# expression_tests = [0]
+# expression_tests = [-1]
 
 backtrackings = [
     "f = lambda x: x+1",
@@ -62,24 +72,23 @@
     'a = b\nc = d',
     ]
 
-def ast_parse_expr( expr ):
+def ast_parse_expr(expr):
     builder = AstBuilder()
-    PYTHON_PARSER.parse_source( expr, "single_input", builder )
+    PYTHON_PARSER.parse_source(expr, 'single_input', builder)
     return builder
 
-def tuple_parse_expr( expr ):
+def tuple_parse_expr(expr):
     t = Transformer()
-    return ast_from_input( expr, "single", t )
+    return ast_from_input(expr, 'single', t)
 
-def check_expression( expr ):
-    r1 = ast_parse_expr( expr )
-    ast = tuple_parse_expr( expr )
+def check_expression(expr):
+    r1 = ast_parse_expr(expr)
+    ast = tuple_parse_expr(expr)
     print "ORIG :", ast
     print "BUILT:", r1.rule_stack[-1]
     assert ast == r1.rule_stack[-1], 'failed on %r' % (expr)
 
 
-
 def test_multiexpr():
     for expr in multiexpr:
         yield check_expression, expr
@@ -96,3 +105,37 @@
 def test_comparisons():
     for i in comparison_tests:
         yield check_expression, comparisons[i]
+
+SNIPPETS = [
+#     'snippet_1.py',
+#    'snippet_2.py',
+#    'snippet_3.py',
+#    'snippet_4.py',
+#    'snippet_comment.py',
+#    'snippet_encoding_declaration2.py',
+#    'snippet_encoding_declaration3.py',
+#    'snippet_encoding_declaration.py',
+#    'snippet_function_calls.py',
+#    'snippet_generator.py',
+#    'snippet_import_statements.py',
+#    'snippet_list_comps.py',
+#    'snippet_multiline.py',
+#    'snippet_numbers.py',
+#    'snippet_only_one_comment.py',
+#    'snippet_redirected_prints.py',
+#    'snippet_samples.py',
+#    'snippet_simple_assignment.py',
+#    'snippet_simple_class.py',
+#    'snippet_simple_for_loop.py',
+#    'snippet_simple_in_expr.py',
+#    'snippet_slice.py',
+#    'snippet_whitespaces.py',
+    ]
+
+def test_snippets():
+    py.test.skip('Not ready to test on real snippet files')
+    for snippet_name in SNIPPETS:
+        filepath = os.path.join(os.path.dirname(__file__), 'samples', snippet_name)
+        source = file(filepath).read()
+        yield check_expression, source
+



More information about the Pypy-commit mailing list