Пример #1
0
static int 
symtable_visit_genexp(struct symtable *st, expr_ty e)
{
	comprehension_ty outermost = ((comprehension_ty)
			 (asdl_seq_GET(e->v.GeneratorExp.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, 0)) {
		return 0;
	}
	st->st_cur->ste_generator = 1;
	/* Outermost iter is received as an argument */
	if (!symtable_implicit_arg(st, 0)) {
		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);
	return symtable_exit_block(st, (void *)e);
}
Пример #2
0
struct symtable *
PySymtable_Build(mod_ty mod, const char *filename, PyFutureFeatures *future)
{
    struct symtable *st = symtable_new();
    asdl_seq *seq;
    int i;

    if (st == NULL)
        return st;
    st->st_filename = filename;
    st->st_future = future;
    if (!GET_IDENTIFIER(top) ||
        !symtable_enter_block(st, top, ModuleBlock, (void *)mod, 0)) {
        PySymtable_Free(st);
        return NULL;
    }

    st->st_top = st->st_cur;
    st->st_cur->ste_unoptimized = OPT_TOPLEVEL;
    /* Any other top-level initialization? */
    switch (mod->kind) {
    case Module_kind:
        seq = mod->v.Module.body;
        for (i = 0; i < asdl_seq_LEN(seq); i++)
            if (!symtable_visit_stmt(st,
                        (stmt_ty)asdl_seq_GET(seq, i)))
                goto error;
        break;
    case Expression_kind:
        if (!symtable_visit_expr(st, mod->v.Expression.body))
            goto error;
        break;
    case Interactive_kind:
        seq = mod->v.Interactive.body;
        for (i = 0; i < asdl_seq_LEN(seq); i++)
            if (!symtable_visit_stmt(st,
                        (stmt_ty)asdl_seq_GET(seq, i)))
                goto error;
        break;
    case Suite_kind:
        PyErr_SetString(PyExc_RuntimeError,
                        "this compiler does not handle Suites");
        goto error;
    }
    if (!symtable_exit_block(st, (void *)mod)) {
        PySymtable_Free(st);
        return NULL;
    }
    if (symtable_analyze(st))
        return st;
    PySymtable_Free(st);
    return NULL;
 error:
    (void) symtable_exit_block(st, (void *)mod);
    PySymtable_Free(st);
    return NULL;
}
Пример #3
0
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(generators, 0));
    /* Outermost iterator is evaluated in current scope */
    VISIT(st, expr, outermost->iter);
    /* 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 = 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,
                            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);
}
Пример #4
0
static int
symtable_visit_stmt(struct symtable *st, stmt_ty s)
{
    switch (s->kind) {
    case FunctionDef_kind:
        if (!symtable_add_def(st, s->v.FunctionDef.name, DEF_LOCAL))
            return 0;
        if (s->v.FunctionDef.args->defaults)
            VISIT_SEQ(st, expr, s->v.FunctionDef.args->defaults);
        if (s->v.FunctionDef.decorator_list)
            VISIT_SEQ(st, expr, s->v.FunctionDef.decorator_list);
        if (!symtable_enter_block(st, s->v.FunctionDef.name,
                                  FunctionBlock, (void *)s, s->lineno))
            return 0;
        VISIT_IN_BLOCK(st, arguments, s->v.FunctionDef.args, s);
        VISIT_SEQ_IN_BLOCK(st, stmt, s->v.FunctionDef.body, s);
        if (!symtable_exit_block(st, s))
            return 0;
        break;
    case ClassDef_kind: {
        PyObject *tmp;
        if (!symtable_add_def(st, s->v.ClassDef.name, DEF_LOCAL))
            return 0;
        VISIT_SEQ(st, expr, s->v.ClassDef.bases);
        if (s->v.ClassDef.decorator_list)
            VISIT_SEQ(st, expr, s->v.ClassDef.decorator_list);
        if (!symtable_enter_block(st, s->v.ClassDef.name, ClassBlock,
                                  (void *)s, s->lineno))
            return 0;
        tmp = st->st_private;
        st->st_private = s->v.ClassDef.name;
        VISIT_SEQ_IN_BLOCK(st, stmt, s->v.ClassDef.body, s);
        st->st_private = tmp;
        if (!symtable_exit_block(st, s))
            return 0;
        break;
    }
    case Return_kind:
        if (s->v.Return.value) {
            VISIT(st, expr, s->v.Return.value);
            st->st_cur->ste_returns_value = 1;
            if (st->st_cur->ste_generator) {
                PyErr_SetString(PyExc_SyntaxError,
                    RETURN_VAL_IN_GENERATOR);
                PyErr_SyntaxLocation(st->st_filename,
                             s->lineno);
                return 0;
            }
        }
        break;
    case Delete_kind:
        VISIT_SEQ(st, expr, s->v.Delete.targets);
        break;
    case Assign_kind:
        VISIT_SEQ(st, expr, s->v.Assign.targets);
        VISIT(st, expr, s->v.Assign.value);
        break;
    case AugAssign_kind:
        VISIT(st, expr, s->v.AugAssign.target);
        VISIT(st, expr, s->v.AugAssign.value);
        break;
    case Print_kind:
        if (s->v.Print.dest)
            VISIT(st, expr, s->v.Print.dest);
        VISIT_SEQ(st, expr, s->v.Print.values);
        break;
    case For_kind:
        VISIT(st, expr, s->v.For.target);
        VISIT(st, expr, s->v.For.iter);
        VISIT_SEQ(st, stmt, s->v.For.body);
        if (s->v.For.orelse)
            VISIT_SEQ(st, stmt, s->v.For.orelse);
        break;
    case While_kind:
        VISIT(st, expr, s->v.While.test);
        VISIT_SEQ(st, stmt, s->v.While.body);
        if (s->v.While.orelse)
            VISIT_SEQ(st, stmt, s->v.While.orelse);
        break;
    case If_kind:
        /* XXX if 0: and lookup_yield() hacks */
        VISIT(st, expr, s->v.If.test);
        VISIT_SEQ(st, stmt, s->v.If.body);
        if (s->v.If.orelse)
            VISIT_SEQ(st, stmt, s->v.If.orelse);
        break;
    case Raise_kind:
        if (s->v.Raise.type) {
            VISIT(st, expr, s->v.Raise.type);
            if (s->v.Raise.inst) {
                VISIT(st, expr, s->v.Raise.inst);
                if (s->v.Raise.tback)
                    VISIT(st, expr, s->v.Raise.tback);
            }
        }
        break;
    case TryExcept_kind:
        VISIT_SEQ(st, stmt, s->v.TryExcept.body);
        VISIT_SEQ(st, stmt, s->v.TryExcept.orelse);
        VISIT_SEQ(st, excepthandler, s->v.TryExcept.handlers);
        break;
    case TryFinally_kind:
        VISIT_SEQ(st, stmt, s->v.TryFinally.body);
        VISIT_SEQ(st, stmt, s->v.TryFinally.finalbody);
        break;
    case Assert_kind:
        VISIT(st, expr, s->v.Assert.test);
        if (s->v.Assert.msg)
            VISIT(st, expr, s->v.Assert.msg);
        break;
    case Import_kind:
        VISIT_SEQ(st, alias, s->v.Import.names);
        /* XXX Don't have the lineno available inside
           visit_alias */
        if (st->st_cur->ste_unoptimized && !st->st_cur->ste_opt_lineno)
            st->st_cur->ste_opt_lineno = s->lineno;
        break;
    case ImportFrom_kind:
        VISIT_SEQ(st, alias, s->v.ImportFrom.names);
        /* XXX Don't have the lineno available inside
           visit_alias */
        if (st->st_cur->ste_unoptimized && !st->st_cur->ste_opt_lineno)
            st->st_cur->ste_opt_lineno = s->lineno;
        break;
    case Exec_kind:
        VISIT(st, expr, s->v.Exec.body);
        if (!st->st_cur->ste_opt_lineno)
            st->st_cur->ste_opt_lineno = s->lineno;
        if (s->v.Exec.globals) {
            st->st_cur->ste_unoptimized |= OPT_EXEC;
            VISIT(st, expr, s->v.Exec.globals);
            if (s->v.Exec.locals)
                VISIT(st, expr, s->v.Exec.locals);
        } else {
            st->st_cur->ste_unoptimized |= OPT_BARE_EXEC;
        }
        break;
    case Global_kind: {
        int i;
        asdl_seq *seq = s->v.Global.names;
        for (i = 0; i < asdl_seq_LEN(seq); i++) {
            identifier name = (identifier)asdl_seq_GET(seq, i);
            char *c_name = PyString_AS_STRING(name);
            long cur = symtable_lookup(st, name);
            if (cur < 0)
                return 0;
            if (cur & (DEF_LOCAL | USE)) {
                char buf[256];
                if (cur & DEF_LOCAL)
                    PyOS_snprintf(buf, sizeof(buf),
                                  GLOBAL_AFTER_ASSIGN,
                                  c_name);
                else
                    PyOS_snprintf(buf, sizeof(buf),
                                  GLOBAL_AFTER_USE,
                                  c_name);
                if (!symtable_warn(st, buf, s->lineno))
                    return 0;
            }
            if (!symtable_add_def(st, name, DEF_GLOBAL))
                return 0;
        }
        break;
    }
    case Expr_kind:
        VISIT(st, expr, s->v.Expr.value);
        break;
    case Pass_kind:
    case Break_kind:
    case Continue_kind:
        /* nothing to do here */
        break;
    case With_kind:
        VISIT(st, expr, s->v.With.context_expr);
        if (s->v.With.optional_vars) {
            VISIT(st, expr, s->v.With.optional_vars);
        }
        VISIT_SEQ(st, stmt, s->v.With.body);
        break;
    }
    return 1;
}
Пример #5
0
static int
symtable_visit_expr(struct symtable *st, expr_ty e)
{
    switch (e->kind) {
    case BoolOp_kind:
        VISIT_SEQ(st, expr, e->v.BoolOp.values);
        break;
    case BinOp_kind:
        VISIT(st, expr, e->v.BinOp.left);
        VISIT(st, expr, e->v.BinOp.right);
        break;
    case UnaryOp_kind:
        VISIT(st, expr, e->v.UnaryOp.operand);
        break;
    case Lambda_kind: {
        if (!GET_IDENTIFIER(lambda))
            return 0;
        if (e->v.Lambda.args->defaults)
            VISIT_SEQ(st, expr, e->v.Lambda.args->defaults);
        if (!symtable_enter_block(st, lambda,
                                  FunctionBlock, (void *)e, e->lineno))
            return 0;
        VISIT_IN_BLOCK(st, arguments, e->v.Lambda.args, (void*)e);
        VISIT_IN_BLOCK(st, expr, e->v.Lambda.body, (void*)e);
        if (!symtable_exit_block(st, (void *)e))
            return 0;
        break;
    }
    case IfExp_kind:
        VISIT(st, expr, e->v.IfExp.test);
        VISIT(st, expr, e->v.IfExp.body);
        VISIT(st, expr, e->v.IfExp.orelse);
        break;
    case Dict_kind:
        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:
        VISIT(st, expr, e->v.ListComp.elt);
        VISIT_SEQ(st, comprehension, e->v.ListComp.generators);
        break;
    case GeneratorExp_kind:
        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);
        st->st_cur->ste_generator = 1;
        if (st->st_cur->ste_returns_value) {
            PyErr_SetString(PyExc_SyntaxError,
                RETURN_VAL_IN_GENERATOR);
            PyErr_SyntaxLocation(st->st_filename,
                         e->lineno);
            return 0;
        }
        break;
    case Compare_kind:
        VISIT(st, expr, e->v.Compare.left);
        VISIT_SEQ(st, expr, e->v.Compare.comparators);
        break;
    case Call_kind:
        VISIT(st, expr, e->v.Call.func);
        VISIT_SEQ(st, expr, e->v.Call.args);
        VISIT_SEQ(st, keyword, e->v.Call.keywords);
        if (e->v.Call.starargs)
            VISIT(st, expr, e->v.Call.starargs);
        if (e->v.Call.kwargs)
            VISIT(st, expr, e->v.Call.kwargs);
        break;
    case Repr_kind:
        VISIT(st, expr, e->v.Repr.value);
        break;
    case Num_kind:
    case Str_kind:
        /* Nothing to do here. */
        break;
    /* The following exprs can be assignment targets. */
    case Attribute_kind:
        VISIT(st, expr, e->v.Attribute.value);
        break;
    case Subscript_kind:
        VISIT(st, expr, e->v.Subscript.value);
        VISIT(st, slice, e->v.Subscript.slice);
        break;
    case Name_kind:
        if (!symtable_add_def(st, e->v.Name.id,
                              e->v.Name.ctx == Load ? USE : DEF_LOCAL))
            return 0;
        break;
    /* child nodes of List and Tuple will have expr_context set */
    case List_kind:
        VISIT_SEQ(st, expr, e->v.List.elts);
        break;
    case Tuple_kind:
        VISIT_SEQ(st, expr, e->v.Tuple.elts);
        break;
    }
    return 1;
}