Author: Armin Rigo <[email protected]>
Branch: py3.5-fstring-pep498
Changeset: r89697:fa0095403f9d
Date: 2017-01-22 22:48 +0100
http://bitbucket.org/pypy/pypy/changeset/fa0095403f9d/
Log: bytecode interpreter
diff --git a/lib-python/3/opcode.py b/lib-python/3/opcode.py
--- a/lib-python/3/opcode.py
+++ b/lib-python/3/opcode.py
@@ -214,8 +214,8 @@
def_op('BUILD_TUPLE_UNPACK', 152)
def_op('BUILD_SET_UNPACK', 153)
-def_op('FORMAT_VALUE', 155)
-def_op('BUILD_STRING', 157)
+def_op('FORMAT_VALUE', 155) # in CPython 3.6, but available in PyPy from 3.5
+def_op('BUILD_STRING', 157) # in CPython 3.6, but available in PyPy from 3.5
# pypy modification, experimental bytecode
def_op('LOOKUP_METHOD', 201) # Index in name list
diff --git a/pypy/interpreter/astcompiler/assemble.py
b/pypy/interpreter/astcompiler/assemble.py
--- a/pypy/interpreter/astcompiler/assemble.py
+++ b/pypy/interpreter/astcompiler/assemble.py
@@ -758,6 +758,13 @@
def _compute_CALL_METHOD(arg):
return -_num_args(arg) - 1
+def _compute_FORMAT_VALUE(arg):
+ #if arg contains some flag: return -1
+ return 0
+
+def _compute_BUILD_STRING(arg):
+ return 1 - arg
+
_stack_effect_computers = {}
for name, func in globals().items():
diff --git a/pypy/interpreter/astcompiler/astbuilder.py
b/pypy/interpreter/astcompiler/astbuilder.py
--- a/pypy/interpreter/astcompiler/astbuilder.py
+++ b/pypy/interpreter/astcompiler/astbuilder.py
@@ -1286,18 +1286,18 @@
else:
self.error("f-string: unexpected '}'", atom_node)
continue
+ self._f_constant_string(joined_pieces, u[start:p1], atom_node)
if p1 == len(u):
- self._f_constant_string(joined_pieces, u[start:], atom_node)
break # no more '{' or '}' left
pn = p1 + 1
if pn < len(u) and u[pn] == u'{': # '{{' => single '{'
- self._f_constant_string(joined_pieces, u[start:pn], atom_node)
- start = pn + 1
+ start = pn
+ p1 = u.find(u'{', start + 1)
else:
assert u[p1] == u'{'
start = self._f_string_expr(joined_pieces, u, pn, atom_node)
assert u[start - 1] == u'}'
- p1 = u.find(u'{', start)
+ p1 = u.find(u'{', start)
def handle_atom(self, atom_node):
first_child = atom_node.get_child(0)
diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py
b/pypy/interpreter/astcompiler/test/test_compiler.py
--- a/pypy/interpreter/astcompiler/test/test_compiler.py
+++ b/pypy/interpreter/astcompiler/test/test_compiler.py
@@ -12,7 +12,7 @@
p = pyparse.PythonParser(space)
info = pyparse.CompileInfo("<test>", mode)
cst = p.parse_source(expr, info)
- ast = astbuilder.ast_from_node(space, cst, info)
+ ast = astbuilder.ast_from_node(space, cst, info, recursive_parser=p)
return codegen.compile_ast(space, ast, info)
def generate_function_code(expr, space):
@@ -1162,6 +1162,9 @@
"""
yield self.st, source, "f()", 43
+ def test_fstring(self):
+ yield self.st, """x = 42; z = f'ab{x}cd'""", 'z', 'ab42cd'
+
class AppTestCompiler:
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -434,6 +434,10 @@
self.GET_AITER(oparg, next_instr)
elif opcode == opcodedesc.GET_ANEXT.index:
self.GET_ANEXT(oparg, next_instr)
+ elif opcode == opcodedesc.FORMAT_VALUE.index:
+ self.FORMAT_VALUE(oparg, next_instr)
+ elif opcode == opcodedesc.BUILD_STRING.index:
+ self.BUILD_STRING(oparg, next_instr)
else:
self.MISSING_OPCODE(oparg, next_instr)
@@ -1607,6 +1611,23 @@
"from __anext__: %T", w_next_iter)
self.pushvalue(w_awaitable)
+ def FORMAT_VALUE(self, oparg, next_instr):
+ space = self.space
+ w_value = self.popvalue()
+ w_res = space.format(w_value, space.newunicode(u''))
+ self.pushvalue(w_res)
+
+ @jit.unroll_safe
+ def BUILD_STRING(self, itemcount, next_instr):
+ space = self.space
+ lst = []
+ for i in range(itemcount-1, -1, -1):
+ w_item = self.peekvalue(i)
+ lst.append(space.unicode_w(w_item))
+ self.dropvalues(itemcount)
+ w_res = space.newunicode(u''.join(lst))
+ self.pushvalue(w_res)
+
### ____________________________________________________________ ###
class ExitFrame(Exception):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit