comparison Python/symtable.c @ 58250:edfed0e32ced legacy-trunk

Issue #2333: Backport set and dict comprehensions syntax.
author Alexandre Vassalotti <alexandre@peadrop.com>
date Mon, 11 Jan 2010 22:36:12 +0000
parents c2fdf25329ff
children fd25030223b0
comparison
equal deleted inserted replaced
58249:33e402909cf2 58250:edfed0e32ced
164 _Py_block_ty block, void *ast, int lineno); 164 _Py_block_ty block, void *ast, int lineno);
165 static int symtable_exit_block(struct symtable *st, void *ast); 165 static int symtable_exit_block(struct symtable *st, void *ast);
166 static int symtable_visit_stmt(struct symtable *st, stmt_ty s); 166 static int symtable_visit_stmt(struct symtable *st, stmt_ty s);
167 static int symtable_visit_expr(struct symtable *st, expr_ty s); 167 static int symtable_visit_expr(struct symtable *st, expr_ty s);
168 static int symtable_visit_genexp(struct symtable *st, expr_ty s); 168 static int symtable_visit_genexp(struct symtable *st, expr_ty s);
169 static int symtable_visit_setcomp(struct symtable *st, expr_ty e);
170 static int symtable_visit_dictcomp(struct symtable *st, expr_ty e);
169 static int symtable_visit_arguments(struct symtable *st, arguments_ty); 171 static int symtable_visit_arguments(struct symtable *st, arguments_ty);
170 static int symtable_visit_excepthandler(struct symtable *st, excepthandler_ty); 172 static int symtable_visit_excepthandler(struct symtable *st, excepthandler_ty);
171 static int symtable_visit_alias(struct symtable *st, alias_ty); 173 static int symtable_visit_alias(struct symtable *st, alias_ty);
172 static int symtable_visit_comprehension(struct symtable *st, comprehension_ty); 174 static int symtable_visit_comprehension(struct symtable *st, comprehension_ty);
173 static int symtable_visit_keyword(struct symtable *st, keyword_ty); 175 static int symtable_visit_keyword(struct symtable *st, keyword_ty);
175 static int symtable_visit_params(struct symtable *st, asdl_seq *args, int top); 177 static int symtable_visit_params(struct symtable *st, asdl_seq *args, int top);
176 static int symtable_visit_params_nested(struct symtable *st, asdl_seq *args); 178 static int symtable_visit_params_nested(struct symtable *st, asdl_seq *args);
177 static int symtable_implicit_arg(struct symtable *st, int pos); 179 static int symtable_implicit_arg(struct symtable *st, int pos);
178 180
179 181
180 static identifier top = NULL, lambda = NULL, genexpr = NULL; 182 static identifier top = NULL, lambda = NULL, genexpr = NULL, setcomp = NULL,
183 dictcomp = NULL;
181 184
182 #define GET_IDENTIFIER(VAR) \ 185 #define GET_IDENTIFIER(VAR) \
183 ((VAR) ? (VAR) : ((VAR) = PyString_InternFromString(# VAR))) 186 ((VAR) ? (VAR) : ((VAR) = PyString_InternFromString(# VAR)))
184 187
185 #define DUPLICATE_ARGUMENT \ 188 #define DUPLICATE_ARGUMENT \
1220 break; 1223 break;
1221 case GeneratorExp_kind: 1224 case GeneratorExp_kind:
1222 if (!symtable_visit_genexp(st, e)) 1225 if (!symtable_visit_genexp(st, e))
1223 return 0; 1226 return 0;
1224 break; 1227 break;
1228 case SetComp_kind:
1229 if (!symtable_visit_setcomp(st, e))
1230 return 0;
1231 break;
1232 case DictComp_kind:
1233 if (!symtable_visit_dictcomp(st, e))
1234 return 0;
1235 break;
1225 case Yield_kind: 1236 case Yield_kind:
1226 if (e->v.Yield.value) 1237 if (e->v.Yield.value)
1227 VISIT(st, expr, e->v.Yield.value); 1238 VISIT(st, expr, e->v.Yield.value);
1228 st->st_cur->ste_generator = 1; 1239 st->st_cur->ste_generator = 1;
1229 if (st->st_cur->ste_returns_value) { 1240 if (st->st_cur->ste_returns_value) {
1460 break; 1471 break;
1461 } 1472 }
1462 return 1; 1473 return 1;
1463 } 1474 }
1464 1475
1476 static int
1477 symtable_new_tmpname(struct symtable *st)
1478 {
1479 char tmpname[256];
1480 identifier tmp;
1481
1482 PyOS_snprintf(tmpname, sizeof(tmpname), "_[%d]",
1483 ++st->st_cur->ste_tmpname);
1484 tmp = PyString_InternFromString(tmpname);
1485 if (!tmp)
1486 return 0;
1487 if (!symtable_add_def(st, tmp, DEF_LOCAL))
1488 return 0;
1489 Py_DECREF(tmp);
1490 return 1;
1491 }
1492
1465 static int 1493 static int
1466 symtable_visit_genexp(struct symtable *st, expr_ty e) 1494 symtable_handle_comprehension(struct symtable *st, expr_ty e,
1467 { 1495 identifier scope_name, asdl_seq *generators,
1496 expr_ty elt, expr_ty value)
1497 {
1498 int is_generator = (e->kind == GeneratorExp_kind);
1499 int needs_tmp = !is_generator;
1468 comprehension_ty outermost = ((comprehension_ty) 1500 comprehension_ty outermost = ((comprehension_ty)
1469 (asdl_seq_GET(e->v.GeneratorExp.generators, 0))); 1501 asdl_seq_GET(generators, 0));
1470 /* Outermost iterator is evaluated in current scope */ 1502 /* Outermost iterator is evaluated in current scope */
1471 VISIT(st, expr, outermost->iter); 1503 VISIT(st, expr, outermost->iter);
1472 /* Create generator scope for the rest */ 1504 /* Create comprehension scope for the rest */
1473 if (!GET_IDENTIFIER(genexpr) || 1505 if (!scope_name ||
1474 !symtable_enter_block(st, genexpr, FunctionBlock, (void *)e, e->lineno)) { 1506 !symtable_enter_block(st, scope_name, FunctionBlock, (void *)e, 0)) {
1475 return 0; 1507 return 0;
1476 } 1508 }
1477 st->st_cur->ste_generator = 1; 1509 st->st_cur->ste_generator = is_generator;
1478 /* Outermost iter is received as an argument */ 1510 /* Outermost iter is received as an argument */
1479 if (!symtable_implicit_arg(st, 0)) { 1511 if (!symtable_implicit_arg(st, 0)) {
1480 symtable_exit_block(st, (void *)e); 1512 symtable_exit_block(st, (void *)e);
1481 return 0; 1513 return 0;
1482 } 1514 }
1515 /* Allocate temporary name if needed */
1516 if (needs_tmp && !symtable_new_tmpname(st)) {
1517 symtable_exit_block(st, (void *)e);
1518 return 0;
1519 }
1483 VISIT_IN_BLOCK(st, expr, outermost->target, (void*)e); 1520 VISIT_IN_BLOCK(st, expr, outermost->target, (void*)e);
1484 VISIT_SEQ_IN_BLOCK(st, expr, outermost->ifs, (void*)e); 1521 VISIT_SEQ_IN_BLOCK(st, expr, outermost->ifs, (void*)e);
1485 VISIT_SEQ_TAIL_IN_BLOCK(st, comprehension, 1522 VISIT_SEQ_TAIL_IN_BLOCK(st, comprehension,
1486 e->v.GeneratorExp.generators, 1, (void*)e); 1523 generators, 1, (void*)e);
1487 VISIT_IN_BLOCK(st, expr, e->v.GeneratorExp.elt, (void*)e); 1524 if (value)
1525 VISIT_IN_BLOCK(st, expr, value, (void*)e);
1526 VISIT_IN_BLOCK(st, expr, elt, (void*)e);
1488 return symtable_exit_block(st, (void *)e); 1527 return symtable_exit_block(st, (void *)e);
1489 } 1528 }
1529
1530 static int
1531 symtable_visit_genexp(struct symtable *st, expr_ty e)
1532 {
1533 return symtable_handle_comprehension(st, e, GET_IDENTIFIER(genexpr),
1534 e->v.GeneratorExp.generators,
1535 e->v.GeneratorExp.elt, NULL);
1536 }
1537
1538 static int
1539 symtable_visit_setcomp(struct symtable *st, expr_ty e)
1540 {
1541 return symtable_handle_comprehension(st, e, GET_IDENTIFIER(setcomp),
1542 e->v.SetComp.generators,
1543 e->v.SetComp.elt, NULL);
1544 }
1545
1546 static int
1547 symtable_visit_dictcomp(struct symtable *st, expr_ty e)
1548 {
1549 return symtable_handle_comprehension(st, e, GET_IDENTIFIER(dictcomp),
1550 e->v.DictComp.generators,
1551 e->v.DictComp.key,
1552 e->v.DictComp.value);
1553 }