[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