|
@@ -1132,8 +1132,12 @@ static int Ctx__prepare_loop_divert(Ctx* self, int line, bool is_break) {
|
|
|
Ctx__emit_(self, OP_POP_TOP, BC_NOARG, line);
|
|
Ctx__emit_(self, OP_POP_TOP, BC_NOARG, line);
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
+ case CodeBlockType_TRY: {
|
|
|
|
|
+ Ctx__emit_(self, OP_END_TRY, BC_NOARG, line);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
case CodeBlockType_EXCEPT: {
|
|
case CodeBlockType_EXCEPT: {
|
|
|
- Ctx__emit_(self, OP_END_EXC_HANDLING, 1, line);
|
|
|
|
|
|
|
+ Ctx__emit_(self, OP_END_TRY, BC_NOARG, line);
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
default: break;
|
|
default: break;
|
|
@@ -1915,9 +1919,11 @@ static Error* exprCompileTimeCall(Compiler* self, py_ItemRef func, int line) {
|
|
|
} while(match(TK_COMMA));
|
|
} while(match(TK_COMMA));
|
|
|
consume(TK_RPAREN);
|
|
consume(TK_RPAREN);
|
|
|
|
|
|
|
|
|
|
+ py_StackRef p0 = py_peek(0);
|
|
|
bool ok = py_vectorcall(argc, kwargc);
|
|
bool ok = py_vectorcall(argc, kwargc);
|
|
|
if(!ok) {
|
|
if(!ok) {
|
|
|
char* msg = py_formatexc();
|
|
char* msg = py_formatexc();
|
|
|
|
|
+ py_clearexc(p0);
|
|
|
err = SyntaxError(self, "compile-time call error:\n%s", msg);
|
|
err = SyntaxError(self, "compile-time call error:\n%s", msg);
|
|
|
PK_FREE(msg);
|
|
PK_FREE(msg);
|
|
|
return err;
|
|
return err;
|
|
@@ -2623,8 +2629,9 @@ static Error* compile_try_except(Compiler* self) {
|
|
|
int patches_length = 0;
|
|
int patches_length = 0;
|
|
|
|
|
|
|
|
Ctx__enter_block(ctx(), CodeBlockType_TRY);
|
|
Ctx__enter_block(ctx(), CodeBlockType_TRY);
|
|
|
- Ctx__emit_(ctx(), OP_TRY_ENTER, BC_NOARG, prev()->line);
|
|
|
|
|
|
|
+ Ctx__emit_(ctx(), OP_BEGIN_TRY, BC_NOARG, prev()->line);
|
|
|
check(compile_block_body(self));
|
|
check(compile_block_body(self));
|
|
|
|
|
+ Ctx__emit_(ctx(), OP_END_TRY, BC_NOARG, BC_KEEPLINE);
|
|
|
|
|
|
|
|
// https://docs.python.org/3/reference/compound_stmts.html#finally-clause
|
|
// https://docs.python.org/3/reference/compound_stmts.html#finally-clause
|
|
|
/* If finally is present, it specifies a ‘cleanup’ handler. The try clause is executed,
|
|
/* If finally is present, it specifies a ‘cleanup’ handler. The try clause is executed,
|
|
@@ -2640,12 +2647,9 @@ static Error* compile_try_except(Compiler* self) {
|
|
|
// A return, break, continue in try/except block will make the finally block not executed
|
|
// A return, break, continue in try/except block will make the finally block not executed
|
|
|
|
|
|
|
|
bool has_finally = curr()->type == TK_FINALLY;
|
|
bool has_finally = curr()->type == TK_FINALLY;
|
|
|
- if(!has_finally) {
|
|
|
|
|
- patches[patches_length++] = Ctx__emit_(ctx(), OP_JUMP_FORWARD, BC_NOARG, BC_KEEPLINE);
|
|
|
|
|
- } else {
|
|
|
|
|
- return SyntaxError(self, "finally clause is not supported yet");
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if(has_finally) return SyntaxError(self, "finally clause is not supported yet");
|
|
|
|
|
|
|
|
|
|
+ patches[patches_length++] = Ctx__emit_(ctx(), OP_JUMP_FORWARD, BC_NOARG, BC_KEEPLINE);
|
|
|
Ctx__exit_block(ctx());
|
|
Ctx__exit_block(ctx());
|
|
|
|
|
|
|
|
do {
|
|
do {
|
|
@@ -2670,7 +2674,7 @@ static Error* compile_try_except(Compiler* self) {
|
|
|
}
|
|
}
|
|
|
int patch = Ctx__emit_(ctx(), OP_POP_JUMP_IF_FALSE, BC_NOARG, BC_KEEPLINE);
|
|
int patch = Ctx__emit_(ctx(), OP_POP_JUMP_IF_FALSE, BC_NOARG, BC_KEEPLINE);
|
|
|
// on match
|
|
// on match
|
|
|
- Ctx__emit_(ctx(), OP_BEGIN_EXC_HANDLING, BC_NOARG, BC_KEEPLINE);
|
|
|
|
|
|
|
+ Ctx__emit_(ctx(), OP_HANDLE_EXCEPTION, BC_NOARG, BC_KEEPLINE);
|
|
|
if(as_name) {
|
|
if(as_name) {
|
|
|
Ctx__emit_(ctx(), OP_PUSH_EXCEPTION, BC_NOARG, BC_KEEPLINE);
|
|
Ctx__emit_(ctx(), OP_PUSH_EXCEPTION, BC_NOARG, BC_KEEPLINE);
|
|
|
Ctx__emit_store_name(ctx(), name_scope(self), as_name, BC_KEEPLINE);
|
|
Ctx__emit_store_name(ctx(), name_scope(self), as_name, BC_KEEPLINE);
|
|
@@ -2678,23 +2682,20 @@ static Error* compile_try_except(Compiler* self) {
|
|
|
Ctx__enter_block(ctx(), CodeBlockType_EXCEPT);
|
|
Ctx__enter_block(ctx(), CodeBlockType_EXCEPT);
|
|
|
check(compile_block_body(self));
|
|
check(compile_block_body(self));
|
|
|
Ctx__exit_block(ctx());
|
|
Ctx__exit_block(ctx());
|
|
|
- Ctx__emit_(ctx(), OP_END_EXC_HANDLING, BC_NOARG, BC_KEEPLINE);
|
|
|
|
|
|
|
+ Ctx__emit_(ctx(), OP_END_TRY, BC_NOARG, BC_KEEPLINE);
|
|
|
patches[patches_length++] = Ctx__emit_(ctx(), OP_JUMP_FORWARD, BC_NOARG, BC_KEEPLINE);
|
|
patches[patches_length++] = Ctx__emit_(ctx(), OP_JUMP_FORWARD, BC_NOARG, BC_KEEPLINE);
|
|
|
Ctx__patch_jump(ctx(), patch);
|
|
Ctx__patch_jump(ctx(), patch);
|
|
|
} while(curr()->type == TK_EXCEPT);
|
|
} while(curr()->type == TK_EXCEPT);
|
|
|
|
|
|
|
|
// no match, re-raise
|
|
// no match, re-raise
|
|
|
- // ...
|
|
|
|
|
|
|
+ Ctx__emit_(ctx(), OP_RE_RAISE, BC_NOARG, BC_KEEPLINE);
|
|
|
|
|
|
|
|
// match one & handled, jump to the end
|
|
// match one & handled, jump to the end
|
|
|
for(int i = 0; i < patches_length; i++) {
|
|
for(int i = 0; i < patches_length; i++) {
|
|
|
Ctx__patch_jump(ctx(), patches[i]);
|
|
Ctx__patch_jump(ctx(), patches[i]);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if(match(TK_FINALLY)) { return SyntaxError(self, "finally clause is not supported yet"); }
|
|
|
|
|
-
|
|
|
|
|
- // re-raise if needed
|
|
|
|
|
- Ctx__emit_(ctx(), OP_RE_RAISE, BC_NOARG, BC_KEEPLINE);
|
|
|
|
|
|
|
+ if(match(TK_FINALLY)) return SyntaxError(self, "finally clause is not supported yet");
|
|
|
return NULL;
|
|
return NULL;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -2797,9 +2798,19 @@ static Error* compile_stmt(Compiler* self) {
|
|
|
consume_end_stmt();
|
|
consume_end_stmt();
|
|
|
break;
|
|
break;
|
|
|
case TK_RAISE: {
|
|
case TK_RAISE: {
|
|
|
- check(EXPR(self));
|
|
|
|
|
- Ctx__s_emit_top(ctx());
|
|
|
|
|
- Ctx__emit_(ctx(), OP_RAISE, BC_NOARG, kw_line);
|
|
|
|
|
|
|
+ if(is_expression(self, false)) {
|
|
|
|
|
+ check(EXPR(self));
|
|
|
|
|
+ Ctx__s_emit_top(ctx());
|
|
|
|
|
+ Ctx__emit_(ctx(), OP_RAISE, BC_NOARG, kw_line);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ int iblock = ctx()->curr_iblock;
|
|
|
|
|
+ CodeBlock* blocks = (CodeBlock*)ctx()->co->blocks.data;
|
|
|
|
|
+ if(blocks[iblock].type != CodeBlockType_EXCEPT) {
|
|
|
|
|
+ return SyntaxError(self,
|
|
|
|
|
+ "raise without exception is only allowed in except block");
|
|
|
|
|
+ }
|
|
|
|
|
+ Ctx__emit_(ctx(), OP_RE_RAISE, BC_NOARG, kw_line);
|
|
|
|
|
+ }
|
|
|
consume_end_stmt();
|
|
consume_end_stmt();
|
|
|
} break;
|
|
} break;
|
|
|
case TK_DEL: {
|
|
case TK_DEL: {
|