diff options
Diffstat (limited to 'Python/symtable.c')
| -rw-r--r-- | Python/symtable.c | 122 | 
1 files changed, 82 insertions, 40 deletions
| diff --git a/Python/symtable.c b/Python/symtable.c index f30ba0f..51b59f0 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -32,7 +32,6 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block,          goto fail;      ste->ste_table = st;      ste->ste_id = k; -    ste->ste_tmpname = 0;      ste->ste_name = name;      Py_INCREF(name); @@ -168,6 +167,8 @@ static int symtable_exit_block(struct symtable *st, void *ast);  static int symtable_visit_stmt(struct symtable *st, stmt_ty s);  static int symtable_visit_expr(struct symtable *st, expr_ty s);  static int symtable_visit_genexp(struct symtable *st, expr_ty s); +static int symtable_visit_setcomp(struct symtable *st, expr_ty e); +static int symtable_visit_dictcomp(struct symtable *st, expr_ty e);  static int symtable_visit_arguments(struct symtable *st, arguments_ty);  static int symtable_visit_excepthandler(struct symtable *st, excepthandler_ty);  static int symtable_visit_alias(struct symtable *st, alias_ty); @@ -179,7 +180,8 @@ static int symtable_visit_params_nested(struct symtable *st, asdl_seq *args);  static int symtable_implicit_arg(struct symtable *st, int pos); -static identifier top = NULL, lambda = NULL, genexpr = NULL; +static identifier top = NULL, lambda = NULL, genexpr = NULL, setcomp = NULL, +    dictcomp = NULL;  #define GET_IDENTIFIER(VAR) \      ((VAR) ? (VAR) : ((VAR) = PyString_InternFromString(# VAR))) @@ -204,7 +206,6 @@ symtable_new(void)      if ((st->st_symbols = PyDict_New()) == NULL)          goto fail;      st->st_cur = NULL; -    st->st_tmpname = 0;      st->st_private = NULL;      return st;   fail: @@ -495,7 +496,7 @@ check_unoptimized(const PySTEntryObject* ste) {      case OPT_IMPORT_STAR:          PyOS_snprintf(buf, sizeof(buf),                        "import * is not allowed in function '%.100s' " -                      "because it is %s", +                      "because it %s",                        PyString_AS_STRING(ste->ste_name), trailer);          break;      case OPT_BARE_EXEC: @@ -702,7 +703,8 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,              ste->ste_child_free = 1;      } -    PyDict_Update(newfree, allfree); +    if (PyDict_Update(newfree, allfree) < 0) +        goto error;      if (ste->ste_type == FunctionBlock && !analyze_cells(scope, newfree))          goto error;      if (!update_symbols(ste->ste_symbols, scope, bound, newfree, @@ -846,7 +848,7 @@ symtable_enter_block(struct symtable *st, identifier name, _Py_block_ty block,      st->st_cur = ste_new(st, name, block, ast, lineno);      if (st->st_cur == NULL)          return 0; -    if (name == GET_IDENTIFIER(top)) +    if (block == ModuleBlock)          st->st_global = st->st_cur->ste_symbols;      if (prev) {          if (PyList_Append(prev->ste_children, @@ -994,23 +996,6 @@ error:  }  static int -symtable_new_tmpname(struct symtable *st) -{ -    char tmpname[256]; -    identifier tmp; - -    PyOS_snprintf(tmpname, sizeof(tmpname), "_[%d]", -                  ++st->st_cur->ste_tmpname); -    tmp = PyString_InternFromString(tmpname); -    if (!tmp) -        return 0; -    if (!symtable_add_def(st, tmp, DEF_LOCAL)) -        return 0; -    Py_DECREF(tmp); -    return 1; -} - -static int  symtable_visit_stmt(struct symtable *st, stmt_ty s)  {      switch (s->kind) { @@ -1183,12 +1168,8 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)          /* nothing to do here */          break;      case With_kind: -        if (!symtable_new_tmpname(st)) -            return 0;          VISIT(st, expr, s->v.With.context_expr);          if (s->v.With.optional_vars) { -            if (!symtable_new_tmpname(st)) -                return 0;              VISIT(st, expr, s->v.With.optional_vars);          }          VISIT_SEQ(st, stmt, s->v.With.body); @@ -1212,8 +1193,7 @@ symtable_visit_expr(struct symtable *st, expr_ty e)          VISIT(st, expr, e->v.UnaryOp.operand);          break;      case Lambda_kind: { -        if (!GET_IDENTIFIER(lambda) || -            !symtable_add_def(st, lambda, DEF_LOCAL)) +        if (!GET_IDENTIFIER(lambda))              return 0;          if (e->v.Lambda.args->defaults)              VISIT_SEQ(st, expr, e->v.Lambda.args->defaults); @@ -1235,9 +1215,10 @@ symtable_visit_expr(struct symtable *st, expr_ty e)          VISIT_SEQ(st, expr, e->v.Dict.keys);          VISIT_SEQ(st, expr, e->v.Dict.values);          break; +    case Set_kind: +        VISIT_SEQ(st, expr, e->v.Set.elts); +        break;      case ListComp_kind: -        if (!symtable_new_tmpname(st)) -            return 0;          VISIT(st, expr, e->v.ListComp.elt);          VISIT_SEQ(st, comprehension, e->v.ListComp.generators);          break; @@ -1245,6 +1226,14 @@ symtable_visit_expr(struct symtable *st, expr_ty e)          if (!symtable_visit_genexp(st, e))              return 0;          break; +    case SetComp_kind: +        if (!symtable_visit_setcomp(st, e)) +            return 0; +        break; +    case DictComp_kind: +        if (!symtable_visit_dictcomp(st, e)) +            return 0; +        break;      case Yield_kind:          if (e->v.Yield.value)              VISIT(st, expr, e->v.Yield.value); @@ -1407,7 +1396,7 @@ static int  symtable_visit_alias(struct symtable *st, alias_ty a)  {      /* Compute store_name, the name actually bound by the import -       operation.  It is diferent than a->name when a->name is a +       operation.  It is different than a->name when a->name is a         dotted package name (e.g. spam.eggs)      */      PyObject *store_name; @@ -1486,27 +1475,80 @@ symtable_visit_slice(struct symtable *st, slice_ty s)  }  static int -symtable_visit_genexp(struct symtable *st, expr_ty e) +symtable_new_tmpname(struct symtable *st)  { +    char tmpname[256]; +    identifier tmp; + +    PyOS_snprintf(tmpname, sizeof(tmpname), "_[%d]", +                  ++st->st_cur->ste_tmpname); +    tmp = PyString_InternFromString(tmpname); +    if (!tmp) +        return 0; +    if (!symtable_add_def(st, tmp, DEF_LOCAL)) +        return 0; +    Py_DECREF(tmp); +    return 1; +} + +static int +symtable_handle_comprehension(struct symtable *st, expr_ty e, +                              identifier scope_name, asdl_seq *generators, +                              expr_ty elt, expr_ty value) +{ +    int is_generator = (e->kind == GeneratorExp_kind); +    int needs_tmp = !is_generator;      comprehension_ty outermost = ((comprehension_ty) -                     (asdl_seq_GET(e->v.GeneratorExp.generators, 0))); +                                    asdl_seq_GET(generators, 0));      /* Outermost iterator is evaluated in current scope */      VISIT(st, expr, outermost->iter); -    /* Create generator scope for the rest */ -    if (!GET_IDENTIFIER(genexpr) || -        !symtable_enter_block(st, genexpr, FunctionBlock, (void *)e, e->lineno)) { +    /* Create comprehension scope for the rest */ +    if (!scope_name || +        !symtable_enter_block(st, scope_name, FunctionBlock, (void *)e, 0)) {          return 0;      } -    st->st_cur->ste_generator = 1; +    st->st_cur->ste_generator = is_generator;      /* Outermost iter is received as an argument */      if (!symtable_implicit_arg(st, 0)) {          symtable_exit_block(st, (void *)e);          return 0;      } +    /* Allocate temporary name if needed */ +    if (needs_tmp && !symtable_new_tmpname(st)) { +        symtable_exit_block(st, (void *)e); +        return 0; +    }      VISIT_IN_BLOCK(st, expr, outermost->target, (void*)e);      VISIT_SEQ_IN_BLOCK(st, expr, outermost->ifs, (void*)e);      VISIT_SEQ_TAIL_IN_BLOCK(st, comprehension, -                            e->v.GeneratorExp.generators, 1, (void*)e); -    VISIT_IN_BLOCK(st, expr, e->v.GeneratorExp.elt, (void*)e); +                            generators, 1, (void*)e); +    if (value) +        VISIT_IN_BLOCK(st, expr, value, (void*)e); +    VISIT_IN_BLOCK(st, expr, elt, (void*)e);      return symtable_exit_block(st, (void *)e);  } + +static int +symtable_visit_genexp(struct symtable *st, expr_ty e) +{ +    return symtable_handle_comprehension(st, e, GET_IDENTIFIER(genexpr), +                                         e->v.GeneratorExp.generators, +                                         e->v.GeneratorExp.elt, NULL); +} + +static int +symtable_visit_setcomp(struct symtable *st, expr_ty e) +{ +    return symtable_handle_comprehension(st, e, GET_IDENTIFIER(setcomp), +                                         e->v.SetComp.generators, +                                         e->v.SetComp.elt, NULL); +} + +static int +symtable_visit_dictcomp(struct symtable *st, expr_ty e) +{ +    return symtable_handle_comprehension(st, e, GET_IDENTIFIER(dictcomp), +                                         e->v.DictComp.generators, +                                         e->v.DictComp.key, +                                         e->v.DictComp.value); +} | 
