mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-19 19:10:17 +00:00
some move
This commit is contained in:
parent
aea3b4758f
commit
783bbfb4ba
@ -31,11 +31,11 @@ typedef enum NameScope {
|
||||
} NameScope;
|
||||
|
||||
typedef enum CodeBlockType {
|
||||
NO_BLOCK,
|
||||
FOR_LOOP,
|
||||
WHILE_LOOP,
|
||||
CONTEXT_MANAGER,
|
||||
TRY_EXCEPT,
|
||||
CodeBlockType_NO_BLOCK,
|
||||
CodeBlockType_FOR_LOOP,
|
||||
CodeBlockType_WHILE_LOOP,
|
||||
CodeBlockType_CONTEXT_MANAGER,
|
||||
CodeBlockType_TRY_EXCEPT,
|
||||
} CodeBlockType;
|
||||
|
||||
typedef enum Opcode {
|
||||
@ -52,6 +52,15 @@ typedef struct Bytecode {
|
||||
void Bytecode__set_signed_arg(Bytecode* self, int arg);
|
||||
bool Bytecode__is_forward_jump(const Bytecode* self);
|
||||
|
||||
|
||||
typedef struct CodeBlock {
|
||||
CodeBlockType type;
|
||||
int parent; // parent index in blocks
|
||||
int start; // start index of this block in codes, inclusive
|
||||
int end; // end index of this block in codes, exclusive
|
||||
int end2; // ...
|
||||
} CodeBlock;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -12,22 +12,6 @@ namespace pkpy {
|
||||
|
||||
typedef PyVar (*NativeFuncC)(VM*, ArgsView);
|
||||
|
||||
struct CodeBlock {
|
||||
CodeBlockType type;
|
||||
int parent; // parent index in blocks
|
||||
int start; // start index of this block in codes, inclusive
|
||||
int end; // end index of this block in codes, exclusive
|
||||
int end2; // ...
|
||||
|
||||
CodeBlock(CodeBlockType type, int parent, int start) :
|
||||
type(type), parent(parent), start(start), end(-1), end2(-1) {}
|
||||
|
||||
int get_break_end() const {
|
||||
if(end2 != -1) return end2;
|
||||
return end;
|
||||
}
|
||||
};
|
||||
|
||||
struct CodeObject;
|
||||
struct FuncDecl;
|
||||
using CodeObject_ = std::shared_ptr<CodeObject>;
|
||||
@ -66,7 +50,7 @@ struct CodeObject {
|
||||
|
||||
CodeObject(pkpy_SourceData_ src, const Str& name) :
|
||||
src(src), name(name), nlocals(0), start_line(-1), end_line(-1) {
|
||||
blocks.push_back(CodeBlock(CodeBlockType::NO_BLOCK, -1, 0));
|
||||
blocks.push_back(CodeBlock{CodeBlockType_NO_BLOCK, -1, 0, -1, -1});
|
||||
c11_smallmap_n2i__ctor(&varnames_inv);
|
||||
c11_smallmap_n2i__ctor(&labels);
|
||||
PK_INCREF(src);
|
||||
|
@ -60,9 +60,11 @@ Error* Compiler::pop_context() noexcept{
|
||||
for(int i = 0; i < codes.size(); i++) {
|
||||
Bytecode& bc = codes[i];
|
||||
if(bc.op == OP_LOOP_CONTINUE) {
|
||||
Bytecode__set_signed_arg(&bc, ctx()->co->blocks[bc.arg].start - i);
|
||||
CodeBlock* block = &ctx()->co->blocks[bc.arg];
|
||||
Bytecode__set_signed_arg(&bc, block->start - i);
|
||||
} else if(bc.op == OP_LOOP_BREAK) {
|
||||
Bytecode__set_signed_arg(&bc, ctx()->co->blocks[bc.arg].get_break_end() - i);
|
||||
CodeBlock* block = &ctx()->co->blocks[bc.arg];
|
||||
Bytecode__set_signed_arg(&bc, (block->end2 != -1 ? block->end2 : block->end) - i);
|
||||
}
|
||||
}
|
||||
// pre-compute func->is_simple
|
||||
@ -730,7 +732,7 @@ Error* Compiler::compile_if_stmt() noexcept{
|
||||
|
||||
Error* Compiler::compile_while_loop() noexcept{
|
||||
Error* err;
|
||||
CodeBlock* block = ctx()->enter_block(CodeBlockType::WHILE_LOOP);
|
||||
CodeBlock* block = ctx()->enter_block(CodeBlockType_WHILE_LOOP);
|
||||
check(EXPR()); // condition
|
||||
ctx()->s_emit_top();
|
||||
int patch = ctx()->emit_(OP_POP_JUMP_IF_FALSE, BC_NOARG, prev().line);
|
||||
@ -753,7 +755,7 @@ Error* Compiler::compile_for_loop() noexcept{
|
||||
check(EXPR_TUPLE()); // [vars, iter]
|
||||
ctx()->s_emit_top(); // [vars]
|
||||
ctx()->emit_(OP_GET_ITER_NEW, BC_NOARG, BC_KEEPLINE);
|
||||
CodeBlock* block = ctx()->enter_block(CodeBlockType::FOR_LOOP);
|
||||
CodeBlock* block = ctx()->enter_block(CodeBlockType_FOR_LOOP);
|
||||
int for_codei = ctx()->emit_(OP_FOR_ITER, ctx()->curr_iblock, BC_KEEPLINE);
|
||||
Expr* vars = ctx()->s_popx();
|
||||
bool ok = vars->emit_store(ctx());
|
||||
@ -773,7 +775,7 @@ Error* Compiler::compile_for_loop() noexcept{
|
||||
|
||||
Error* Compiler::compile_try_except() noexcept{
|
||||
Error* err;
|
||||
ctx()->enter_block(CodeBlockType::TRY_EXCEPT);
|
||||
ctx()->enter_block(CodeBlockType_TRY_EXCEPT);
|
||||
ctx()->emit_(OP_TRY_ENTER, BC_NOARG, prev().line);
|
||||
check(compile_block_body());
|
||||
small_vector_2<int, 8> patches;
|
||||
@ -954,7 +956,7 @@ Error* Compiler::compile_stmt() noexcept{
|
||||
ctx()->s_emit_top();
|
||||
|
||||
ctx()->emit_(OP_GET_ITER_NEW, BC_NOARG, kw_line);
|
||||
ctx()->enter_block(CodeBlockType::FOR_LOOP);
|
||||
ctx()->enter_block(CodeBlockType_FOR_LOOP);
|
||||
ctx()->emit_(OP_FOR_ITER_YIELD_VALUE, BC_NOARG, kw_line);
|
||||
ctx()->emit_(OP_LOOP_CONTINUE, ctx()->get_loop(), kw_line);
|
||||
ctx()->exit_block();
|
||||
@ -1019,7 +1021,7 @@ Error* Compiler::compile_stmt() noexcept{
|
||||
case TK_WITH: {
|
||||
check(EXPR()); // [ <expr> ]
|
||||
ctx()->s_emit_top();
|
||||
ctx()->enter_block(CodeBlockType::CONTEXT_MANAGER);
|
||||
ctx()->enter_block(CodeBlockType_CONTEXT_MANAGER);
|
||||
Expr* as_name = nullptr;
|
||||
if(match(TK_AS)) {
|
||||
consume(TK_ID);
|
||||
|
@ -16,15 +16,15 @@ inline bool is_small_int(i64 value) { return value >= INT16_MIN && value <= INT1
|
||||
int CodeEmitContext::get_loop() const noexcept{
|
||||
int index = curr_iblock;
|
||||
while(index >= 0) {
|
||||
if(co->blocks[index].type == CodeBlockType::FOR_LOOP) break;
|
||||
if(co->blocks[index].type == CodeBlockType::WHILE_LOOP) break;
|
||||
if(co->blocks[index].type == CodeBlockType_FOR_LOOP) break;
|
||||
if(co->blocks[index].type == CodeBlockType_WHILE_LOOP) break;
|
||||
index = co->blocks[index].parent;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
CodeBlock* CodeEmitContext::enter_block(CodeBlockType type) noexcept{
|
||||
co->blocks.push_back(CodeBlock(type, curr_iblock, (int)co->codes.size()));
|
||||
co->blocks.push_back(CodeBlock{type, curr_iblock, (int)co->codes.size(), -1, -1});
|
||||
curr_iblock = co->blocks.size() - 1;
|
||||
return &co->blocks[curr_iblock];
|
||||
}
|
||||
@ -34,7 +34,7 @@ void CodeEmitContext::exit_block() noexcept{
|
||||
co->blocks[curr_iblock].end = co->codes.size();
|
||||
curr_iblock = co->blocks[curr_iblock].parent;
|
||||
assert(curr_iblock >= 0);
|
||||
if(curr_type == CodeBlockType::FOR_LOOP) {
|
||||
if(curr_type == CodeBlockType_FOR_LOOP) {
|
||||
// add a no op here to make block check work
|
||||
emit_(OP_NO_OP, BC_NOARG, BC_KEEPLINE, true);
|
||||
}
|
||||
@ -381,7 +381,7 @@ void CompExpr::emit_(CodeEmitContext* ctx) {
|
||||
ctx->emit_(op0, 0, line);
|
||||
iter->emit_(ctx);
|
||||
ctx->emit_(OP_GET_ITER, BC_NOARG, BC_KEEPLINE);
|
||||
ctx->enter_block(CodeBlockType::FOR_LOOP);
|
||||
ctx->enter_block(CodeBlockType_FOR_LOOP);
|
||||
int curr_iblock = ctx->curr_iblock;
|
||||
int for_codei = ctx->emit_(OP_FOR_ITER, curr_iblock, BC_KEEPLINE);
|
||||
bool ok = vars->emit_store(ctx);
|
||||
|
@ -29,7 +29,7 @@ int Frame::prepare_jump_exception_handler(ValueStack* _s) {
|
||||
// try to find a parent try block
|
||||
int i = co->lines[ip()].iblock;
|
||||
while(i >= 0) {
|
||||
if(co->blocks[i].type == CodeBlockType::TRY_EXCEPT) break;
|
||||
if(co->blocks[i].type == CodeBlockType_TRY_EXCEPT) break;
|
||||
i = co->blocks[i].parent;
|
||||
}
|
||||
if(i < 0) return -1;
|
||||
@ -42,9 +42,9 @@ int Frame::prepare_jump_exception_handler(ValueStack* _s) {
|
||||
|
||||
int Frame::_exit_block(ValueStack* _s, int i) {
|
||||
auto type = co->blocks[i].type;
|
||||
if(type == CodeBlockType::FOR_LOOP) {
|
||||
if(type == CodeBlockType_FOR_LOOP) {
|
||||
_s->pop(); // pop the iterator
|
||||
} else if(type == CodeBlockType::CONTEXT_MANAGER) {
|
||||
} else if(type == CodeBlockType_CONTEXT_MANAGER) {
|
||||
_s->pop();
|
||||
}
|
||||
return co->blocks[i].parent;
|
||||
|
Loading…
x
Reference in New Issue
Block a user