void BytecodeTranslatorVisitor::visitBinaryOpNode(BinaryOpNode * node) { onVisitNode(node); TokenKind op = node->kind(); if (op == tOR || op == tAND) { processLazyLogic(node); return; } VISIT(node->right()); ensureTopIsNumeric(); VISIT(node->left()); ensureTopIsNumeric(); if (tEQ <= op && op <= tLE) processComparison(node->kind()); else if (tADD <= op && op <= tDIV) processNumericOperation(node->kind()); else if (op == tMOD || op == tAXOR || op == tAOR || op == tAAND) { popType(VT_INT); ensureTopType(VT_INT); EMIT(op == tAXOR ? BC_IAXOR : op == tMOD ? BC_IMOD : op == tAOR ? BC_IAOR : BC_IAAND); } else ERROR("Unknown binary op"); }
static int symtable_visit_comprehension(struct symtable *st, comprehension_ty lc) { VISIT(st, expr, lc->target); VISIT(st, expr, lc->iter); VISIT_SEQ(st, expr, lc->ifs); return 1; }
void BytecodeTranslatorVisitor::visitForNode(ForNode* node) { onVisitNode(node); const AstVar* i = node->var(); if (i->type() != VT_INT) ERROR("Non-iterable type in for loop"); const BinaryOpNode* expr = node->inExpr()->asBinaryOpNode(); if (expr == NULL || expr->kind() != tRANGE) ERROR("Invalid range in for loop"); CONTEXT(function(), locals(), node->body()->scope(), typeStack()); beforeProcessBlock(); bool needTempVar = !expr->right()->isIntLiteralNode(); AstVar* temp = NULL; if (needTempVar) { if (!scope()->declareVariable("<tempForEnd>", VT_INT)) ERROR("internal error: temp name is unavailable"); temp = scope()->lookupVariable("<tempForEnd>", false); } Label L_Begin(bytecode()); Label L_End(bytecode()); VISIT(expr->left()); EMIT_STORE(i); if (needTempVar) { VISIT(expr->right()); EMIT_STORE(temp); popType(VT_INT); } popType(VT_INT); EMIT_BIND(L_Begin); if (needTempVar) EMIT_LOAD(temp); else VISIT(expr->right()); EMIT_LOAD(i); EMIT_BRANCH(BC_IFICMPG, L_End); processBlockNode(node->body()); afterProcessBlock(); /* i += 1 */ EMIT_LOAD(i); EMIT(BC_ILOAD1); EMIT(BC_IADD); EMIT_STORE(i); EMIT_BRANCH(BC_JA, L_Begin); EMIT_BIND(L_End); pushType(VT_VOID); }
static int symtable_visit_excepthandler(struct symtable *st, excepthandler_ty eh) { if (eh->v.ExceptHandler.type) VISIT(st, expr, eh->v.ExceptHandler.type); if (eh->v.ExceptHandler.name) VISIT(st, expr, eh->v.ExceptHandler.name); VISIT_SEQ(st, stmt, eh->v.ExceptHandler.body); return 1; }
static int Writer_traverse(WriterObj *self, visitproc visit, void *arg) { int err; #define VISIT(SLOT) \ if (SLOT) { \ err = visit((PyObject *)(SLOT), arg); \ if (err) \ return err; \ } VISIT(self->dialect); VISIT(self->writeline); return 0; }
static int bomb_traverse(PyBombObject *bomb, visitproc visit, void *arg) { int err; #define VISIT(o) if (o) {if ((err = visit((PyObject *)(o), arg))) return err;} VISIT(bomb->curexc_type); VISIT(bomb->curexc_value); VISIT(bomb->curexc_traceback); #undef VISIT return 0; }
static int cframe_traverse(PyCFrameObject *cf, visitproc visit, void *arg) { int err; #define VISIT(o) if (o) {if ((err = visit((PyObject *)(o), arg))) return err;} VISIT(cf->f_back); VISIT(cf->ob1); VISIT(cf->ob2); VISIT(cf->ob3); #undef VISIT return 0; }
static int Reader_traverse(ReaderObj *self, visitproc visit, void *arg) { int err; #define VISIT(SLOT) \ if (SLOT) { \ err = visit((PyObject *)(SLOT), arg); \ if (err) \ return err; \ } VISIT(self->dialect); VISIT(self->input_iter); VISIT(self->fields); return 0; }
void BytecodeTranslatorVisitor::visitUnaryOpNode(UnaryOpNode* node) { onVisitNode(node); VISIT(node->operand()); switch (node->kind()) { case tNOT: { ensureTopType(VT_INT); /* if (!3.14) should fail */ Label L_True(bytecode()); Label L_End(bytecode()); EMIT(BC_ILOAD0); EMIT_BRANCH(BC_IFICMPE, L_True); EMIT(BC_ILOAD0); EMIT_BRANCH(BC_JA, L_End); EMIT_BIND(L_True); EMIT(BC_ILOAD1); EMIT_BIND(L_End); break; } case tSUB: ensureTopIsNumeric(); EMIT(TYPED(NEG)); break; default: ERROR("Unknown unary op"); } }
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); }
void BytecodeTranslatorVisitor::visitIfNode(IfNode* node) { onVisitNode(node); Label L_End(bytecode()); if (!node->elseBlock()) { falseJump(node->ifExpr(), L_End); VISIT(node->thenBlock()); EMIT_BIND(L_End); } else { Label L_Else(bytecode()); falseJump(node->ifExpr(), L_Else); visitTyped(node->thenBlock(), VT_VOID); EMIT_BRANCH(BC_JA, L_End); EMIT_BIND(L_Else); VISIT(node->elseBlock()); EMIT_BIND(L_End); } }
static int Per_traverse(cPersistentObject *self, visitproc visit, void *arg) { int err; #define VISIT(SLOT) \ if (SLOT) { \ err = visit((PyObject *)(SLOT), arg); \ if (err) \ return err; \ } VISIT(self->jar); VISIT(self->oid); VISIT(self->cache); #undef VISIT return 0; }
void BytecodeTranslatorVisitor::processLazyLogic(BinaryOpNode* node) { Label L_Lazy(bytecode()); Label L_End(bytecode()); bool isOr = node->kind() == tOR; VISIT(node->left()); popType(VT_INT); EMIT(BC_ILOAD0); EMIT_BRANCH(isOr ? BC_IFICMPNE : BC_IFICMPE, L_Lazy); VISIT(node->right()); ensureTopType(VT_INT); EMIT_BRANCH(BC_JA, L_End); EMIT_BIND(L_Lazy); EMIT(isOr ? BC_ILOAD1 : BC_ILOAD0); EMIT_BIND(L_End); }
PYCURL_INTERNAL int do_share_traverse(CurlShareObject *self, visitproc visit, void *arg) { int err; #undef VISIT #define VISIT(v) if ((v) != NULL && ((err = visit(v, arg)) != 0)) return err VISIT(self->dict); return 0; #undef VISIT }
void BytecodeTranslatorVisitor::visitWhileNode(WhileNode* node) { onVisitNode(node); Label L_Begin(bytecode()); Label L_End(bytecode()); EMIT_BIND(L_Begin); falseJump(node->whileExpr(), L_End); VISIT(node->loopBlock()); EMIT_BRANCH(BC_JA, L_Begin); EMIT_BIND(L_End); }
void BytecodeTranslatorVisitor::falseJump(AstNode* node, Label& label) { bool isComparison = false; if (node->isBinaryOpNode()) { TokenKind kind = node->asBinaryOpNode()->kind(); if (tEQ <= kind && kind <= tLE) isComparison = true; } if (!isComparison) { visitTyped(node, VT_INT); EMIT(BC_ILOAD0); EMIT_BRANCH(BC_IFICMPE, label); } else { /* Premature optimization is the root of all evil */ VISIT(node->asBinaryOpNode()->right()); ensureTopIsNumeric(); VISIT(node->asBinaryOpNode()->left()); ensureTopIsNumeric(); TokenKind kind = node->asBinaryOpNode()->kind(); castTopsToCommonType(); Instruction cmp = TYPED(CMP); bool hack = topType() == VT_INT; popType(); popType(); if (!hack) { EMIT(cmp); EMIT(BC_ILOAD0); } switch (kind) { case tEQ: EMIT_BRANCH(BC_IFICMPNE, label); break; case tNEQ: EMIT_BRANCH(BC_IFICMPE, label); break; case tGT: EMIT_BRANCH(hack ? BC_IFICMPLE : BC_IFICMPGE, label); break; case tGE: EMIT_BRANCH(hack ? BC_IFICMPL : BC_IFICMPG, label); break; case tLT: EMIT_BRANCH(hack ? BC_IFICMPGE : BC_IFICMPLE, label); break; default: EMIT_BRANCH(hack ? BC_IFICMPG : BC_IFICMPL, label); break; } } }
void BytecodeTranslatorVisitor::processBlockNode(BlockNode* node) { for (uint32_t i = 0; i < node->nodes(); i++) { AstNode* ith = node->nodeAt(i); warningIf(isUnused(ith), "unused result of statement"); VISIT(ith); VarType result = popType(); if (result != VT_VOID && !ith->isReturnNode()) EMIT(BC_POP); } }
static PyObject *m_deepin_lunar_traverse(DeepinLunarObject *self, visitproc visit, void *args) { int err; #undef VISIT #define VISIT(v) if ((v) != NULL && ((err = visit(v, args)) != 0)) return err VISIT(self->dict); return 0; #undef VISIT }
static int channel_traverse(PyChannelObject *ch, visitproc visit, void *arg) { int err; PyTaskletObject *p; #define VISIT(o) if (o) {if ((err = visit((PyObject *)(o), arg))) return err;} for (p = ch->head; p != (PyTaskletObject *) ch; p = p->next) { VISIT(p); } #undef VISIT return 0; }
void luna_visit(luna_visitor_t *self, luna_node_t *node) { switch (node->type) { case LUNA_NODE_BLOCK: VISIT(block); case LUNA_NODE_ID: VISIT(id); case LUNA_NODE_INT: VISIT(int); case LUNA_NODE_FLOAT: VISIT(float); case LUNA_NODE_STRING: VISIT(string); case LUNA_NODE_SLOT: VISIT(slot); case LUNA_NODE_CALL: VISIT(call); case LUNA_NODE_IF: VISIT(if); case LUNA_NODE_WHILE: VISIT(while); case LUNA_NODE_UNARY_OP: VISIT(unary_op); case LUNA_NODE_BINARY_OP: VISIT(binary_op); case LUNA_NODE_FUNCTION: VISIT(function); case LUNA_NODE_ARRAY: VISIT(array); case LUNA_NODE_RETURN: VISIT(return); } }
static int symtable_visit_slice(struct symtable *st, slice_ty s) { switch (s->kind) { case Slice_kind: if (s->v.Slice.lower) VISIT(st, expr, s->v.Slice.lower) if (s->v.Slice.upper) VISIT(st, expr, s->v.Slice.upper) if (s->v.Slice.step) VISIT(st, expr, s->v.Slice.step) break; case ExtSlice_kind: VISIT_SEQ(st, slice, s->v.ExtSlice.dims) break; case Index_kind: VISIT(st, expr, s->v.Index.value) break; case Ellipsis_kind: break; } return 1; }
void BytecodeTranslatorVisitor::visitPrintNode(PrintNode * node) { onVisitNode(node); for (uint32_t i = 0; i < node->operands(); ++i) { VISIT(node->operandAt(i)); switch (topType()) { case VT_INT: EMIT(BC_IPRINT); break; case VT_DOUBLE: EMIT(BC_DPRINT); break; case VT_STRING: EMIT(BC_SPRINT); break; default: ERROR("Unprintable parameter"); } popType(); } pushType(VT_VOID); }
static inline int VisitSegment (short nSegment, int bAutomap) { if (nSegment < 0) return 0; if (bAutomap) { if (automap.m_bDisplay) { if (!(automap.m_bFull || automap.m_visible [nSegment])) return 0; if (!gameOpts->render.automap.bSkybox && (SEGMENTS [nSegment].m_nType == SEGMENT_IS_SKYBOX)) return 0; } else automap.m_visited [0][nSegment] = gameData.render.mine.bSetAutomapVisited; } if (VISITED (nSegment)) return 0; VISIT (nSegment); 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(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); }
int rootstate_traverse(NyHeapTraverse *ta) { visitproc visit = ta->visit; NyHeapViewObject *hv = (void *)ta->hv; void *arg = ta->arg; PyThreadState *ts, *bts = PyThreadState_GET(); PyInterpreterState *is; int err; for (is = PyInterpreterState_Head(); is; is = PyInterpreterState_Next(is)) { if (hv->is_hiding_calling_interpreter && is == bts->interp) continue; VISIT(is->modules); VISIT(is->sysdict); VISIT(is->builtins); #if PY_VERSION_HEX >= 0x020303f0 VISIT(is->codec_search_path); VISIT(is->codec_search_cache); VISIT(is->codec_error_registry); #endif for (ts = is->tstate_head; ts; ts = ts->next) { if (ts == bts && hv->limitframe) { VISIT(hv->limitframe); } else if (!hv->limitframe) { VISIT(ts->frame); } VISIT(ts->c_profileobj); VISIT(ts->c_traceobj); VISIT(ts->curexc_type); VISIT(ts->curexc_value); VISIT(ts->curexc_traceback); VISIT(ts->exc_type); VISIT(ts->exc_value); VISIT(ts->exc_traceback); VISIT(ts->dict); #if PY_VERSION_HEX >= 0x020303f0 VISIT(ts->async_exc); #endif } } return 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; }
static int symtable_visit_keyword(struct symtable *st, keyword_ty k) { VISIT(st, expr, k->value); return 1; }
void BytecodeTranslatorVisitor::visitTyped(AstNode* node, VarType type) { VISIT(node); tryCast(type); popType(type); }
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; }