This commit is contained in:
blueloveTH 2024-08-08 12:24:17 +08:00
parent 22d4c07f50
commit 471d4ae578
3 changed files with 45 additions and 22 deletions

View File

@ -2664,28 +2664,29 @@ static Error* compile_stmt(Compiler* self) {
Ctx__s_pop(ctx()); Ctx__s_pop(ctx());
consume_end_stmt(); consume_end_stmt();
} break; } break;
// case TK_WITH: { case TK_WITH: {
// check(EXPR(self)); // [ <expr> ] check(EXPR(self)); // [ <expr> ]
// Ctx__s_emit_top(ctx()); Ctx__s_emit_top(ctx());
// Ctx__enter_block(ctx(), CodeBlockType_CONTEXT_MANAGER); Ctx__enter_block(ctx(), CodeBlockType_CONTEXT_MANAGER);
// Expr* as_name = nullptr; NameExpr* as_name = NULL;
// if(match(TK_AS)) { if(match(TK_AS)) {
// consume(TK_ID); consume(TK_ID);
// as_name = make_expr<NameExpr>(prev().str(), name_scope()); py_Name name = py_namev(Token__sv(prev()));
// } as_name = NameExpr__new(prev()->line, name, name_scope(self));
// Ctx__emit_(ctx(), OP_WITH_ENTER, BC_NOARG, prev().line); }
// // [ <expr> <expr>.__enter__() ] Ctx__emit_(ctx(), OP_WITH_ENTER, BC_NOARG, prev()->line);
// if(as_name) { // [ <expr> <expr>.__enter__() ]
// bool ok = as_name->emit_store(ctx()); if(as_name) {
// delete_expr(as_name); bool ok = vtemit_store((Expr*)as_name, ctx());
// if(!ok) return SyntaxError(self, ); vtdelete((Expr*)as_name);
// } else { if(!ok) return SyntaxError(self, "invalid syntax");
// Ctx__emit_(ctx(), OP_POP_TOP, BC_NOARG, BC_KEEPLINE); } else {
// } Ctx__emit_(ctx(), OP_POP_TOP, BC_NOARG, BC_KEEPLINE);
// check(compile_block_body()); }
// Ctx__emit_(ctx(), OP_WITH_EXIT, BC_NOARG, prev().line); check(compile_block_body(self, compile_stmt));
// Ctx__exit_block(ctx()); Ctx__emit_(ctx(), OP_WITH_EXIT, BC_NOARG, prev()->line);
// } break; Ctx__exit_block(ctx());
} break;
/*************************************************/ /*************************************************/
case TK_EQ: { case TK_EQ: {
consume(TK_ID); consume(TK_ID);

View File

@ -898,6 +898,28 @@ FrameResult VM__run_top_frame(VM* self) {
DISPATCH(); DISPATCH();
} }
/////////// ///////////
case OP_WITH_ENTER: {
// [expr]
py_push(TOP());
if(!py_pushmethod(__enter__)){
TypeError("'%t' object does not support the context manager protocol", TOP()->type);
goto __ERROR;
}
if(!py_vectorcall(0, 0)) goto __ERROR;
PUSH(py_retval());
DISPATCH();
}
case OP_WITH_EXIT: {
// [expr]
py_push(TOP());
if(!py_pushmethod(__exit__)){
TypeError("'%t' object does not support the context manager protocol", TOP()->type);
goto __ERROR;
}
if(!py_vectorcall(0, 0)) goto __ERROR;
DISPATCH();
}
///////////
case OP_TRY_ENTER: { case OP_TRY_ENTER: {
Frame__set_unwind_target(frame, SP()); Frame__set_unwind_target(frame, SP());
DISPATCH(); DISPATCH();