blueloveTH hai 1 ano
pai
achega
783bbfb4ba

+ 14 - 5
include/pocketpy/objects/codeobject.h

@@ -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

+ 1 - 17
include/pocketpy/objects/codeobject.hpp

@@ -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);

+ 9 - 7
src/compiler/compiler.cpp

@@ -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);

+ 5 - 5
src/compiler/expr.cpp

@@ -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);

+ 3 - 3
src/interpreter/frame.cpp

@@ -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;