[pypy-svn] r23730 - in pypy/branch/condexpr: . pypy/interpreter/astcompiler pypy/interpreter/pyparser pypy/interpreter/pyparser/data pypy/interpreter/pyparser/test pypy/interpreter/stablecompiler pypy/interpreter/test pypy/module/__builtin__ pypy/module/__builtin__/test pypy/tool pypy/translator
blais at codespeak.net
blais at codespeak.net
Tue Feb 28 02:21:54 CET 2006
Author: blais
Date: Tue Feb 28 02:21:52 2006
New Revision: 23730
Added:
pypy/branch/condexpr/
- copied from r23700, pypy/dist/
pypy/branch/condexpr/pypy/interpreter/pyparser/data/Grammar2.5a
pypy/branch/condexpr/pypy/interpreter/pyparser/data/README
pypy/branch/condexpr/pypy/module/__builtin__/__init__.py
- copied unchanged from r23703, pypy/dist/pypy/module/__builtin__/__init__.py
pypy/branch/condexpr/pypy/module/__builtin__/app_functional.py
- copied unchanged from r23703, pypy/dist/pypy/module/__builtin__/app_functional.py
pypy/branch/condexpr/pypy/module/__builtin__/test/test_functional.py
- copied unchanged from r23703, pypy/dist/pypy/module/__builtin__/test/test_functional.py
pypy/branch/condexpr/pypy/translator/interactive.py
- copied unchanged from r23703, pypy/dist/pypy/translator/interactive.py
Removed:
pypy/branch/condexpr/pypy/interpreter/astcompiler/transformer.py
Modified:
pypy/branch/condexpr/pypy/interpreter/astcompiler/ast.py
pypy/branch/condexpr/pypy/interpreter/astcompiler/ast.txt
pypy/branch/condexpr/pypy/interpreter/pyparser/astbuilder.py
pypy/branch/condexpr/pypy/interpreter/pyparser/ebnfparse.py
pypy/branch/condexpr/pypy/interpreter/pyparser/pysymbol.py
pypy/branch/condexpr/pypy/interpreter/pyparser/pythonparse.py
pypy/branch/condexpr/pypy/interpreter/pyparser/symbol.py
pypy/branch/condexpr/pypy/interpreter/pyparser/test/test_astbuilder.py
pypy/branch/condexpr/pypy/interpreter/stablecompiler/transformer.py
pypy/branch/condexpr/pypy/interpreter/test/test_syntax.py
pypy/branch/condexpr/pypy/tool/option.py
Log:
Branch for adding conditional expressions to PyPy.
This involves changing the grammar so there are lots
of changes involved.
Modified: pypy/branch/condexpr/pypy/interpreter/astcompiler/ast.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/ast.py (original)
+++ pypy/branch/condexpr/pypy/interpreter/astcompiler/ast.py Tue Feb 28 02:21:52 2006
@@ -1232,6 +1232,63 @@
ops=GetSetProperty(Compare.fget_ops, Compare.fset_ops ),
)
+class CondExpr(Node):
+ def __init__(self, expr, left, right, lineno=-1):
+ Node.__init__(self, lineno)
+ self.expr = expr
+ self.left = left
+ self.right = right
+
+ def getChildren(self):
+ "NOT_RPYTHON"
+ return self.expr, self.left, self.right
+
+ def getChildNodes(self):
+ return [self.expr, self.left, self.right]
+
+ def __repr__(self):
+ return "CondExpr(%s, %s, %s)" % (self.expr.__repr__(), self.left.__repr__(), self.right.__repr__())
+
+ def accept(self, visitor):
+ return visitor.visitCondExpr(self)
+
+ def fget_expr( space, self):
+ return space.wrap(self.expr)
+ def fset_expr( space, self, w_arg):
+ self.expr = space.interp_w(Node, w_arg, can_be_None=False)
+ def fget_left( space, self):
+ return space.wrap(self.left)
+ def fset_left( space, self, w_arg):
+ self.left = space.interp_w(Node, w_arg, can_be_None=False)
+ def fget_right( space, self):
+ return space.wrap(self.right)
+ def fset_right( space, self, w_arg):
+ self.right = space.interp_w(Node, w_arg, can_be_None=False)
+
+def descr_CondExpr_new(space, w_subtype, w_expr, w_left, w_right, lineno=-1):
+ self = space.allocate_instance(CondExpr, w_subtype)
+ expr = space.interp_w(Node, w_expr, can_be_None=False)
+ self.expr = expr
+ left = space.interp_w(Node, w_left, can_be_None=False)
+ self.left = left
+ right = space.interp_w(Node, w_right, can_be_None=False)
+ self.right = right
+ self.lineno = lineno
+ return space.wrap(self)
+
+def descr_CondExpr_accept( space, w_self, w_visitor):
+ w_callable = space.getattr(w_visitor, space.wrap('visitCondExpr'))
+ args = Arguments(space, [ w_self ])
+ return space.call_args(w_callable, args)
+
+CondExpr.typedef = TypeDef('CondExpr', Node.typedef,
+ __new__ = interp2app(descr_CondExpr_new, unwrap_spec=[ObjSpace, W_Root, W_Root, W_Root, W_Root, int]),
+ accept=interp2app(descr_CondExpr_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
+ expr=GetSetProperty(CondExpr.fget_expr, CondExpr.fset_expr ),
+ left=GetSetProperty(CondExpr.fget_left, CondExpr.fset_left ),
+ right=GetSetProperty(CondExpr.fget_right, CondExpr.fset_right ),
+ )
+
class Const(Node):
def __init__(self, value, lineno=-1):
Node.__init__(self, lineno)
@@ -4232,6 +4289,8 @@
return self.default( node )
def visitCompare(self, node):
return self.default( node )
+ def visitCondExpr(self, node):
+ return self.default( node )
def visitConst(self, node):
return self.default( node )
def visitContinue(self, node):
Modified: pypy/branch/condexpr/pypy/interpreter/astcompiler/ast.txt
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/ast.txt (original)
+++ pypy/branch/condexpr/pypy/interpreter/astcompiler/ast.txt Tue Feb 28 02:21:52 2006
@@ -78,6 +78,7 @@
AbstractTest:
Or(AbstractTest): nodes!
And(AbstractTest): nodes!
+CondExpr: expr, left, right
BitOp:
Bitor(BitOp): nodes!
Bitxor(BitOp): nodes!
Modified: pypy/branch/condexpr/pypy/interpreter/pyparser/astbuilder.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original)
+++ pypy/branch/condexpr/pypy/interpreter/pyparser/astbuilder.py Tue Feb 28 02:21:52 2006
@@ -1,6 +1,6 @@
"""This module provides the astbuilder class which is to be used
by GrammarElements to directly build the AST during parsing
-without going trhough the nested tuples step
+without going through the nested tuples step
"""
from grammar import BaseGrammarBuilder, AbstractContext
@@ -257,9 +257,9 @@
ifs = []
else:
assert False, 'Unexpected token: expecting for in listcomp'
- #
+ #
# Original implementation:
- #
+ #
# if tokens[index].get_value() == 'for':
# index += 1 # skip 'for'
# ass_node = to_lvalue(tokens[index], consts.OP_ASSIGN)
@@ -320,7 +320,7 @@
def get_docstring(builder,stmt):
"""parses a Stmt node.
-
+
If a docstring if found, the Discard node is **removed**
from <stmt> and the docstring is returned.
@@ -340,7 +340,7 @@
del stmt.nodes[0]
doc = expr.value
return doc
-
+
def to_lvalue(ast_node, flags):
lineno = ast_node.lineno
@@ -388,7 +388,7 @@
lineno, 0, '')
else:
raise SyntaxError("can't assign to non-lvalue",
- lineno, 0, '')
+ lineno, 0, '')
def is_augassign( ast_node ):
if ( isinstance( ast_node, ast.Name ) or
@@ -410,7 +410,7 @@
i -= 1
atoms.reverse()
return atoms
-
+
#def eval_string(value):
# """temporary implementation
#
@@ -466,7 +466,7 @@
def parse_attraccess(tokens):
"""parses token list like ['a', '.', 'b', '.', 'c', ...]
-
+
and returns an ast node : ast.Getattr(Getattr(Name('a'), 'b'), 'c' ...)
"""
token = tokens[0]
@@ -579,7 +579,7 @@
return lst[first:last]
else:
return []
-
+
def build_power(builder, nb):
"""power: atom trailer* ['**' factor]"""
@@ -742,7 +742,10 @@
builder.push(TokenObject(tok.NAME, 'is not', lineno))
else:
assert False, "TODO" # uh ?
-
+
+def build_or_test(builder, nb):
+ return build_binary_expr(builder, nb, ast.Or)
+
def build_and_test(builder, nb):
return build_binary_expr(builder, nb, ast.And)
@@ -756,8 +759,18 @@
assert False, "not_test implementation incomplete in not_test"
def build_test(builder, nb):
- return build_binary_expr(builder, nb, ast.Or)
-
+ atoms = get_atoms(builder, nb)
+ if len(atoms) == 1:
+ builder.push(atoms[0])
+ elif len(atoms) == 5:
+ builder.push(
+ ast.CondExpr(atoms[2], atoms[0], atoms[4], atoms[1].lineno))
+ else:
+ assert False, "invalid number of atoms for rule 'test'"
+
+# Note: we do not include a build_old_test() because it does not need to do
+# anything.
+
def build_testlist(builder, nb):
return build_binary_expr(builder, nb, ast.Tuple)
@@ -837,7 +850,7 @@
stmts.extend(node.nodes)
elif isinstance(node, TokenObject) and node.name == tok.ENDMARKER:
# XXX Can't we just remove the last element of the list ?
- break
+ break
elif isinstance(node, TokenObject) and node.name == tok.NEWLINE:
continue
else:
@@ -911,7 +924,6 @@
names, defaults, flags = parse_arglist(slicecut(atoms, 1, -2))
builder.push(ast.Lambda(names, defaults, flags, code, lineno))
-
def build_trailer(builder, nb):
"""trailer: '(' ')' | '(' arglist ')' | '[' subscriptlist ']' | '.' NAME
"""
@@ -1009,7 +1021,7 @@
else:
builder.push(SlicelistObject('slice', sliceinfos, lineno))
-
+
def build_listmaker(builder, nb):
"""listmaker: test ( list_for | (',' test)* [','] )"""
atoms = get_atoms(builder, nb)
@@ -1325,7 +1337,7 @@
def build_del_stmt(builder, nb):
atoms = get_atoms(builder, nb)
builder.push(to_lvalue(atoms[1], consts.OP_DELETE))
-
+
def build_assert_stmt(builder, nb):
"""assert_stmt: 'assert' test [',' test]"""
@@ -1404,7 +1416,7 @@
['else' ':' suite] | 'try' ':' suite 'finally' ':' suite)
# NB compile.c makes sure that the default except clause is last
except_clause: 'except' [test [',' test]]
-
+
"""
atoms = get_atoms(builder, nb)
l = len(atoms)
@@ -1446,6 +1458,7 @@
sym['expr'] : build_expr,
sym['comparison'] : build_comparison,
sym['comp_op'] : build_comp_op,
+ sym['or_test'] : build_or_test,
sym['and_test'] : build_and_test,
sym['not_test'] : build_not_test,
sym['test'] : build_test,
@@ -1457,6 +1470,7 @@
sym['file_input'] : build_file_input,
sym['testlist_gexp'] : build_testlist_gexp,
sym['lambdef'] : build_lambdef,
+ sym['old_lambdef'] : build_lambdef,
sym['trailer'] : build_trailer,
sym['arglist'] : build_arglist,
sym['subscript'] : build_subscript,
@@ -1494,8 +1508,8 @@
self.count = count
self.lineno = lineno # src.getline()
self.col = 0 # src.getcol()
-
-
+
+
class RuleObject(BaseRuleObject):
"""A simple object used to wrap a rule or token"""
def __init__(self, name, count, lineno):
@@ -1511,18 +1525,18 @@
class TempRuleObject(BaseRuleObject):
"""used to keep track of how many items get_atom() should pop"""
-
+
def __init__(self, name, count, lineno):
BaseRuleObject.__init__(self, count, lineno)
self.temp_rulename = name
-
+
def __str__(self):
return "<Rule: %s/%d>" % (self.temp_rulename, self.count)
def __repr__(self):
return "<Rule: %s/%d>" % (self.temp_rulename, self.count)
-
+
class TokenObject(ast.Node):
"""A simple object used to wrap a rule or token"""
def __init__(self, name, value, lineno):
@@ -1532,7 +1546,7 @@
# self.line = 0 # src.getline()
self.col = 0 # src.getcol()
self.lineno = lineno
-
+
def get_name(self):
return tok.tok_rpunct.get(self.name,
tok.tok_name.get(self.name, str(self.name)))
@@ -1542,10 +1556,10 @@
if value is None:
value = ''
return value
-
+
def __str__(self):
return "<Token: (%s,%s)>" % (self.get_name(), self.value)
-
+
def __repr__(self):
return "<Token: (%r,%s)>" % (self.get_name(), self.value)
@@ -1568,13 +1582,13 @@
def __str__(self):
return "<ArgList: (%s, %s, %s)>" % self.value
-
+
def __repr__(self):
return "<ArgList: (%s, %s, %s)>" % self.value
-
+
class SubscriptObject(ObjectAccessor):
"""helper class to build subscript list
-
+
self.value represents the __getitem__ argument
"""
def __init__(self, name, value, lineno):
@@ -1584,7 +1598,7 @@
def __str__(self):
return "<SubscriptList: (%s)>" % self.value
-
+
def __repr__(self):
return "<SubscriptList: (%s)>" % self.value
@@ -1603,10 +1617,10 @@
def __str__(self):
return "<SliceList: (%s)>" % self.value
-
+
def __repr__(self):
return "<SliceList: (%s)>" % self.value
-
+
class AstBuilderContext(AbstractContext):
"""specific context management for AstBuidler"""
@@ -1622,7 +1636,7 @@
self.rule_stack = []
self.space = space
self.source_encoding = None
-
+
def context(self):
return AstBuilderContext(self.rule_stack)
@@ -1718,12 +1732,12 @@
l = space.builtin.get('long')
return space.call_function(l, space.wrap(value), space.wrap(base))
if value.endswith('j') or value.endswith('J'):
- c = space.builtin.get('complex')
+ c = space.builtin.get('complex')
return space.call_function(c, space.wrap(value))
try:
i = space.builtin.get('int')
return space.call_function(i, space.wrap(value), space.wrap(base))
- except:
+ except:
f = space.builtin.get('float')
return space.call_function(f, space.wrap(value))
@@ -1760,4 +1774,4 @@
else:
obj2 = "-"
print "% 3d | %30s | %30s" % (i, obj1, obj2)
-
+
Added: pypy/branch/condexpr/pypy/interpreter/pyparser/data/Grammar2.5a
==============================================================================
--- (empty file)
+++ pypy/branch/condexpr/pypy/interpreter/pyparser/data/Grammar2.5a Tue Feb 28 02:21:52 2006
@@ -0,0 +1,129 @@
+# Grammar for Python
+
+# Note: Changing the grammar specified in this file will most likely
+# require corresponding changes in the parser module
+# (../Modules/parsermodule.c). If you can't make the changes to
+# that module yourself, please co-ordinate the required changes
+# with someone who can; ask around on python-dev for help. Fred
+# Drake <fdrake at acm.org> will probably be listening there.
+
+# Commands for Kees Blom's railroad program
+#diagram:token NAME
+#diagram:token NUMBER
+#diagram:token STRING
+#diagram:token NEWLINE
+#diagram:token ENDMARKER
+#diagram:token INDENT
+#diagram:output\input python.bla
+#diagram:token DEDENT
+#diagram:output\textwidth 20.04cm\oddsidemargin 0.0cm\evensidemargin 0.0cm
+#diagram:rules
+
+# Start symbols for the grammar:
+# single_input is a single interactive statement;
+# file_input is a module or sequence of commands read from an input file;
+# eval_input is the input for the eval() and input() functions.
+# NB: compound_stmt in single_input is followed by extra NEWLINE!
+single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
+file_input: (NEWLINE | stmt)* ENDMARKER
+eval_input: testlist NEWLINE* ENDMARKER
+
+decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
+decorators: decorator+
+funcdef: [decorators] 'def' NAME parameters ':' suite
+parameters: '(' [varargslist] ')'
+varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' '**' NAME] | '**' NAME) | fpdef ['=' test] (',' fpdef ['=' test])* [',']
+fpdef: NAME | '(' fplist ')'
+fplist: fpdef (',' fpdef)* [',']
+
+stmt: simple_stmt | compound_stmt
+simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
+small_stmt: expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt | import_stmt | global_stmt | exec_stmt | assert_stmt
+expr_stmt: testlist (augassign testlist | ('=' testlist)*)
+augassign: '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=' | '**=' | '//='
+# For normal assignments, additional restrictions enforced by the interpreter
+print_stmt: 'print' ( '>>' test [ (',' test)+ [','] ] | [ test (',' test)* [','] ] )
+del_stmt: 'del' exprlist
+pass_stmt: 'pass'
+flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt
+break_stmt: 'break'
+continue_stmt: 'continue'
+return_stmt: 'return' [testlist]
+yield_stmt: 'yield' testlist
+raise_stmt: 'raise' [test [',' test [',' test]]]
+import_stmt: import_name | import_from
+import_name: 'import' dotted_as_names
+import_from: 'from' dotted_name 'import' ('*' | '(' import_as_names [','] ')' | import_as_names)
+import_as_name: NAME [NAME NAME]
+dotted_as_name: dotted_name [NAME NAME]
+import_as_names: import_as_name (',' import_as_name)*
+dotted_as_names: dotted_as_name (',' dotted_as_name)*
+dotted_name: NAME ('.' NAME)*
+global_stmt: 'global' NAME (',' NAME)*
+exec_stmt: 'exec' expr ['in' test [',' test]]
+assert_stmt: 'assert' test [',' test]
+
+compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
+if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
+while_stmt: 'while' test ':' suite ['else' ':' suite]
+for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]
+try_stmt: ('try' ':' suite (except_clause ':' suite)+ #diagram:break
+ ['else' ':' suite] | 'try' ':' suite 'finally' ':' suite)
+# NB compile.c makes sure that the default except clause is last
+except_clause: 'except' [test [',' test]]
+suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
+
+# Backward compatibility cruft to support:
+# [ x for x in lambda: True, lambda: False if x() ]
+# even while also allowing:
+# lambda x: 5 if x else 2
+# (But not a mix of the two)
+testlist_safe: old_test [(',' old_test)+ [',']]
+old_test: or_test | old_lambdef
+old_lambdef: 'lambda' [varargslist] ':' old_test
+
+test: or_test ['if' or_test 'else' test] | lambdef
+or_test: and_test ('or' and_test)*
+and_test: not_test ('and' not_test)*
+not_test: 'not' not_test | comparison
+comparison: expr (comp_op expr)*
+comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is' 'not'|'is'
+expr: xor_expr ('|' xor_expr)*
+xor_expr: and_expr ('^' and_expr)*
+and_expr: shift_expr ('&' shift_expr)*
+shift_expr: arith_expr (('<<'|'>>') arith_expr)*
+arith_expr: term (('+'|'-') term)*
+term: factor (('*'|'/'|'%'|'//') factor)*
+factor: ('+'|'-'|'~') factor | power
+power: atom trailer* ['**' factor]
+atom: '(' [testlist_gexp] ')' | '[' [listmaker] ']' | '{' [dictmaker] '}' | '`' testlist1 '`' | NAME | NUMBER | STRING+
+listmaker: test ( list_for | (',' test)* [','] )
+testlist_gexp: test ( gen_for | (',' test)* [','] )
+lambdef: 'lambda' [varargslist] ':' test
+# trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
+trailer: '(' ')' | '(' arglist ')' | '[' subscriptlist ']' | '.' NAME
+subscriptlist: subscript (',' subscript)* [',']
+subscript: '.' '.' '.' | [test] ':' [test] [sliceop] | test
+sliceop: ':' [test]
+exprlist: expr (',' expr)* [',']
+testlist: test (',' test)* [',']
+dictmaker: test ':' test (',' test ':' test)* [',']
+
+classdef: 'class' NAME ['(' testlist ')'] ':' suite
+
+# arglist: (argument ',')* (argument [',']| '*' test [',' '**' test] | '**' test)
+arglist: (argument ',')* ( '*' test [',' '**' test] | '**' test | argument | [argument ','] )
+argument: [test '='] test [gen_for] # Really [keyword '='] test
+
+list_iter: list_for | list_if
+list_for: 'for' exprlist 'in' testlist_safe [list_iter]
+list_if: 'if' test [list_iter]
+
+gen_iter: gen_for | gen_if
+gen_for: 'for' exprlist 'in' or_test [gen_iter]
+gen_if: 'if' test [gen_iter]
+
+testlist1: test (',' test)*
+
+# not used in grammar, but may appear in "node" passed from Parser to Compiler
+encoding_decl: NAME
Added: pypy/branch/condexpr/pypy/interpreter/pyparser/data/README
==============================================================================
--- (empty file)
+++ pypy/branch/condexpr/pypy/interpreter/pyparser/data/README Tue Feb 28 02:21:52 2006
@@ -0,0 +1,5 @@
+If you modify the grammar, you need to regenerate interpreter/pyparser/symbol.py
+
+Note that you could delete the old grammars, because the stable compiler only
+supports the latest.
+
Modified: pypy/branch/condexpr/pypy/interpreter/pyparser/ebnfparse.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/ebnfparse.py (original)
+++ pypy/branch/condexpr/pypy/interpreter/pyparser/ebnfparse.py Tue Feb 28 02:21:52 2006
@@ -260,7 +260,7 @@
from pprint import pprint
if __name__ == "__main__":
- grambuild = parse_grammar(file('data/Grammar2.3'))
+ grambuild = parse_grammar(file('data/Grammar2.5a'))
for i,r in enumerate(grambuild.items):
print "% 3d : %s" % (i, r)
pprint(grambuild.terminals.keys())
Modified: pypy/branch/condexpr/pypy/interpreter/pyparser/pysymbol.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/pysymbol.py (original)
+++ pypy/branch/condexpr/pypy/interpreter/pyparser/pysymbol.py Tue Feb 28 02:21:52 2006
@@ -60,7 +60,7 @@
globals()[_name] = _value
-
+# (This function does not seen to be called right now)
def update_symbols( parser ):
"""Update the symbol module according to rules
in PythonParser instance : parser"""
@@ -70,3 +70,32 @@
# There is no symbol in this module until the grammar is loaded
# once loaded the grammar parser will fill the mappings with the
# grammar symbols
+
+def gen_symbol_file( grammar ):
+ """
+ Generate a compatible symbol file for symbol.py, using the grammar that has
+ been generated from the grammar in the PyPy parser. (Note that we assume
+ that the parser generates the tokens deterministically.)
+ """
+ import os.path
+ f = open(os.path.join(os.path.dirname(__file__), 'symbol.py'), 'w')
+ print >> f, """
+# This file is automatically generated; please don't muck it up!
+#
+# To update the symbols in this file, call this function from python_grammar()
+# and call PyPy.
+"""
+ for k, v in grammar.symbols.sym_name.iteritems():
+ if k >= 0:
+ print >> f, '%s = %s' % (v, k)
+
+ print >> f, """
+
+# Generate sym_name
+sym_name = {}
+for _name, _value in globals().items():
+ if type(_value) is type(0):
+ sym_name[_value] = _name
+"""
+ f.close()
+
Modified: pypy/branch/condexpr/pypy/interpreter/pyparser/pythonparse.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/pythonparse.py (original)
+++ pypy/branch/condexpr/pypy/interpreter/pyparser/pythonparse.py Tue Feb 28 02:21:52 2006
@@ -48,7 +48,7 @@
goalnumber = pysymbol._cpython_symbols.sym_values[goal]
target = self.rules[goalnumber]
src = Source(lines, flags)
-
+
result = target.match(src, builder)
if not result:
line, lineno = src.debug()
@@ -56,7 +56,7 @@
raise SyntaxError("invalid syntax", lineno, -1, line)
# return None
return builder
-
+
_recode_to_utf8 = gateway.applevel(r'''
def _recode_to_utf8(text, encoding):
return unicode(text, encoding).encode("utf-8")
@@ -96,7 +96,7 @@
if eol2 < 0:
return _check_line_for_encoding(s[eol + 1:])
return _check_line_for_encoding(s[eol + 1:eol2])
-
+
def _check_line_for_encoding(line):
"""returns the declared encoding or None"""
i = 0
@@ -112,7 +112,7 @@
"""returns the python grammar corresponding to our CPython version"""
if version == "native":
_ver = PYTHON_VERSION
- elif version in ("2.3","2.4"):
+ elif version in ("2.3","2.4","2.5a"):
_ver = version
return os.path.join( os.path.dirname(__file__), "data", "Grammar" + _ver ), _ver
@@ -126,6 +126,12 @@
gram = ebnfparse.parse_grammar( file(fname) )
grammar.DEBUG = level
parser = PythonParser( gram )
+
+ # Uncomment this to generate the symbol.py for the parser using the grammar
+ # that is being generated by PyPy. Note: we really should put this
+ # somewhere else.
+ ## pysymbol.gen_symbol_file(gram)
+
return parser
debug_print( "Loading grammar %s" % PYTHON_GRAMMAR )
@@ -141,7 +147,7 @@
def parse_file_input(pyf, gram, builder ):
"""Parse a python file"""
return gram.parse_source( pyf.read(), "file_input", builder )
-
+
def parse_single_input(textsrc, gram, builder ):
"""Parse a python single statement"""
return gram.parse_source( textsrc, "single_input", builder )
@@ -157,4 +163,4 @@
def make_rule( space, w_rule ):
rule = space.str_w( w_rule )
-
+
Modified: pypy/branch/condexpr/pypy/interpreter/pyparser/symbol.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/symbol.py (original)
+++ pypy/branch/condexpr/pypy/interpreter/pyparser/symbol.py Tue Feb 28 02:21:52 2006
@@ -1,15 +1,9 @@
-#! /usr/bin/env python
-
-"""Non-terminal symbols of Python grammar (from "graminit.h")."""
# This file is automatically generated; please don't muck it up!
#
-# To update the symbols in this file, 'cd' to the top directory of
-# the python source tree after building the interpreter and run:
-#
-# python Lib/symbol.py
+# To update the symbols in this file, call this function from python_grammar()
+# and call PyPy.
-#--start constants--
single_input = 256
file_input = 257
eval_input = 258
@@ -88,20 +82,14 @@
gen_if = 331
testlist1 = 332
encoding_decl = 333
-#--end constants--
+old_test = 334
+or_test = 335
+old_lambdef = 336
+
+# Generate sym_name
sym_name = {}
for _name, _value in globals().items():
if type(_value) is type(0):
sym_name[_value] = _name
-
-def main():
- import sys
- import token
- if len(sys.argv) == 1:
- sys.argv = sys.argv + ["Include/graminit.h", "Lib/symbol.py"]
- token.main()
-
-if __name__ == "__main__":
- main()
Modified: pypy/branch/condexpr/pypy/interpreter/pyparser/test/test_astbuilder.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py (original)
+++ pypy/branch/condexpr/pypy/interpreter/pyparser/test/test_astbuilder.py Tue Feb 28 02:21:52 2006
@@ -206,8 +206,22 @@
"[a, (b,c), d] = e",
"a, (b, c), d = e",
]
-EXPECTED["k[v,]"] = "Module(None, Stmt([Discard(Subscript(Name('k'), 2, Tuple([Name('v')])))]))"
-EXPECTED["m[a,b]"] = "Module(None, Stmt([Discard(Subscript(Name('m'), 2, Tuple([Name('a'), Name('b')])))]))"
+
+# We do not export the following tests because we would have to implement 2.5
+# features in the stable compiler (other than just building the AST).
+expressions_inbetweenversions = expressions + [
+ "1 if True else 2",
+ "1 if False else 2",
+ ]
+
+EXPECTED["k[v,]"] = ("Module(None, Stmt([Discard(Subscript(Name('k'), 2, "
+ "Tuple([Name('v')])))]))")
+EXPECTED["m[a,b]"] = ("Module(None, Stmt([Discard(Subscript(Name('m'), 2, "
+ "Tuple([Name('a'), Name('b')])))]))")
+EXPECTED["1 if True else 2"] = ("Module(None, Stmt([Discard(CondExpr("
+ "Name('True'), Const(1), Const(2)))]))")
+EXPECTED["1 if False else 2"] = ("Module(None, Stmt([Discard(CondExpr("
+ "Name('False'), Const(1), Const(2)))]))")
funccalls = [
"l = func()",
@@ -601,7 +615,7 @@
TESTS = [
constants,
- expressions,
+ expressions_inbetweenversions,
augassigns,
comparisons,
funccalls,
Modified: pypy/branch/condexpr/pypy/interpreter/stablecompiler/transformer.py
==============================================================================
--- pypy/dist/pypy/interpreter/stablecompiler/transformer.py (original)
+++ pypy/branch/condexpr/pypy/interpreter/stablecompiler/transformer.py Tue Feb 28 02:21:52 2006
@@ -308,9 +308,12 @@
return Lambda(names, defaults, flags, code, lineno=nodelist[1][2])
+ # (This is like lambdef but it uses the old_test instead.)
+ # old_lambdef: 'lambda' [varargslist] ':' old_test
+ old_lambdef = lambdef
+
def classdef(self, nodelist):
# classdef: 'class' NAME ['(' testlist ')'] ':' suite
-
name = nodelist[1][1]
doc = self.get_docstring(nodelist[-1])
if nodelist[2][0] == token.COLON:
@@ -579,7 +582,7 @@
def testlist(self, nodelist):
# testlist: expr (',' expr)* [',']
- # testlist_safe: test [(',' test)+ [',']]
+ # testlist_safe: old_test [(',' old_test)+ [',']]
# exprlist: expr (',' expr)* [',']
return self.com_binary(Tuple, nodelist)
@@ -594,15 +597,33 @@
return self.testlist(nodelist)
def test(self, nodelist):
- # and_test ('or' and_test)* | lambdef
- if len(nodelist) == 1 and nodelist[0][0] == symbol.lambdef:
- return self.lambdef(nodelist[0])
- return self.com_binary(Or, nodelist)
+ # test: or_test ['if' or_test 'else' test] | lambdef
+ if len(nodelist) == 1:
+ if nodelist[0][0] == symbol.lambdef:
+ return self.lambdef(nodelist[0])
+ else:
+ # Normal or-expression
+ return self.com_node(nodelist[0])
+ else:
+ # Here we implement conditional expressions
+ return ast.CondExpr(nodelist[2], nodelist[0], nodelist[4],
+ nodelist[1].lineno)
def and_test(self, nodelist):
# not_test ('and' not_test)*
return self.com_binary(And, nodelist)
+ def old_test(self, nodelist):
+ # old_test: or_test | old_lambdef
+ if len(nodelist) == 1 and nodelist[0][0] == symbol.lambdef:
+ return self.lambdef(nodelist[0])
+ assert len(nodelist) == 1
+ return self.com_node(nodelist[0])
+
+ def or_test(self, nodelist):
+ # or_test: and_test ('or' and_test)*
+ return self.com_binary(Or, nodelist)
+
def not_test(self, nodelist):
# 'not' not_test | comparison
result = self.com_node(nodelist[-1])
@@ -1396,6 +1417,8 @@
symbol.testlist,
symbol.testlist_safe,
symbol.test,
+ symbol.old_test,
+ symbol.or_test,
symbol.and_test,
symbol.not_test,
symbol.comparison,
@@ -1421,54 +1444,10 @@
token.NOTEQUAL : '!=',
}
-_legal_node_types = [
- symbol.funcdef,
- symbol.classdef,
- symbol.stmt,
- symbol.small_stmt,
- symbol.flow_stmt,
- symbol.simple_stmt,
- symbol.compound_stmt,
- symbol.expr_stmt,
- symbol.print_stmt,
- symbol.del_stmt,
- symbol.pass_stmt,
- symbol.break_stmt,
- symbol.continue_stmt,
- symbol.return_stmt,
- symbol.raise_stmt,
- symbol.import_stmt,
- symbol.global_stmt,
- symbol.exec_stmt,
- symbol.assert_stmt,
- symbol.if_stmt,
- symbol.while_stmt,
- symbol.for_stmt,
- symbol.try_stmt,
- symbol.suite,
- symbol.testlist,
- symbol.testlist_safe,
- symbol.test,
- symbol.and_test,
- symbol.not_test,
- symbol.comparison,
- symbol.exprlist,
- symbol.expr,
- symbol.xor_expr,
- symbol.and_expr,
- symbol.shift_expr,
- symbol.arith_expr,
- symbol.term,
- symbol.factor,
- symbol.power,
- symbol.atom,
- ]
-
-if hasattr(symbol, 'yield_stmt'):
- _legal_node_types.append(symbol.yield_stmt)
-
_assign_types = [
symbol.test,
+ symbol.old_test,
+ symbol.or_test,
symbol.and_test,
symbol.not_test,
symbol.comparison,
Modified: pypy/branch/condexpr/pypy/interpreter/test/test_syntax.py
==============================================================================
--- pypy/dist/pypy/interpreter/test/test_syntax.py (original)
+++ pypy/branch/condexpr/pypy/interpreter/test/test_syntax.py Tue Feb 28 02:21:52 2006
@@ -248,6 +248,15 @@
raise
+class AppTestCondExpr:
+
+ def test_condexpr(self):
+ for s, expected in [("x = 1 if True else 2", 1),
+ ("x = 1 if False else 2", 2)]:
+ exec s
+ assert x == expected
+
+
if __name__ == '__main__':
# only to check on top of CPython (you need 2.4)
from py.test import raises
Modified: pypy/branch/condexpr/pypy/tool/option.py
==============================================================================
--- pypy/dist/pypy/tool/option.py (original)
+++ pypy/branch/condexpr/pypy/tool/option.py Tue Feb 28 02:21:52 2006
@@ -16,7 +16,7 @@
# "ast" uses interpreter/pyparser & interpreter/astcompiler.py
# "cpython" uses cpython parser and cpython c-level compiler
usemodules = []
- version = "2.4" # "native" / "2.3" / "2.4"
+ version = "2.5a" # "native" / "2.3" / "2.4" / "2.5a"
def run_tb_server(option, opt, value, parser):
from pypy.tool import tb_server
More information about the Pypy-commit
mailing list