Changeset 177

Show
Ignore:
Timestamp:
12/28/06 15:41:17 (2 years ago)
Author:
akhavr
Message:

ticket:370:

  • added Lambda support
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • pybeast/trunk/dtest/py2py.py

    r176 r177  
    105105    def test_invert(self): 
    106106        'Test Invert expr' 
    107         self.reformat_and_test('a = ~ 1') 
     107        self.reformat_and_test('a = ~1') 
    108108 
    109109    def test_not(self): 
     
    119119        self.reformat_and_test('a = -a') 
    120120 
     121 
     122class Lambda(Expr): 
     123    'Test Lambda expr handling' 
     124 
     125    def test_lambda(self): 
     126        'Test lambda itself' 
     127        self.reformat_and_test('a = lambda x: x + 1') 
     128 
     129    def test_lambda_with_defaults(self): 
     130        'Test lambda with defaults' 
     131        self.reformat_and_test('a = lambda x, y=1: x + y') 
     132 
     133    def test_with_varargs(self): 
     134        'Test lambda with varargs' 
     135        self.reformat_and_test('a = lambda x, y=1, *args: x + y + len( args )') 
     136 
     137    def test_with_varargs_and_kw(self): 
     138        'Test lambda with varargs and kw' 
     139        self.reformat_and_test( 
     140            'lambda x, y=1, *args, **kw: x + y + len( args ) + len( dir( kw ) )' 
     141            ) 
     142 
     143    def test_with_just_kw(self): 
     144        'Test lambda with kw only' 
     145        self.reformat_and_test('lambda x, y=1, **kw: x + y + len( dir( kw ) )') 
     146 
    121147         
    122148if __name__ == '__main__': 
  • pybeast/trunk/src/py2py.py

    r176 r177  
    22# Copyright (C) 2006 KDS Software Group http://www.kds.com.ua 
    33 
    4 '''Dump python AST into a source code''' 
     4'''Dump python AST into a source code 
     5 
     6$Id$ 
     7Copyright (C) 2006 KDS Software Group http://www.kds.com.ua 
     8''' 
    59 
    610import compiler 
     11import compiler.consts 
    712 
    813def need_parens(inside_op, outside_op): 
     
    6469        return 
    6570 
     71    def visit_callfunc(self, node, walker): 
     72        'visit CallFunc node' 
     73        self.expr_ops_stack.append(node.__class__.__name__) 
     74        walker.dispatch(node.node) 
     75        self.code += '(' 
     76 
     77        for arg in node.args: 
     78            walker.dispatch(arg) 
     79            self.code += ', ' 
     80        self.code = self.code[:-2] 
     81 
     82        self.code += ' )' 
     83        self.expr_ops_stack.pop() 
     84 
    6685    def visit_const(self, node, *args): 
    6786        'visit Const node' 
    68         self.code += ' ' + str(node.value) 
     87        if self.expr_ops_stack[-1] not in ('Invert', 'Lambda', 'UnaryAdd', 
     88                                           'UnarySub'): 
     89            self.code += ' ' 
     90        self.code += str(node.value) 
     91 
     92    def visit_lambda(self, node, walker): 
     93        'visit Lambda node' 
     94        self.expr_ops_stack.append(node.__class__.__name__) 
     95 
     96        len_defaults = len(node.argnames) 
     97        have_varargs = node.flags & compiler.consts.CO_VARARGS 
     98        have_varkeywords = node.flags & compiler.consts.CO_VARKEYWORDS 
     99 
     100        if have_varargs: 
     101            len_defaults -= 1 
     102        if have_varkeywords: 
     103            len_defaults -= 1 
     104        defaults = [None] * len_defaults 
     105        defaults[:len(node.defaults)] = node.defaults 
     106        defaults.reverse() 
     107 
     108        self.code += ' lambda' 
     109 
     110        prefix = '' 
     111        for i in range( len(node.argnames) ): 
     112            arg = node.argnames[i] 
     113            try: 
     114                default = defaults[i] 
     115            except IndexError: 
     116                default = None 
     117                if prefix == '' and have_varargs: 
     118                    prefix = '*' 
     119                else: 
     120                    prefix = '**' 
     121            self.code += ' %s%s' % (prefix, arg) 
     122            if default is None: 
     123                self.code += ',' 
     124            else: 
     125                self.code += '=' 
     126                walker.dispatch(default) 
     127                self.code += ',' 
     128                 
     129        self.code = self.code[:-1] + ':' 
     130        walker.dispatch(node.code) 
     131 
     132        self.expr_ops_stack.pop() 
    69133 
    70134    def visit_name(self, node, *args): 
    71135        'visit Name node' 
    72         if self.expr_ops_stack[-1] not in ('UnaryAdd','UnarySub'): 
     136        if self.expr_ops_stack[-1] not in ('Invert', 'Lambda', 'UnaryAdd', 
     137                                           'UnarySub'): 
    73138            self.code += ' ' 
    74139        self.code += str(node.name)