mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
gh-98831: Modernize FORMAT_VALUE (#101628)
Generator update: support balanced parentheses and brackets in conditions and size expressions.
This commit is contained in:
parent
aacbdb0c65
commit
b2b85b5db9
5 changed files with 24 additions and 35 deletions
|
@ -3054,18 +3054,10 @@ dummy_func(
|
||||||
ERROR_IF(slice == NULL, error);
|
ERROR_IF(slice == NULL, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
// error: FORMAT_VALUE has irregular stack effect
|
inst(FORMAT_VALUE, (value, fmt_spec if ((oparg & FVS_MASK) == FVS_HAVE_SPEC) -- result)) {
|
||||||
inst(FORMAT_VALUE) {
|
|
||||||
/* Handles f-string value formatting. */
|
/* Handles f-string value formatting. */
|
||||||
PyObject *result;
|
|
||||||
PyObject *fmt_spec;
|
|
||||||
PyObject *value;
|
|
||||||
PyObject *(*conv_fn)(PyObject *);
|
PyObject *(*conv_fn)(PyObject *);
|
||||||
int which_conversion = oparg & FVC_MASK;
|
int which_conversion = oparg & FVC_MASK;
|
||||||
int have_fmt_spec = (oparg & FVS_MASK) == FVS_HAVE_SPEC;
|
|
||||||
|
|
||||||
fmt_spec = have_fmt_spec ? POP() : NULL;
|
|
||||||
value = POP();
|
|
||||||
|
|
||||||
/* See if any conversion is specified. */
|
/* See if any conversion is specified. */
|
||||||
switch (which_conversion) {
|
switch (which_conversion) {
|
||||||
|
@ -3088,7 +3080,7 @@ dummy_func(
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
Py_XDECREF(fmt_spec);
|
Py_XDECREF(fmt_spec);
|
||||||
goto error;
|
ERROR_IF(true, error);
|
||||||
}
|
}
|
||||||
value = result;
|
value = result;
|
||||||
}
|
}
|
||||||
|
@ -3106,12 +3098,8 @@ dummy_func(
|
||||||
result = PyObject_Format(value, fmt_spec);
|
result = PyObject_Format(value, fmt_spec);
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
Py_XDECREF(fmt_spec);
|
Py_XDECREF(fmt_spec);
|
||||||
if (result == NULL) {
|
ERROR_IF(result == NULL, error);
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PUSH(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inst(COPY, (bottom, unused[oparg-1] -- bottom, unused[oparg-1], top)) {
|
inst(COPY, (bottom, unused[oparg-1] -- bottom, unused[oparg-1], top)) {
|
||||||
|
|
20
Python/generated_cases.c.h
generated
20
Python/generated_cases.c.h
generated
|
@ -3703,16 +3703,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
TARGET(FORMAT_VALUE) {
|
TARGET(FORMAT_VALUE) {
|
||||||
/* Handles f-string value formatting. */
|
PyObject *fmt_spec = ((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? PEEK((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0)) : NULL;
|
||||||
|
PyObject *value = PEEK(1 + (((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0));
|
||||||
PyObject *result;
|
PyObject *result;
|
||||||
PyObject *fmt_spec;
|
/* Handles f-string value formatting. */
|
||||||
PyObject *value;
|
|
||||||
PyObject *(*conv_fn)(PyObject *);
|
PyObject *(*conv_fn)(PyObject *);
|
||||||
int which_conversion = oparg & FVC_MASK;
|
int which_conversion = oparg & FVC_MASK;
|
||||||
int have_fmt_spec = (oparg & FVS_MASK) == FVS_HAVE_SPEC;
|
|
||||||
|
|
||||||
fmt_spec = have_fmt_spec ? POP() : NULL;
|
|
||||||
value = POP();
|
|
||||||
|
|
||||||
/* See if any conversion is specified. */
|
/* See if any conversion is specified. */
|
||||||
switch (which_conversion) {
|
switch (which_conversion) {
|
||||||
|
@ -3735,7 +3731,7 @@
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
Py_XDECREF(fmt_spec);
|
Py_XDECREF(fmt_spec);
|
||||||
goto error;
|
if (true) { STACK_SHRINK((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0)); goto pop_1_error; }
|
||||||
}
|
}
|
||||||
value = result;
|
value = result;
|
||||||
}
|
}
|
||||||
|
@ -3753,12 +3749,10 @@
|
||||||
result = PyObject_Format(value, fmt_spec);
|
result = PyObject_Format(value, fmt_spec);
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
Py_XDECREF(fmt_spec);
|
Py_XDECREF(fmt_spec);
|
||||||
if (result == NULL) {
|
if (result == NULL) { STACK_SHRINK((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0)); goto pop_1_error; }
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
STACK_SHRINK((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0));
|
||||||
PUSH(result);
|
POKE(1, result);
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -333,7 +333,7 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
|
||||||
case BUILD_SLICE:
|
case BUILD_SLICE:
|
||||||
return ((oparg == 3) ? 1 : 0) + 2;
|
return ((oparg == 3) ? 1 : 0) + 2;
|
||||||
case FORMAT_VALUE:
|
case FORMAT_VALUE:
|
||||||
return -1;
|
return (((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0) + 1;
|
||||||
case COPY:
|
case COPY:
|
||||||
return (oparg-1) + 1;
|
return (oparg-1) + 1;
|
||||||
case BINARY_OP:
|
case BINARY_OP:
|
||||||
|
@ -681,7 +681,7 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
|
||||||
case BUILD_SLICE:
|
case BUILD_SLICE:
|
||||||
return 1;
|
return 1;
|
||||||
case FORMAT_VALUE:
|
case FORMAT_VALUE:
|
||||||
return -1;
|
return 1;
|
||||||
case COPY:
|
case COPY:
|
||||||
return (oparg-1) + 2;
|
return (oparg-1) + 2;
|
||||||
case BINARY_OP:
|
case BINARY_OP:
|
||||||
|
|
|
@ -263,7 +263,14 @@ class Parser(PLexer):
|
||||||
@contextual
|
@contextual
|
||||||
def expression(self) -> Expression | None:
|
def expression(self) -> Expression | None:
|
||||||
tokens: list[lx.Token] = []
|
tokens: list[lx.Token] = []
|
||||||
while (tkn := self.peek()) and tkn.kind not in (lx.RBRACKET, lx.RPAREN):
|
level = 1
|
||||||
|
while tkn := self.peek():
|
||||||
|
if tkn.kind in (lx.LBRACKET, lx.LPAREN):
|
||||||
|
level += 1
|
||||||
|
elif tkn.kind in (lx.RBRACKET, lx.RPAREN):
|
||||||
|
level -= 1
|
||||||
|
if level == 0:
|
||||||
|
break
|
||||||
tokens.append(tkn)
|
tokens.append(tkn)
|
||||||
self.next()
|
self.next()
|
||||||
if not tokens:
|
if not tokens:
|
||||||
|
|
|
@ -500,20 +500,20 @@ def test_register():
|
||||||
|
|
||||||
def test_cond_effect():
|
def test_cond_effect():
|
||||||
input = """
|
input = """
|
||||||
inst(OP, (aa, input if (oparg & 1), cc -- xx, output if (oparg & 2), zz)) {
|
inst(OP, (aa, input if ((oparg & 1) == 1), cc -- xx, output if (oparg & 2), zz)) {
|
||||||
output = spam(oparg, input);
|
output = spam(oparg, input);
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
output = """
|
output = """
|
||||||
TARGET(OP) {
|
TARGET(OP) {
|
||||||
PyObject *cc = PEEK(1);
|
PyObject *cc = PEEK(1);
|
||||||
PyObject *input = (oparg & 1) ? PEEK(1 + ((oparg & 1) ? 1 : 0)) : NULL;
|
PyObject *input = ((oparg & 1) == 1) ? PEEK(1 + (((oparg & 1) == 1) ? 1 : 0)) : NULL;
|
||||||
PyObject *aa = PEEK(2 + ((oparg & 1) ? 1 : 0));
|
PyObject *aa = PEEK(2 + (((oparg & 1) == 1) ? 1 : 0));
|
||||||
PyObject *xx;
|
PyObject *xx;
|
||||||
PyObject *output = NULL;
|
PyObject *output = NULL;
|
||||||
PyObject *zz;
|
PyObject *zz;
|
||||||
output = spam(oparg, input);
|
output = spam(oparg, input);
|
||||||
STACK_SHRINK(((oparg & 1) ? 1 : 0));
|
STACK_SHRINK((((oparg & 1) == 1) ? 1 : 0));
|
||||||
STACK_GROW(((oparg & 2) ? 1 : 0));
|
STACK_GROW(((oparg & 2) ? 1 : 0));
|
||||||
POKE(1, zz);
|
POKE(1, zz);
|
||||||
if (oparg & 2) { POKE(1 + ((oparg & 2) ? 1 : 0), output); }
|
if (oparg & 2) { POKE(1 + ((oparg & 2) ? 1 : 0), output); }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue