blueloveTH преди 3 години
родител
ревизия
c4321b8f4b
променени са 4 файла, в които са добавени 199 реда и са изтрити 250 реда
  1. 181 221
      src/ceval.h
  2. 16 27
      src/compiler.h
  3. 1 1
      src/frame.h
  4. 1 1
      src/opcodes.h

+ 181 - 221
src/ceval.h

@@ -12,7 +12,7 @@ PyVar VM::run_frame(Frame* frame){
         {
         case OP_NO_OP: continue;
         case OP_LOAD_CONST: frame->push(frame->co->consts[byte.arg]); continue;
-        case OP_LOAD_LAMBDA: {
+        case OP_LOAD_FUNCTION: {
             PyVar obj = frame->co->consts[byte.arg];
             setattr(obj, __module__, frame->_module);
             frame->push(obj);
@@ -54,12 +54,11 @@ PyVar VM::run_frame(Frame* frame){
             PyVarRef r = frame->pop();
             PyRef_AS_C(r)->set(this, frame, std::move(obj));
         } continue;
-        case OP_DELETE_REF: {
-            PyVarRef r = frame->pop();
-            PyRef_AS_C(r)->del(this, frame);
-        } continue;
-        case OP_BUILD_SMART_TUPLE:
-        {
+        case OP_DELETE_REF: 
+            PyRef_AS_C(frame->top())->del(this, frame);
+            frame->_pop();
+            continue;
+        case OP_BUILD_SMART_TUPLE: {
             pkpy::Args items = frame->pop_n_reversed(byte.arg);
             bool done = false;
             for(int i=0; i<items.size(); i++){
@@ -72,114 +71,93 @@ PyVar VM::run_frame(Frame* frame){
             }
             if(!done) frame->push(PyRef(TupleRef(std::move(items))));
         } continue;
-        case OP_BUILD_STRING:
-        {
+        case OP_BUILD_STRING: {
             pkpy::Args items = frame->pop_n_values_reversed(this, byte.arg);
             StrStream ss;
             for(int i=0; i<items.size(); i++) ss << PyStr_AS_C(asStr(items[i]));
             frame->push(PyStr(ss.str()));
         } continue;
-        case OP_LOAD_EVAL_FN: {
-            frame->push(builtins->attr(m_eval));
-        } continue;
+        case OP_LOAD_EVAL_FN: frame->push(builtins->attr(m_eval)); continue;
         case OP_LIST_APPEND: {
             pkpy::Args args(2);
             args[1] = frame->pop_value(this);            // obj
             args[0] = frame->top_value_offset(this, -2);     // list
             fast_call(m_append, std::move(args));
         } continue;
-        case OP_STORE_FUNCTION:
-            {
-                PyVar obj = frame->pop_value(this);
-                const pkpy::Function_& fn = PyFunction_AS_C(obj);
-                setattr(obj, __module__, frame->_module);
-                frame->f_globals()[fn->name] = obj;
-            } continue;
-        case OP_BUILD_CLASS:
-            {
-                const Str& clsName = frame->co->names[byte.arg].first;
-                PyVar clsBase = frame->pop_value(this);
-                if(clsBase == None) clsBase = _t(tp_object);
-                check_type(clsBase, tp_type);
-                PyVar cls = new_type_object(frame->_module, clsName, clsBase);
-                while(true){
-                    PyVar fn = frame->pop_value(this);
-                    if(fn == None) break;
-                    const pkpy::Function_& f = PyFunction_AS_C(fn);
-                    setattr(fn, __module__, frame->_module);
-                    setattr(cls, f->name, fn);
-                }
-            } continue;
+        case OP_BUILD_CLASS: {
+            const Str& clsName = frame->co->names[byte.arg].first;
+            PyVar clsBase = frame->pop_value(this);
+            if(clsBase == None) clsBase = _t(tp_object);
+            check_type(clsBase, tp_type);
+            PyVar cls = new_type_object(frame->_module, clsName, clsBase);
+            while(true){
+                PyVar fn = frame->pop_value(this);
+                if(fn == None) break;
+                const pkpy::Function_& f = PyFunction_AS_C(fn);
+                setattr(cls, f->name, fn);
+            }
+        } continue;
         case OP_RETURN_VALUE: return frame->pop_value(this);
-        case OP_PRINT_EXPR:
-            {
-                const PyVar expr = frame->top_value(this);
-                if(expr == None) continue;
-                *_stdout << PyStr_AS_C(asRepr(expr)) << '\n';
-            } continue;
+        case OP_PRINT_EXPR: {
+            const PyVar expr = frame->top_value(this);
+            if(expr == None) continue;
+            *_stdout << PyStr_AS_C(asRepr(expr)) << '\n';
+        } continue;
         case OP_POP_TOP: frame->_pop(); continue;
-        case OP_BINARY_OP:
-            {
-                pkpy::Args args(2);
-                args[1] = frame->pop_value(this);
-                args[0] = frame->top_value(this);
-                frame->top() = fast_call(BINARY_SPECIAL_METHODS[byte.arg], std::move(args));
-            } continue;
-        case OP_BITWISE_OP:
-            {
-                pkpy::Args args(2);
-                args[1] = frame->pop_value(this);
-                args[0] = frame->top_value(this);
-                frame->top() = fast_call(BITWISE_SPECIAL_METHODS[byte.arg], std::move(args));
-            } continue;
-        case OP_INPLACE_BINARY_OP:
-            {
-                pkpy::Args args(2);
-                args[1] = frame->pop_value(this);
-                args[0] = frame->top_value(this);
-                PyVar ret = fast_call(BINARY_SPECIAL_METHODS[byte.arg], std::move(args));
-                PyRef_AS_C(frame->top())->set(this, frame, std::move(ret));
-                frame->_pop();
-            } continue;
-        case OP_INPLACE_BITWISE_OP:
-            {
-                pkpy::Args args(2);
-                args[1] = frame->pop_value(this);
-                args[0] = frame->top_value(this);
-                PyVar ret = fast_call(BITWISE_SPECIAL_METHODS[byte.arg], std::move(args));
-                PyRef_AS_C(frame->top())->set(this, frame, std::move(ret));
-                frame->_pop();
-            } continue;
-        case OP_COMPARE_OP:
-            {
-                pkpy::Args args(2);
-                args[1] = frame->pop_value(this);
-                args[0] = frame->top_value(this);
-                frame->top() = fast_call(CMP_SPECIAL_METHODS[byte.arg], std::move(args));
-            } continue;
-        case OP_IS_OP:
-            {
-                PyVar rhs = frame->pop_value(this);
-                bool ret_c = rhs == frame->top_value(this);
-                if(byte.arg == 1) ret_c = !ret_c;
-                frame->top() = PyBool(ret_c);
-            } continue;
-        case OP_CONTAINS_OP:
-            {
-                PyVar rhs = frame->pop_value(this);
-                bool ret_c = PyBool_AS_C(call(rhs, __contains__, pkpy::one_arg(frame->pop_value(this))));
-                if(byte.arg == 1) ret_c = !ret_c;
-                frame->push(PyBool(ret_c));
-            } continue;
+        case OP_BINARY_OP: {
+            pkpy::Args args(2);
+            args[1] = frame->pop_value(this);
+            args[0] = frame->top_value(this);
+            frame->top() = fast_call(BINARY_SPECIAL_METHODS[byte.arg], std::move(args));
+        } continue;
+        case OP_BITWISE_OP: {
+            pkpy::Args args(2);
+            args[1] = frame->pop_value(this);
+            args[0] = frame->top_value(this);
+            frame->top() = fast_call(BITWISE_SPECIAL_METHODS[byte.arg], std::move(args));
+        } continue;
+        case OP_INPLACE_BINARY_OP: {
+            pkpy::Args args(2);
+            args[1] = frame->pop_value(this);
+            args[0] = frame->top_value(this);
+            PyVar ret = fast_call(BINARY_SPECIAL_METHODS[byte.arg], std::move(args));
+            PyRef_AS_C(frame->top())->set(this, frame, std::move(ret));
+            frame->_pop();
+        } continue;
+        case OP_INPLACE_BITWISE_OP: {
+            pkpy::Args args(2);
+            args[1] = frame->pop_value(this);
+            args[0] = frame->top_value(this);
+            PyVar ret = fast_call(BITWISE_SPECIAL_METHODS[byte.arg], std::move(args));
+            PyRef_AS_C(frame->top())->set(this, frame, std::move(ret));
+            frame->_pop();
+        } continue;
+        case OP_COMPARE_OP: {
+            pkpy::Args args(2);
+            args[1] = frame->pop_value(this);
+            args[0] = frame->top_value(this);
+            frame->top() = fast_call(CMP_SPECIAL_METHODS[byte.arg], std::move(args));
+        } continue;
+        case OP_IS_OP: {
+            PyVar rhs = frame->pop_value(this);
+            bool ret_c = rhs == frame->top_value(this);
+            if(byte.arg == 1) ret_c = !ret_c;
+            frame->top() = PyBool(ret_c);
+        } continue;
+        case OP_CONTAINS_OP: {
+            PyVar rhs = frame->pop_value(this);
+            bool ret_c = PyBool_AS_C(call(rhs, __contains__, pkpy::one_arg(frame->pop_value(this))));
+            if(byte.arg == 1) ret_c = !ret_c;
+            frame->push(PyBool(ret_c));
+        } continue;
         case OP_UNARY_NEGATIVE:
             frame->top() = num_negated(frame->top_value(this));
             continue;
-        case OP_UNARY_NOT:
-            {
-                PyVar obj = frame->pop_value(this);
-                const PyVar& obj_bool = asBool(obj);
-                frame->push(PyBool(!PyBool_AS_C(obj_bool)));
-            } continue;
+        case OP_UNARY_NOT: {
+            PyVar obj = frame->pop_value(this);
+            const PyVar& obj_bool = asBool(obj);
+            frame->push(PyBool(!PyBool_AS_C(obj_bool)));
+        } continue;
         case OP_POP_JUMP_IF_FALSE:
             if(!PyBool_AS_C(asBool(frame->pop_value(this)))) frame->jump_abs(byte.arg);
             continue;
@@ -187,61 +165,54 @@ PyVar VM::run_frame(Frame* frame){
         case OP_LOAD_TRUE: frame->push(True); continue;
         case OP_LOAD_FALSE: frame->push(False); continue;
         case OP_LOAD_ELLIPSIS: frame->push(Ellipsis); continue;
-        case OP_ASSERT:
-            {
-                PyVar _msg = frame->pop_value(this);
-                Str msg = PyStr_AS_C(asStr(_msg));
-                PyVar expr = frame->pop_value(this);
-                if(asBool(expr) != True) _error("AssertionError", msg);
-            } continue;
-        case OP_EXCEPTION_MATCH:
-            {
-                const auto& _e = PyException_AS_C(frame->top());
-                Str name = frame->co->names[byte.arg].first;
-                frame->push(PyBool(_e.match_type(name)));
-            } continue;
-        case OP_RAISE:
-            {
-                PyVar obj = frame->pop_value(this);
-                Str msg = obj == None ? "" : PyStr_AS_C(asStr(obj));
-                Str type = frame->co->names[byte.arg].first;
-                _error(type, msg);
-            } continue;
+        case OP_ASSERT: {
+            PyVar _msg = frame->pop_value(this);
+            Str msg = PyStr_AS_C(asStr(_msg));
+            PyVar expr = frame->pop_value(this);
+            if(asBool(expr) != True) _error("AssertionError", msg);
+        } continue;
+        case OP_EXCEPTION_MATCH: {
+            const auto& e = PyException_AS_C(frame->top());
+            Str name = frame->co->names[byte.arg].first;
+            frame->push(PyBool(e.match_type(name)));
+        } continue;
+        case OP_RAISE: {
+            PyVar obj = frame->pop_value(this);
+            Str msg = obj == None ? "" : PyStr_AS_C(asStr(obj));
+            Str type = frame->co->names[byte.arg].first;
+            _error(type, msg);
+        } continue;
         case OP_RE_RAISE: _raise(); continue;
         case OP_BUILD_LIST:
-            frame->push(PyList(
-                frame->pop_n_values_reversed(this, byte.arg).move_to_list()));
+            frame->push(PyList(frame->pop_n_values_reversed(this, byte.arg).move_to_list()));
             continue;
-        case OP_BUILD_MAP:
-            {
-                pkpy::Args items = frame->pop_n_values_reversed(this, byte.arg*2);
-                PyVar obj = call(builtins->attr("dict"));
-                for(int i=0; i<items.size(); i+=2){
-                    call(obj, __setitem__, pkpy::two_args(items[i], items[i+1]));
-                }
-                frame->push(obj);
-            } continue;
-        case OP_BUILD_SET:
-            {
-                PyVar list = PyList(
-                    frame->pop_n_values_reversed(this, byte.arg).move_to_list()
-                );
-                PyVar obj = call(builtins->attr("set"), pkpy::one_arg(list));
-                frame->push(obj);
-            } continue;
+        case OP_BUILD_MAP: {
+            pkpy::Args items = frame->pop_n_values_reversed(this, byte.arg*2);
+            PyVar obj = call(builtins->attr("dict"));
+            for(int i=0; i<items.size(); i+=2){
+                call(obj, __setitem__, pkpy::two_args(items[i], items[i+1]));
+            }
+            frame->push(obj);
+        } continue;
+        case OP_BUILD_SET: {
+            PyVar list = PyList(
+                frame->pop_n_values_reversed(this, byte.arg).move_to_list()
+            );
+            PyVar obj = call(builtins->attr("set"), pkpy::one_arg(list));
+            frame->push(obj);
+        } continue;
         case OP_DUP_TOP_VALUE: frame->push(frame->top_value(this)); continue;
-        case OP_CALL:
-            {
-                int ARGC = byte.arg & 0xFFFF;
-                int KWARGC = (byte.arg >> 16) & 0xFFFF;
-                pkpy::Args kwargs(0);
-                if(KWARGC > 0) kwargs = frame->pop_n_values_reversed(this, KWARGC*2);
-                pkpy::Args args = frame->pop_n_values_reversed(this, ARGC);
-                PyVar callable = frame->pop_value(this);
-                PyVar ret = call(callable, std::move(args), kwargs, true);
-                if(ret == _py_op_call) return ret;
-                frame->push(std::move(ret));
-            } continue;
+        case OP_CALL: {
+            int ARGC = byte.arg & 0xFFFF;
+            int KWARGC = (byte.arg >> 16) & 0xFFFF;
+            pkpy::Args kwargs(0);
+            if(KWARGC > 0) kwargs = frame->pop_n_values_reversed(this, KWARGC*2);
+            pkpy::Args args = frame->pop_n_values_reversed(this, ARGC);
+            PyVar callable = frame->pop_value(this);
+            PyVar ret = call(callable, std::move(args), kwargs, true);
+            if(ret == _py_op_call) return ret;
+            frame->push(std::move(ret));
+        } continue;
         case OP_JUMP_ABSOLUTE: frame->jump_abs(byte.arg); continue;
         case OP_SAFE_JUMP_ABSOLUTE: frame->jump_abs_safe(byte.arg); continue;
         case OP_GOTO: {
@@ -250,87 +221,76 @@ PyVar VM::run_frame(Frame* frame){
             if(target == nullptr) _error("KeyError", "label '" + label + "' not found");
             frame->jump_abs_safe(*target);
         } continue;
-        case OP_GET_ITER:
-            {
-                PyVar obj = frame->pop_value(this);
-                PyVar iter_obj = asIter(obj);
-                PyVarRef var = frame->pop();
-                check_type(var, tp_ref);
-                PyIter_AS_C(iter_obj)->var = var;
-                frame->push(std::move(iter_obj));
-            } continue;
-        case OP_FOR_ITER:
-            {
-                // top() must be PyIter, so no need to try_deref()
-                auto& it = PyIter_AS_C(frame->top());
-                PyVar obj = it->next();
-                if(obj != nullptr){
-                    PyRef_AS_C(it->var)->set(this, frame, std::move(obj));
-                }else{
-                    int blockEnd = frame->co->blocks[byte.block].end;
-                    frame->jump_abs_safe(blockEnd);
-                }
-            } continue;
-        case OP_LOOP_CONTINUE:
-            {
-                int blockStart = frame->co->blocks[byte.block].start;
-                frame->jump_abs(blockStart);
-            } continue;
-        case OP_LOOP_BREAK:
-            {
+        case OP_GET_ITER: {
+            PyVar obj = frame->pop_value(this);
+            PyVar iter_obj = asIter(obj);
+            PyVarRef var = frame->pop();
+            check_type(var, tp_ref);
+            PyIter_AS_C(iter_obj)->var = var;
+            frame->push(std::move(iter_obj));
+        } continue;
+        case OP_FOR_ITER: {
+            auto& it = PyIter_AS_C(frame->top());
+            PyVar obj = it->next();
+            if(obj != nullptr){
+                PyRef_AS_C(it->var)->set(this, frame, std::move(obj));
+            }else{
                 int blockEnd = frame->co->blocks[byte.block].end;
                 frame->jump_abs_safe(blockEnd);
-            } continue;
-        case OP_JUMP_IF_FALSE_OR_POP:
-            {
-                const PyVar expr = frame->top_value(this);
-                if(asBool(expr)==False) frame->jump_abs(byte.arg);
-                else frame->pop_value(this);
-            } continue;
-        case OP_JUMP_IF_TRUE_OR_POP:
-            {
-                const PyVar expr = frame->top_value(this);
-                if(asBool(expr)==True) frame->jump_abs(byte.arg);
-                else frame->pop_value(this);
-            } continue;
-        case OP_BUILD_SLICE:
-            {
-                PyVar stop = frame->pop_value(this);
-                PyVar start = frame->pop_value(this);
-                pkpy::Slice s;
-                if(start != None) {check_type(start, tp_int); s.start = (int)PyInt_AS_C(start);}
-                if(stop != None) {check_type(stop, tp_int); s.stop = (int)PyInt_AS_C(stop);}
-                frame->push(PySlice(s));
-            } continue;
-        case OP_IMPORT_NAME:
-            {
-                const Str& name = frame->co->names[byte.arg].first;
-                auto it = _modules.find(name);
-                if(it == _modules.end()){
-                    auto it2 = _lazy_modules.find(name);
-                    if(it2 == _lazy_modules.end()){
-                        _error("ImportError", "module '" + name + "' not found");
-                    }else{
-                        const Str& source = it2->second;
-                        CodeObject_ code = compile(source, name, EXEC_MODE);
-                        PyVar _m = new_module(name);
-                        _exec(code, _m, pkpy::make_shared<pkpy::NameDict>());
-                        frame->push(_m);
-                        _lazy_modules.erase(it2);
-                    }
+            }
+        } continue;
+        case OP_LOOP_CONTINUE: {
+            int blockStart = frame->co->blocks[byte.block].start;
+            frame->jump_abs(blockStart);
+        } continue;
+        case OP_LOOP_BREAK: {
+            int blockEnd = frame->co->blocks[byte.block].end;
+            frame->jump_abs_safe(blockEnd);
+        } continue;
+        case OP_JUMP_IF_FALSE_OR_POP: {
+            const PyVar expr = frame->top_value(this);
+            if(asBool(expr)==False) frame->jump_abs(byte.arg);
+            else frame->pop_value(this);
+        } continue;
+        case OP_JUMP_IF_TRUE_OR_POP: {
+            const PyVar expr = frame->top_value(this);
+            if(asBool(expr)==True) frame->jump_abs(byte.arg);
+            else frame->pop_value(this);
+        } continue;
+        case OP_BUILD_SLICE: {
+            PyVar stop = frame->pop_value(this);
+            PyVar start = frame->pop_value(this);
+            pkpy::Slice s;
+            if(start != None) {check_type(start, tp_int); s.start = (int)PyInt_AS_C(start);}
+            if(stop != None) {check_type(stop, tp_int); s.stop = (int)PyInt_AS_C(stop);}
+            frame->push(PySlice(s));
+        } continue;
+        case OP_IMPORT_NAME: {
+            const Str& name = frame->co->names[byte.arg].first;
+            auto it = _modules.find(name);
+            if(it == _modules.end()){
+                auto it2 = _lazy_modules.find(name);
+                if(it2 == _lazy_modules.end()){
+                    _error("ImportError", "module " + name.escape(true) + " not found");
                 }else{
-                    frame->push(it->second);
+                    const Str& source = it2->second;
+                    CodeObject_ code = compile(source, name, EXEC_MODE);
+                    PyVar _m = new_module(name);
+                    _exec(code, _m, pkpy::make_shared<pkpy::NameDict>());
+                    frame->push(_m);
+                    _lazy_modules.erase(it2);
                 }
-            } continue;
+            }else{
+                frame->push(it->second);
+            }
+        } continue;
         case OP_YIELD_VALUE: return _py_op_yield;
         // TODO: using "goto" inside with block may cause __exit__ not called
         case OP_WITH_ENTER: call(frame->pop_value(this), __enter__); continue;
         case OP_WITH_EXIT: call(frame->pop_value(this), __exit__); continue;
         case OP_TRY_BLOCK_ENTER: frame->on_try_block_enter(); continue;
         case OP_TRY_BLOCK_EXIT: frame->on_try_block_exit(); continue;
-        default:
-            throw std::runtime_error(Str("opcode ") + OP_NAMES[byte.op] + " is not implemented");
-            continue;
+        default: throw std::runtime_error(Str("opcode ") + OP_NAMES[byte.op] + " is not implemented");
         }
     }
 

+ 16 - 27
src/compiler.h

@@ -5,7 +5,6 @@
 #include "ceval.h"
 
 class Compiler;
-
 typedef void (Compiler::*GrammarFn)();
 typedef void (Compiler::*CompilerAction)();
 
@@ -28,6 +27,7 @@ class Compiler {
 
     CodeObject_ co() const{ return codes.top(); }
     CompileMode mode() const{ return parser->src->mode; }
+    NameScope name_scope() const { return codes.size()>1 ? NAME_LOCAL : NAME_GLOBAL; }
 
 public:
     Compiler(VM* vm, const char* source, Str filename, CompileMode mode){
@@ -132,7 +132,7 @@ private:
                     case 'n':  buff.push_back('\n'); break;
                     case 'r':  buff.push_back('\r'); break;
                     case 't':  buff.push_back('\t'); break;
-                    default: SyntaxError("invalid escape character");
+                    default: SyntaxError("invalid escape char");
                 }
             } else {
                 buff.push_back(c);
@@ -396,7 +396,7 @@ private:
         emit(OP_RETURN_VALUE);
         func->code->optimize(vm);
         this->codes.pop();
-        emit(OP_LOAD_LAMBDA, co()->add_const(vm->PyFunction(func)));
+        emit(OP_LOAD_FUNCTION, co()->add_const(vm->PyFunction(func)));
     }
 
     void exprAssign() {
@@ -612,10 +612,7 @@ __LISTCOMP:
 
     void _exprName(bool force_lvalue) {
         Token tkname = parser->prev;
-        int index = co()->add_name(
-            tkname.str(),
-            codes.size()>1 ? NAME_LOCAL : NAME_GLOBAL
-        );
+        int index = co()->add_name(tkname.str(), name_scope());
         bool fast_load = !force_lvalue && co()->_rvalue;
         emit(fast_load ? OP_LOAD_NAME : OP_LOAD_NAME_REF, index);
     }
@@ -719,7 +716,7 @@ __LISTCOMP:
                 consume(TK("@id"));
                 tkmodule = parser->prev;
             }
-            int index = co()->add_name(tkmodule.str(), NAME_GLOBAL);
+            int index = co()->add_name(tkmodule.str(), name_scope());
             emit(OP_STORE_NAME, index);
         } while (match(TK(",")));
         consume_end_stmt();
@@ -739,7 +736,7 @@ __LISTCOMP:
                 consume(TK("@id"));
                 tkname = parser->prev;
             }
-            index = co()->add_name(tkname.str(), NAME_GLOBAL);
+            index = co()->add_name(tkname.str(), name_scope());
             emit(OP_STORE_NAME, index);
         } while (match(TK(",")));
         emit(OP_POP_TOP);
@@ -875,6 +872,12 @@ __LISTCOMP:
             compile_while_loop();
         } else if (match(TK("for"))) {
             compile_for_loop();
+        } else if (match(TK("import"))){
+            compile_normal_import();
+        } else if (match(TK("from"))){
+            compile_from_import();
+        } else if (match(TK("def"))){
+            compile_function();
         } else if (match(TK("try"))) {
             compile_try_except();
         }else if(match(TK("assert"))){
@@ -888,10 +891,7 @@ __LISTCOMP:
             consume(TK("as"));
             consume(TK("@id"));
             Token tkname = parser->prev;
-            int index = co()->add_name(
-                tkname.str(),
-                codes.size()>1 ? NAME_LOCAL : NAME_GLOBAL
-            );
+            int index = co()->add_name(tkname.str(), name_scope());
             emit(OP_STORE_NAME, index);
             emit(OP_LOAD_NAME_REF, index);
             emit(OP_WITH_ENTER);
@@ -1009,23 +1009,19 @@ __LISTCOMP:
         pkpy::Function_ func = pkpy::make_shared<pkpy::Function>();
         consume(TK("@id"));
         func->name = parser->prev.str();
-
         consume(TK("("));
         if (!match(TK(")"))) {
             _compile_f_args(func, true);
             consume(TK(")"));
         }
-
-        // eat type hints
-        if(match(TK("->"))) consume(TK("@id"));
-
+        if(match(TK("->"))) consume(TK("@id")); // eat type hints
         func->code = pkpy::make_shared<CodeObject>(parser->src, func->name);
         this->codes.push(func->code);
         compile_block_body();
         func->code->optimize(vm);
         this->codes.pop();
-        emit(OP_LOAD_CONST, co()->add_const(vm->PyFunction(func)));
-        if(!is_compiling_class) emit(OP_STORE_FUNCTION);
+        emit(OP_LOAD_FUNCTION, co()->add_const(vm->PyFunction(func)));
+        if(!is_compiling_class) emit(OP_STORE_NAME, co()->add_name(func->name, name_scope()));
     }
 
     PyVarOrNull read_literal(){
@@ -1088,15 +1084,8 @@ public:
         }
 
         while (!match(TK("@eof"))) {
-            // compile top-level statement
             if (match(TK("class"))) {
                 compile_class();
-            } else if (match(TK("def"))) {
-                compile_function();
-            } else if (match(TK("import"))) {
-                compile_normal_import();
-            } else if (match(TK("from"))) {
-                compile_from_import();
             } else {
                 compile_stmt();
             }

+ 1 - 1
src/frame.h

@@ -109,7 +109,7 @@ struct Frame {
     }
 
     int _exit_block(int i){
-        if(co->blocks[i].type == FOR_LOOP) pop();
+        if(co->blocks[i].type == FOR_LOOP) _pop();
         else if(co->blocks[i].type == TRY_EXCEPT) on_try_block_exit();
         return co->blocks[i].parent;
     }

+ 1 - 1
src/opcodes.h

@@ -48,7 +48,7 @@ OPCODE(LOAD_NONE)
 OPCODE(LOAD_TRUE)
 OPCODE(LOAD_FALSE)
 OPCODE(LOAD_EVAL_FN)
-OPCODE(LOAD_LAMBDA)
+OPCODE(LOAD_FUNCTION)
 OPCODE(LOAD_ELLIPSIS)
 OPCODE(LOAD_NAME)
 OPCODE(LOAD_NAME_REF)