| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- # Copyright (c) 2018-2019, 2021-2022 2024 by Rocky Bernstein
- #
- # This program is free software: you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation, either version 3 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
- """Isolate Python version-specific semantic actions here.
- """
- from uncompyle6.parsers.treenode import SyntaxTree
- from uncompyle6.scanners.tok import Token
- from uncompyle6.semantics.consts import (
- INDENT_PER_LEVEL,
- NO_PARENTHESIS_EVER,
- PRECEDENCE,
- TABLE_DIRECT,
- TABLE_R,
- )
- from uncompyle6.semantics.helper import flatten_list
- def customize_for_version(self, is_pypy, version):
- if is_pypy:
- ########################
- # PyPy changes
- #######################
- # fmt: off
- self.TABLE_DIRECT.update({
- "assert": ("%|assert %c\n", 0),
- # This can happen as a result of an if transformation
- "assert2": ("%|assert %c, %c\n", 0, 3),
- "assert_pypy": ( "%|assert %c\n" , (1, "assert_expr") ),
- # This is as a result of an if transformation
- 'assert0_pypy': ( "%|assert %c\n" , 0),
- 'assert_not_pypy': ( "%|assert not %c\n" , (1, "assert_exp") ),
- "assert2_not_pypy": (
- "%|assert not %c, %c\n",
- (1, "assert_exp"),
- (4, "expr"),
- ),
- "try_except_pypy": ( "%|try:\n%+%c%-%c\n\n", 1, 2 ),
- "tryfinallystmt_pypy": ( "%|try:\n%+%c%-%|finally:\n%+%c%-\n\n", 1, 3 ),
- "assign3_pypy": ( "%|%c, %c, %c = %c, %c, %c\n", 5, 4, 3, 0, 1, 2 ),
- "assign2_pypy": ( "%|%c, %c = %c, %c\n", 3, 2, 0, 1),
- })
- # fmt: on
- if version[:2] >= (3, 7):
- def n_call_kw_pypy37(node):
- self.template_engine(("%p(", (0, NO_PARENTHESIS_EVER)), node)
- assert node[-1] == "CALL_METHOD_KW"
- arg_count = node[-1].attr
- kw_names = node[-2]
- assert kw_names == "pypy_kw_keys"
- kwargs_names = kw_names[0].attr
- kwarg_count = len(kwargs_names)
- pos_argc = arg_count - kwarg_count
- flat_elems = flatten_list(node[1:-2])
- n = len(flat_elems)
- assert n == arg_count, "n: %s, arg_count: %s\n%s" % (
- n,
- arg_count,
- node,
- )
- sep = ""
- for i in range(pos_argc):
- elem = flat_elems[i]
- line_number = self.line_number
- value = self.traverse(elem)
- if line_number != self.line_number:
- sep += "\n" + self.indent + INDENT_PER_LEVEL[:-1]
- pass
- self.write(f"{sep}{value}")
- sep = ", "
- assert n >= len(kwargs_names)
- j = pos_argc
- for i in range(kwarg_count):
- elem = flat_elems[j]
- j += 1
- assert elem == "expr"
- line_number = self.line_number
- value = self.traverse(elem)
- if line_number != self.line_number:
- sep += "\n" + self.indent + INDENT_PER_LEVEL[:-1]
- pass
- self.write(f"{sep}{kwargs_names[i]}={value}")
- sep = ", "
- pass
- self.write(")")
- self.prune()
- self.n_call_kw_pypy37 = n_call_kw_pypy37
- else:
- ########################
- # Without PyPy
- #######################
- self.TABLE_DIRECT.update(
- {
- # "assert" and "assert_expr" are added via transform rules.
- "assert": ("%|assert %c\n", 0),
- "assert2": ("%|assert %c, %c\n", 0, 3),
- # Created only via transformation
- "assertnot": ("%|assert not %p\n", (0, PRECEDENCE["unary_not"])),
- "assert2not": (
- "%|assert not %p, %c\n",
- (0, PRECEDENCE["unary_not"]),
- 3,
- ),
- "assign2": ("%|%c, %c = %c, %c\n", 3, 4, 0, 1),
- "assign3": ("%|%c, %c, %c = %c, %c, %c\n", 5, 6, 7, 0, 1, 2),
- "try_except": ("%|try:\n%+%c%-%c\n\n", 1, 3),
- }
- )
- if version >= (3, 0):
- if version >= (3, 2):
- self.TABLE_DIRECT.update(
- {"del_deref_stmt": ("%|del %c\n", 0), "DELETE_DEREF": ("%{pattr}", 0)}
- )
- from uncompyle6.semantics.customize3 import customize_for_version3
- customize_for_version3(self, version)
- else: # < 3.0
- self.TABLE_DIRECT.update(
- {"except_cond3": ("%|except %c, %c:\n", (1, "expr"), (-2, "store"))}
- )
- if version <= (2, 6):
- self.TABLE_DIRECT["testtrue_then"] = self.TABLE_DIRECT["testtrue"]
- if (2, 4) <= version <= (2, 6):
- self.TABLE_DIRECT.update({"comp_for": (" for %c in %c", 3, 1)})
- else:
- self.TABLE_DIRECT.update({"comp_for": (" for %c in %c%c", 2, 0, 3)})
- if version >= (2, 5):
- from uncompyle6.semantics.customize25 import customize_for_version25
- customize_for_version25(self, version)
- if version >= (2, 6):
- from uncompyle6.semantics.customize26_27 import (
- customize_for_version26_27,
- )
- customize_for_version26_27(self, version)
- pass
- else: # < 2.5
- global NAME_MODULE
- NAME_MODULE = SyntaxTree(
- "stmt",
- [
- SyntaxTree(
- "assign",
- [
- SyntaxTree(
- "expr",
- [
- Token(
- "LOAD_GLOBAL",
- pattr="__name__",
- offset=0,
- has_arg=True,
- )
- ],
- ),
- SyntaxTree(
- "store",
- [
- Token(
- "STORE_NAME",
- pattr="__module__",
- offset=3,
- has_arg=True,
- )
- ],
- ),
- ],
- )
- ],
- )
- self.TABLE_DIRECT.update(
- {
- "importmultiple": ("%|import %c%c\n", 2, 3),
- "import_cont": (", %c", 2),
- "tryfinallystmt": (
- "%|try:\n%+%c%-%|finally:\n%+%c%-",
- (1, "suite_stmts_opt"),
- (5, "suite_stmts_opt"),
- ),
- }
- )
- if version == (2, 4):
- def n_iftrue_stmt24(node):
- self.template_engine(("%c", 0), node)
- self.default(node)
- self.prune()
- self.n_iftrue_stmt24 = n_iftrue_stmt24
- elif version < (1, 4):
- from uncompyle6.semantics.customize14 import customize_for_version14
- customize_for_version14(self, version)
- def n_call(node):
- expr = node[0]
- assert expr == "expr"
- params = node[1]
- if params == "tuple":
- self.template_engine(("%p(", (0, NO_PARENTHESIS_EVER)), expr)
- sep = ""
- for param in params[:-1]:
- self.write(sep)
- self.preorder(param)
- sep = ", "
- self.write(")")
- else:
- self.template_engine(
- (
- "%p(%P)",
- (0, "expr", 100),
- (1, -1, ", ", NO_PARENTHESIS_EVER),
- ),
- node,
- )
- self.prune()
- self.n_call = n_call
- else: # 1.0 <= version <= 2.3:
- self.TABLE_DIRECT.update({"if1_stmt": ("%|if 1\n%+%c%-", 5)})
- if version <= (2, 1):
- self.TABLE_DIRECT.update(
- {
- "importmultiple": ("%c", 2),
- # FIXME: not quite right. We have indiividual imports
- # when there is in fact one: "import a, b, ..."
- "imports_cont": ("%C%,", (1, 100, "\n")),
- }
- )
- pass
- pass
- pass # < 2.5
- # < 3.0 continues
- self.TABLE_R.update(
- {
- "STORE_SLICE+0": ("%c[:]", 0),
- "STORE_SLICE+1": ("%c[%p:]", 0, (1, -1)),
- "STORE_SLICE+2": ("%c[:%p]", 0, (1, -1)),
- "STORE_SLICE+3": ("%c[%p:%p]", 0, (1, -1), (2, -1)),
- "DELETE_SLICE+0": ("%|del %c[:]\n", 0),
- "DELETE_SLICE+1": ("%|del %c[%c:]\n", 0, 1),
- "DELETE_SLICE+2": ("%|del %c[:%c]\n", 0, 1),
- "DELETE_SLICE+3": ("%|del %c[%c:%c]\n", 0, 1, 2),
- }
- )
- self.TABLE_DIRECT.update({"raise_stmt2": ("%|raise %c, %c\n", 0, 1)})
- # exec as a built-in statement is only in Python 2.x
- def n_exec_stmt(node):
- """
- exec_stmt ::= expr exprlist DUP_TOP EXEC_STMT
- exec_stmt ::= expr exprlist EXEC_STMT
- """
- self.write(self.indent, "exec ")
- self.preorder(node[0])
- if not node[1][0].isNone():
- sep = " in "
- for subnode in node[1]:
- self.write(sep)
- sep = ", "
- self.preorder(subnode)
- self.println()
- self.prune() # stop recursing
- self.n_exec_smt = n_exec_stmt
- pass # < 3.0
- return
|