SF patch 1547796 by Georg Brandl -- set literals.

This commit is contained in:
Guido van Rossum 2006-08-28 15:27:34 +00:00
parent ecfd0b2f3b
commit 86e58e239e
22 changed files with 229 additions and 72 deletions

View file

@ -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",

View file

@ -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));

View file

@ -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);

View file

@ -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:

View file

@ -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"},

View file

@ -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