mirror of
https://github.com/python/cpython.git
synced 2025-10-14 02:43:49 +00:00
SF patch 1547796 by Georg Brandl -- set literals.
This commit is contained in:
parent
ecfd0b2f3b
commit
86e58e239e
22 changed files with 229 additions and 72 deletions
|
@ -178,6 +178,10 @@ static char *Dict_fields[]={
|
|||
"keys",
|
||||
"values",
|
||||
};
|
||||
static PyTypeObject *Set_type;
|
||||
static char *Set_fields[]={
|
||||
"elts",
|
||||
};
|
||||
static PyTypeObject *ListComp_type;
|
||||
static char *ListComp_fields[]={
|
||||
"elt",
|
||||
|
@ -517,6 +521,8 @@ static int init_types(void)
|
|||
if (!IfExp_type) return 0;
|
||||
Dict_type = make_type("Dict", expr_type, Dict_fields, 2);
|
||||
if (!Dict_type) return 0;
|
||||
Set_type = make_type("Set", expr_type, Set_fields, 1);
|
||||
if (!Set_type) return 0;
|
||||
ListComp_type = make_type("ListComp", expr_type, ListComp_fields, 2);
|
||||
if (!ListComp_type) return 0;
|
||||
GeneratorExp_type = make_type("GeneratorExp", expr_type,
|
||||
|
@ -1434,6 +1440,22 @@ Dict(asdl_seq * keys, asdl_seq * values, int lineno, int col_offset, PyArena
|
|||
return p;
|
||||
}
|
||||
|
||||
expr_ty
|
||||
Set(asdl_seq * elts, int lineno, int col_offset, PyArena *arena)
|
||||
{
|
||||
expr_ty p;
|
||||
p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
|
||||
if (!p) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
p->kind = Set_kind;
|
||||
p->v.Set.elts = elts;
|
||||
p->lineno = lineno;
|
||||
p->col_offset = col_offset;
|
||||
return p;
|
||||
}
|
||||
|
||||
expr_ty
|
||||
ListComp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset,
|
||||
PyArena *arena)
|
||||
|
@ -2424,6 +2446,15 @@ ast2obj_expr(void* _o)
|
|||
goto failed;
|
||||
Py_DECREF(value);
|
||||
break;
|
||||
case Set_kind:
|
||||
result = PyType_GenericNew(Set_type, NULL, NULL);
|
||||
if (!result) goto failed;
|
||||
value = ast2obj_list(o->v.Set.elts, ast2obj_expr);
|
||||
if (!value) goto failed;
|
||||
if (PyObject_SetAttrString(result, "elts", value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
break;
|
||||
case ListComp_kind:
|
||||
result = PyType_GenericNew(ListComp_type, NULL, NULL);
|
||||
if (!result) goto failed;
|
||||
|
@ -3069,6 +3100,7 @@ init_ast(void)
|
|||
return;
|
||||
if (PyDict_SetItemString(d, "IfExp", (PyObject*)IfExp_type) < 0) return;
|
||||
if (PyDict_SetItemString(d, "Dict", (PyObject*)Dict_type) < 0) return;
|
||||
if (PyDict_SetItemString(d, "Set", (PyObject*)Set_type) < 0) return;
|
||||
if (PyDict_SetItemString(d, "ListComp", (PyObject*)ListComp_type) < 0)
|
||||
return;
|
||||
if (PyDict_SetItemString(d, "GeneratorExp",
|
||||
|
|
68
Python/ast.c
68
Python/ast.c
|
@ -394,6 +394,7 @@ set_context(expr_ty e, expr_context_ty ctx, const node *n)
|
|||
expr_name = "list comprehension";
|
||||
break;
|
||||
case Dict_kind:
|
||||
case Set_kind:
|
||||
case Num_kind:
|
||||
case Str_kind:
|
||||
expr_name = "literal";
|
||||
|
@ -1187,7 +1188,7 @@ static expr_ty
|
|||
ast_for_atom(struct compiling *c, const node *n)
|
||||
{
|
||||
/* atom: '(' [yield_expr|testlist_gexp] ')' | '[' [listmaker] ']'
|
||||
| '{' [dictmaker] '}' | NAME | NUMBER | STRING+
|
||||
| '{' [dictsetmaker] '}' | NAME | NUMBER | STRING+
|
||||
*/
|
||||
node *ch = CHILD(n, 0);
|
||||
|
||||
|
@ -1242,36 +1243,55 @@ ast_for_atom(struct compiling *c, const node *n)
|
|||
else
|
||||
return ast_for_listcomp(c, ch);
|
||||
case LBRACE: {
|
||||
/* dictmaker: test ':' test (',' test ':' test)* [','] */
|
||||
/* dictsetmaker: test ':' test (',' test ':' test)* [','] |
|
||||
* test (',' test)* [','] */
|
||||
int i, size;
|
||||
asdl_seq *keys, *values;
|
||||
|
||||
ch = CHILD(n, 1);
|
||||
size = (NCH(ch) + 1) / 4; /* +1 in case no trailing comma */
|
||||
keys = asdl_seq_new(size, c->c_arena);
|
||||
if (!keys)
|
||||
return NULL;
|
||||
|
||||
values = asdl_seq_new(size, c->c_arena);
|
||||
if (!values)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < NCH(ch); i += 4) {
|
||||
expr_ty expression;
|
||||
|
||||
expression = ast_for_expr(c, CHILD(ch, i));
|
||||
if (!expression)
|
||||
return NULL;
|
||||
if (NCH(ch) == 1 || (NCH(ch) > 0 && STR(CHILD(ch, 1))[0] == ',')) {
|
||||
/* it's a set */
|
||||
size = (NCH(ch) + 1) / 2; /* +1 in case no trailing comma */
|
||||
keys = asdl_seq_new(size, c->c_arena);
|
||||
if (!keys)
|
||||
return NULL;
|
||||
|
||||
asdl_seq_SET(keys, i / 4, expression);
|
||||
for (i = 0; i < NCH(ch); i += 2) {
|
||||
expr_ty expression;
|
||||
expression = ast_for_expr(c, CHILD(ch, i));
|
||||
if (!expression)
|
||||
return NULL;
|
||||
asdl_seq_SET(keys, i / 2, expression);
|
||||
}
|
||||
return Set(keys, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
} else {
|
||||
/* it's a dict */
|
||||
size = (NCH(ch) + 1) / 4; /* +1 in case no trailing comma */
|
||||
keys = asdl_seq_new(size, c->c_arena);
|
||||
if (!keys)
|
||||
return NULL;
|
||||
|
||||
values = asdl_seq_new(size, c->c_arena);
|
||||
if (!values)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < NCH(ch); i += 4) {
|
||||
expr_ty expression;
|
||||
|
||||
expression = ast_for_expr(c, CHILD(ch, i));
|
||||
if (!expression)
|
||||
return NULL;
|
||||
|
||||
expression = ast_for_expr(c, CHILD(ch, i + 2));
|
||||
if (!expression)
|
||||
return NULL;
|
||||
asdl_seq_SET(keys, i / 4, expression);
|
||||
|
||||
asdl_seq_SET(values, i / 4, expression);
|
||||
}
|
||||
return Dict(keys, values, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
expression = ast_for_expr(c, CHILD(ch, i + 2));
|
||||
if (!expression)
|
||||
return NULL;
|
||||
|
||||
asdl_seq_SET(values, i / 4, expression);
|
||||
}
|
||||
return Dict(keys, values, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
}
|
||||
}
|
||||
default:
|
||||
PyErr_Format(PyExc_SystemError, "unhandled atom %d", TYPE(ch));
|
||||
|
|
|
@ -1945,6 +1945,24 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
|
|||
}
|
||||
break;
|
||||
|
||||
case BUILD_SET:
|
||||
x = PySet_New(NULL);
|
||||
if (x != NULL) {
|
||||
for (; --oparg >= 0;) {
|
||||
w = POP();
|
||||
if (err == 0)
|
||||
err = PySet_Add(x, w);
|
||||
Py_DECREF(w);
|
||||
}
|
||||
if (err != 0) {
|
||||
Py_DECREF(x);
|
||||
break;
|
||||
}
|
||||
PUSH(x);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case BUILD_MAP:
|
||||
x = PyDict_New();
|
||||
PUSH(x);
|
||||
|
|
|
@ -851,6 +851,7 @@ opcode_stack_effect(int opcode, int oparg)
|
|||
return 1;
|
||||
case BUILD_TUPLE:
|
||||
case BUILD_LIST:
|
||||
case BUILD_SET:
|
||||
return 1-oparg;
|
||||
case BUILD_MAP:
|
||||
return 1;
|
||||
|
@ -2955,6 +2956,11 @@ compiler_visit_expr(struct compiler *c, expr_ty e)
|
|||
ADDOP(c, STORE_SUBSCR);
|
||||
}
|
||||
break;
|
||||
case Set_kind:
|
||||
n = asdl_seq_LEN(e->v.Set.elts);
|
||||
VISIT_SEQ(c, expr, e->v.Set.elts);
|
||||
ADDOP_I(c, BUILD_SET, n);
|
||||
break;
|
||||
case ListComp_kind:
|
||||
return compiler_listcomp(c, e);
|
||||
case GeneratorExp_kind:
|
||||
|
|
|
@ -1500,26 +1500,42 @@ static state states_70[3] = {
|
|||
static arc arcs_71_0[1] = {
|
||||
{26, 1},
|
||||
};
|
||||
static arc arcs_71_1[1] = {
|
||||
static arc arcs_71_1[3] = {
|
||||
{21, 2},
|
||||
{27, 3},
|
||||
{0, 1},
|
||||
};
|
||||
static arc arcs_71_2[1] = {
|
||||
{26, 3},
|
||||
{26, 4},
|
||||
};
|
||||
static arc arcs_71_3[2] = {
|
||||
{27, 4},
|
||||
{26, 5},
|
||||
{0, 3},
|
||||
};
|
||||
static arc arcs_71_4[2] = {
|
||||
{26, 1},
|
||||
{27, 6},
|
||||
{0, 4},
|
||||
};
|
||||
static state states_71[5] = {
|
||||
static arc arcs_71_5[2] = {
|
||||
{27, 3},
|
||||
{0, 5},
|
||||
};
|
||||
static arc arcs_71_6[2] = {
|
||||
{26, 7},
|
||||
{0, 6},
|
||||
};
|
||||
static arc arcs_71_7[1] = {
|
||||
{21, 2},
|
||||
};
|
||||
static state states_71[8] = {
|
||||
{1, arcs_71_0},
|
||||
{1, arcs_71_1},
|
||||
{3, arcs_71_1},
|
||||
{1, arcs_71_2},
|
||||
{2, arcs_71_3},
|
||||
{2, arcs_71_4},
|
||||
{2, arcs_71_5},
|
||||
{2, arcs_71_6},
|
||||
{1, arcs_71_7},
|
||||
};
|
||||
static arc arcs_72_0[1] = {
|
||||
{157, 1},
|
||||
|
@ -1911,7 +1927,7 @@ static dfa dfas[84] = {
|
|||
"\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\140\010\311\000\000"},
|
||||
{326, "testlist", 0, 3, states_70,
|
||||
"\000\040\010\000\000\000\000\000\000\000\000\000\000\020\004\000\140\010\311\000\000"},
|
||||
{327, "dictmaker", 0, 5, states_71,
|
||||
{327, "dictsetmaker", 0, 8, states_71,
|
||||
"\000\040\010\000\000\000\000\000\000\000\000\000\000\020\004\000\140\010\311\000\000"},
|
||||
{328, "classdef", 0, 8, states_72,
|
||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\040\000"},
|
||||
|
|
|
@ -66,9 +66,10 @@ extern time_t PyOS_GetLastModificationTime(char *, FILE *);
|
|||
storing constants that should have been removed)
|
||||
Python 3000: 3000
|
||||
3010 (removed UNARY_CONVERT)
|
||||
3020 (added BUILD_SET)
|
||||
.
|
||||
*/
|
||||
#define MAGIC (3010 | ((long)'\r'<<16) | ((long)'\n'<<24))
|
||||
#define MAGIC (3020 | ((long)'\r'<<16) | ((long)'\n'<<24))
|
||||
|
||||
/* Magic word as global; note that _PyImport_Init() can change the
|
||||
value of this global to accommodate for alterations of how the
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue