Commit 87a1c7eb authored by Stefan Behnel's avatar Stefan Behnel

special-case the substring list processing in JoinedStrNode again to reduce...

special-case the substring list processing in JoinedStrNode again to reduce the number of temp vars used
parent 188bdbca
......@@ -2964,24 +2964,46 @@ class RawCNameExprNode(ExprNode):
class JoinedStrNode(ExprNode):
# F-strings
#
# values ListNode([UnicodeNode|FormattedValueNode]) Substrings of the f-string
# values [UnicodeNode|FormattedValueNode] Substrings of the f-string
#
type = py_object_type
type = unicode_type
is_temp = True
subexprs = ['values']
def analyse_types(self, env):
self.values = self.values.analyse_expressions(env)
self.values = [v.analyse_types(env).coerce_to_pyobject(env) for v in self.values]
return self
def generate_result_code(self, code):
def generate_evaluation_code(self, code):
code.mark_pos(self.pos)
num_items = len(self.values)
list_var = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
code.putln('%s = PyList_New(%s); %s' % (
list_var,
num_items,
code.error_goto_if_null(list_var, self.pos)))
code.put_gotref(list_var)
for i, node in enumerate(self.values):
node.generate_evaluation_code(code)
node.make_owned_reference(code)
code.put_giveref(node.py_result())
code.putln('PyList_SET_ITEM(%s, %s, %s);' % (list_var, i, node.py_result()))
node.generate_post_assignment_code(code)
node.free_temps(code)
code.mark_pos(self.pos)
self.allocate_temp_result(code)
code.putln('%s = PyUnicode_Join(%s, %s); %s' % (
self.result(),
Naming.empty_unicode,
self.values.py_result(),
code.error_goto_if_null(self.result(), self.pos)))
list_var,
code.error_goto_if_null(self.py_result(), self.pos)))
code.put_gotref(self.py_result())
code.put_decref_clear(list_var, py_object_type)
code.funcstate.release_temp(list_var)
class FormattedValueNode(ExprNode):
......
......@@ -350,9 +350,9 @@ class PostParse(ScopeTrackingTransform):
def visit_JoinedStrNode(self, node):
"""
Clean up after the parser by wrapping the substrings in a ListNode and
discarding empty Unicode strings. Empty or single-value join lists are not
uncommon because f-string format specs are always parsed into JoinedStrNodes.
Clean up after the parser by discarding empty Unicode strings.
Empty or single-value join lists are not uncommon because f-string
format specs are always parsed into JoinedStrNodes.
"""
values = []
for value in node.values:
......@@ -365,7 +365,7 @@ class PostParse(ScopeTrackingTransform):
elif len(values) == 1:
node = values[0]
else:
node.values = ExprNodes.ListNode(node.pos, args=values)
node.values = values
self.visitchildren(node)
return node
......
......@@ -279,7 +279,7 @@ f'{a * x()}'"""
self.assertEqual(cy_eval(build_fstr(i), x=x, width=width), (x+' ')*i)
# Test concatenating 2 largs fstrings.
self.assertEqual(cy_eval(build_fstr(255)*2, x=x, width=width), (x+' ')*(255*2)) # CPython uses 255*256
self.assertEqual(cy_eval(build_fstr(255)*3, x=x, width=width), (x+' ')*(255*3)) # CPython uses 255*256
s = build_fstr(253, '{x:{width}} ')
self.assertEqual(cy_eval(s, x=x, width=width), (x+' ')*254)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment