diff --git a/test/bytecode_2.6/02_ifelse_lambda.pyc b/test/bytecode_2.6/02_ifelse_lambda.pyc deleted file mode 100644 index 88a52e42..00000000 Binary files a/test/bytecode_2.6/02_ifelse_lambda.pyc and /dev/null differ diff --git a/test/bytecode_2.6_run/02_ifelse_lambda.pyc b/test/bytecode_2.6_run/02_ifelse_lambda.pyc new file mode 100644 index 00000000..b53e7ea9 Binary files /dev/null and b/test/bytecode_2.6_run/02_ifelse_lambda.pyc differ diff --git a/test/bytecode_2.7/02_ifelse_lambda.pyc b/test/bytecode_2.7/02_ifelse_lambda.pyc deleted file mode 100644 index a1288bfb..00000000 Binary files a/test/bytecode_2.7/02_ifelse_lambda.pyc and /dev/null differ diff --git a/test/bytecode_2.7_run/02_ifelse_lambda.pyc b/test/bytecode_2.7_run/02_ifelse_lambda.pyc new file mode 100644 index 00000000..2e71776f Binary files /dev/null and b/test/bytecode_2.7_run/02_ifelse_lambda.pyc differ diff --git a/test/bytecode_3.5_run/02_ifelse_lambda.pyc b/test/bytecode_3.5_run/02_ifelse_lambda.pyc new file mode 100644 index 00000000..36bd11c5 Binary files /dev/null and b/test/bytecode_3.5_run/02_ifelse_lambda.pyc differ diff --git a/test/bytecode_3.6/02_ifelse_lambda.pyc b/test/bytecode_3.6/02_ifelse_lambda.pyc deleted file mode 100644 index 9c64872b..00000000 Binary files a/test/bytecode_3.6/02_ifelse_lambda.pyc and /dev/null differ diff --git a/test/bytecode_3.6_run/02_ifelse_lambda.pyc b/test/bytecode_3.6_run/02_ifelse_lambda.pyc new file mode 100644 index 00000000..b24a1d4b Binary files /dev/null and b/test/bytecode_3.6_run/02_ifelse_lambda.pyc differ diff --git a/test/bytecode_3.7/04_withas.pyc b/test/bytecode_3.7/04_withas.pyc new file mode 100644 index 00000000..c7551c4b Binary files /dev/null and b/test/bytecode_3.7/04_withas.pyc differ diff --git a/test/bytecode_3.7/05_36lambda.pyc b/test/bytecode_3.7/05_36lambda.pyc new file mode 100644 index 00000000..e595ddec Binary files /dev/null and b/test/bytecode_3.7/05_36lambda.pyc differ diff --git a/test/bytecode_3.7/05_call_function_kw2.pyc b/test/bytecode_3.7/05_call_function_kw2.pyc new file mode 100644 index 00000000..bff60701 Binary files /dev/null and b/test/bytecode_3.7/05_call_function_kw2.pyc differ diff --git a/test/simple_source/branching/02_ifelse_lambda.py b/test/simple_source/branching/02_ifelse_lambda.py index 5bc996fd..75dc2a0f 100644 --- a/test/simple_source/branching/02_ifelse_lambda.py +++ b/test/simple_source/branching/02_ifelse_lambda.py @@ -2,7 +2,8 @@ # lambda's have to be more or less on a line f = lambda x: 1 if x<2 else 3 -f(5) +assert f(3) == 3 +assert f(1) == 1 # If that wasn't enough ... # Python will create dead code @@ -10,10 +11,18 @@ f(5) # not to include the else expression g = lambda: 1 if True else 3 -g() +assert g() == 1 h = lambda: 1 if False else 3 -h() +assert h() == 3 # From 2.7 test_builtin -lambda c: 'a' <= c <= 'z', 'Hello World' +i = lambda c: 'a' <= c <= 'z', 'Hello World' +assert i[0]('a') == True +assert i[0]('A') == False + +# Issue #170. Bug is needing an "conditional_not_lambda" grammar rule +# in addition the the "conditional_lambda" rule +j = lambda a: False if not a else True +assert j(True) == True +assert j(False) == False diff --git a/uncompyle6/parsers/parse25.py b/uncompyle6/parsers/parse25.py index a60ce46b..7451c418 100644 --- a/uncompyle6/parsers/parse25.py +++ b/uncompyle6/parsers/parse25.py @@ -75,8 +75,12 @@ class Python25Parser(Python26Parser): setupwithas ::= DUP_TOP LOAD_ATTR ROT_TWO LOAD_ATTR CALL_FUNCTION_0 setup_finally stmt ::= classdefdeco stmt ::= conditional_lambda + stmt ::= conditional_not_lambda conditional_lambda ::= expr jmp_false_then expr return_if_lambda return_stmt_lambda LAMBDA_MARKER + conditional_not_lambda + ::= expr jmp_true_then expr return_if_lambda + return_stmt_lambda LAMBDA_MARKER """) super(Python25Parser, self).customize_grammar_rules(tokens, customize) if self.version == 2.5: diff --git a/uncompyle6/parsers/parse26.py b/uncompyle6/parsers/parse26.py index 0b680d27..c935e3b7 100644 --- a/uncompyle6/parsers/parse26.py +++ b/uncompyle6/parsers/parse26.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017 Rocky Bernstein +# Copyright (c) 2017-2018 Rocky Bernstein """ spark grammar differences over Python2 for Python 2.6. """ @@ -289,8 +289,12 @@ class Python26Parser(Python2Parser): return_if_lambda ::= RETURN_END_IF_LAMBDA POP_TOP stmt ::= conditional_lambda + stmt ::= conditional_not_lambda conditional_lambda ::= expr jmp_false_then expr return_if_lambda return_stmt_lambda LAMBDA_MARKER + conditional_not_lambda ::= + expr jmp_true_then expr return_if_lambda + return_stmt_lambda LAMBDA_MARKER # conditional_true are for conditions which always evaluate true # There is dead or non-optional remnants of the condition code though, diff --git a/uncompyle6/parsers/parse27.py b/uncompyle6/parsers/parse27.py index 9b5c1819..c9b0bca5 100644 --- a/uncompyle6/parsers/parse27.py +++ b/uncompyle6/parsers/parse27.py @@ -158,8 +158,12 @@ class Python27Parser(Python2Parser): # Common with 2.6 return_if_lambda ::= RETURN_END_IF_LAMBDA COME_FROM stmt ::= conditional_lambda + stmt ::= conditional_not_lambda conditional_lambda ::= expr jmp_false expr return_if_lambda return_stmt_lambda LAMBDA_MARKER + conditional_not_lambda + ::= expr jmp_true expr return_if_lambda + return_stmt_lambda LAMBDA_MARKER kv3 ::= expr expr STORE_MAP """ diff --git a/uncompyle6/parsers/parse3.py b/uncompyle6/parsers/parse3.py index a214c82a..884d3e1f 100644 --- a/uncompyle6/parsers/parse3.py +++ b/uncompyle6/parsers/parse3.py @@ -334,6 +334,17 @@ class Python3Parser(PythonParser): def p_stmt3(self, args): """ + stmt ::= conditional_lambda + stmt ::= conditional_not_lambda + conditional_lambda ::= expr jmp_false expr return_if_lambda + return_stmt_lambda LAMBDA_MARKER + conditional_not_lambda + ::= expr jmp_true expr return_if_lambda + return_stmt_lambda LAMBDA_MARKER + + return_stmt_lambda ::= ret_expr RETURN_VALUE_LAMBDA + return_if_lambda ::= RETURN_END_IF_LAMBDA + stmt ::= return_closure return_closure ::= LOAD_CLOSURE RETURN_VALUE RETURN_LAST @@ -580,12 +591,16 @@ class Python3Parser(PythonParser): self.addRule(""" stmt ::= assign3_pypy stmt ::= assign2_pypy - assign3_pypy ::= expr expr expr store store store - assign2_pypy ::= expr expr store store - return_if_lambda ::= RETURN_END_IF_LAMBDA - stmt ::= conditional_lambda + assign3_pypy ::= expr expr expr store store store + assign2_pypy ::= expr expr store store + return_if_lambda ::= RETURN_END_IF_LAMBDA + stmt ::= conditional_lambda + stmt ::= conditional_not_lambda conditional_lambda ::= expr jmp_false expr return_if_lambda return_lambda LAMBDA_MARKER + conditional_not_lambda + ::= expr jmp_true expr return_if_lambda + return_lambda LAMBDA_MARKER """, nop_func) n = len(tokens) diff --git a/uncompyle6/parsers/parse36.py b/uncompyle6/parsers/parse36.py index 1445e6b1..d0bf2059 100644 --- a/uncompyle6/parsers/parse36.py +++ b/uncompyle6/parsers/parse36.py @@ -36,13 +36,6 @@ class Python36Parser(Python35Parser): # 3.6 redoes how return_closure works. FIXME: Isolate to LOAD_CLOSURE return_closure ::= LOAD_CLOSURE DUP_TOP STORE_NAME RETURN_VALUE RETURN_LAST - stmt ::= conditional_lambda - conditional_lambda ::= expr jmp_false expr return_if_lambda - return_stmt_lambda LAMBDA_MARKER - return_stmt_lambda ::= ret_expr RETURN_VALUE_LAMBDA - return_if_lambda ::= RETURN_END_IF_LAMBDA - - for_block ::= l_stmts_opt come_from_loops JUMP_BACK come_from_loops ::= COME_FROM_LOOP* diff --git a/uncompyle6/semantics/consts.py b/uncompyle6/semantics/consts.py index 34ae5152..d83c6c26 100644 --- a/uncompyle6/semantics/consts.py +++ b/uncompyle6/semantics/consts.py @@ -209,7 +209,12 @@ TABLE_DIRECT = { 'ret_cond': ( '%p if %p else %p', (2, 27), (0, 27), (-1, 27) ), 'conditionalnot': ( '%p if not %p else %p', (2, 27), (0, 22), (4, 27) ), 'ret_cond_not': ( '%p if not %p else %p', (2, 27), (0, 22), (-1, 27) ), - 'conditional_lambda': ( '%c if %c else %c', 2, 0, 4), + 'conditional_lambda': + ( '%c if %c else %c', + (2, 'expr'), 0, 4 ), + 'conditional_not_lambda': + ( '%c if not %c else %c', + (2, 'expr'), 0, 4 ), 'compare_single': ( '%p %[-1]{pattr.replace("-", " ")} %p', (0, 19), (1, 19) ), 'compare_chained': ( '%p %p', (0, 29), (1, 30)), @@ -321,71 +326,69 @@ MAP = { # or https://docs.python.org/3/reference/expressions.html # for a list. -# Things at the top of this list below with low-value precidence will +# Things at the top of this lnist below with low-value precidence will # tend to have parenthesis around them. Things at the bottom # of the list will tend not to have parenthesis around them. PRECEDENCE = { - 'list': 0, - 'dict': 0, - 'unary_convert': 0, - 'dict_comp': 0, - 'set_comp': 0, - 'set_comp_expr': 0, - 'list_comp': 0, - 'generator_exp': 0, + 'list': 0, + 'dict': 0, + 'unary_convert': 0, + 'dict_comp': 0, + 'set_comp': 0, + 'set_comp_expr': 0, + 'list_comp': 0, + 'generator_exp': 0, - 'attribute': 2, - 'subscript': 2, - 'subscript2': 2, - 'slice0': 2, - 'slice1': 2, - 'slice2': 2, - 'slice3': 2, - 'buildslice2': 2, - 'buildslice3': 2, - 'call': 2, + 'attribute': 2, + 'subscript': 2, + 'subscript2': 2, + 'slice0': 2, + 'slice1': 2, + 'slice2': 2, + 'slice3': 2, + 'buildslice2': 2, + 'buildslice3': 2, + 'call': 2, - 'BINARY_POWER': 4, + 'BINARY_POWER': 4, - 'unary_expr': 6, + 'unary_expr': 6, - 'BINARY_MULTIPLY': 8, - 'BINARY_DIVIDE': 8, - 'BINARY_TRUE_DIVIDE': 8, - 'BINARY_FLOOR_DIVIDE': 8, - 'BINARY_MODULO': 8, + 'BINARY_MULTIPLY': 8, + 'BINARY_DIVIDE': 8, + 'BINARY_TRUE_DIVIDE': 8, + 'BINARY_FLOOR_DIVIDE': 8, + 'BINARY_MODULO': 8, - 'BINARY_ADD': 10, - 'BINARY_SUBTRACT': 10, + 'BINARY_ADD': 10, + 'BINARY_SUBTRACT': 10, - 'BINARY_LSHIFT': 12, - 'BINARY_RSHIFT': 12, + 'BINARY_LSHIFT': 12, + 'BINARY_RSHIFT': 12, - 'BINARY_AND': 14, + 'BINARY_AND': 14, + 'BINARY_XOR': 16, + 'BINARY_OR': 18, - 'BINARY_XOR': 16, + 'compare': 20, + 'unary_not': 22, + 'and': 24, + 'ret_and': 24, - 'BINARY_OR': 18, + 'or': 26, + 'ret_or': 26, - 'compare': 20, + 'conditional': 28, + 'conditional_lamdba': 28, + 'conditional_not_lamdba': 28, + 'conditionalnot': 28, + 'ret_cond': 28, + 'ret_cond_not': 28, - 'unary_not': 22, + '_mklambda': 30, - 'and': 24, - 'ret_and': 24, - - 'or': 26, - 'ret_or': 26, - - 'conditional': 28, - 'conditional_lamdba': 28, - 'conditionalnot': 28, - 'ret_cond': 28, - 'ret_cond_not': 28, - - '_mklambda': 30, - 'yield': 101, - 'yield_from': 101 + 'yield': 101, + 'yield_from': 101 } ASSIGN_TUPLE_PARAM = lambda param_name: \