blueloveTH 3 лет назад
Родитель
Сommit
9e7ef156c5
4 измененных файлов с 26 добавлено и 23 удалено
  1. 1 1
      src/codeobject.h
  2. 13 13
      src/compiler.h
  3. 4 1
      src/obj.h
  4. 8 8
      src/vm.h

+ 1 - 1
src/codeobject.h

@@ -93,7 +93,7 @@ struct CodeObject {
         ss << '\n' << consts.str() << '\n' << names.str() << '\n';
         for(int i=0; i<co_consts.size(); i++){
             auto fn = std::get_if<_Func>(&co_consts[i]->_native);
-            if(fn) ss << '\n' << fn->code->co_name << ":\n" << fn->code->toString();
+            if(fn) ss << '\n' << (*fn)->code->co_name << ":\n" << (*fn)->code->toString();
         }
         return _Str(ss);
     }

+ 13 - 13
src/compiler.h

@@ -319,14 +319,14 @@ public:
     }
 
     void exprLambda() {
-        _Func func;
-        func.name = "<lambda>";
+        _Func func = std::make_shared<Function>();
+        func->name = "<lambda>";
         if(!match(TK(":"))){
             __compileFunctionArgs(func);
             consume(TK(":"));
         }
-        func.code = std::make_shared<CodeObject>(parser->src, func.name);
-        this->codes.push(func.code);
+        func->code = std::make_shared<CodeObject>(parser->src, func->name);
+        this->codes.push(func->code);
         EXPR_TUPLE();
         emitCode(OP_RETURN_VALUE);
         this->codes.pop();
@@ -773,7 +773,7 @@ __LISTCOMP:
         emitCode(OP_BUILD_CLASS, clsNameIdx);
     }
 
-    void __compileFunctionArgs(_Func& func){
+    void __compileFunctionArgs(_Func func){
         int state = 0;      // 0 for args, 1 for *args, 2 for k=v, 3 for **kwargs
         do {
             if(state == 3) syntaxError("**kwargs should be the last argument");
@@ -788,15 +788,15 @@ __LISTCOMP:
 
             consume(TK("@id"));
             const _Str& name = parser->previous.str();
-            if(func.hasName(name)) syntaxError("duplicate argument name");
+            if(func->hasName(name)) syntaxError("duplicate argument name");
 
             if(state == 0 && peek() == TK("=")) state = 2;
 
             switch (state)
             {
-                case 0: func.args.push_back(name); break;
-                case 1: func.starredArg = name; state+=1; break;
-                case 2: consume(TK("=")); func.kwArgs[name] = consumeLiteral(); break;
+                case 0: func->args.push_back(name); break;
+                case 1: func->starredArg = name; state+=1; break;
+                case 2: consume(TK("=")); func->kwArgs[name] = consumeLiteral(); break;
                 case 3: syntaxError("**kwargs is not supported yet"); break;
             }
         } while (match(TK(",")));
@@ -807,17 +807,17 @@ __LISTCOMP:
             if(match(TK("pass"))) return;
             consume(TK("def"));
         }
-        _Func func;
+        _Func func = std::make_shared<Function>();
         consume(TK("@id"));
-        func.name = parser->previous.str();
+        func->name = parser->previous.str();
 
         if (match(TK("(")) && !match(TK(")"))) {
             __compileFunctionArgs(func);
             consume(TK(")"));
         }
 
-        func.code = std::make_shared<CodeObject>(parser->src, func.name);
-        this->codes.push(func.code);
+        func->code = std::make_shared<CodeObject>(parser->src, func->name);
+        this->codes.push(func->code);
         compileBlockBody();
         this->codes.pop();
         emitCode(OP_LOAD_CONST, getCode()->addConst(vm->PyFunction(func)));

+ 4 - 1
src/obj.h

@@ -51,7 +51,7 @@ typedef std::shared_ptr<const BasePointer> _Pointer;
 typedef PyVar (*_CppFunc)(VM*, PyVarList);
 typedef std::shared_ptr<CodeObject> _Code;
 
-struct _Func {
+struct Function {
     _Str name;
     _Code code;
     std::vector<_Str> args;
@@ -100,8 +100,11 @@ public:
     _Iterator(VM* vm, PyVar _ref) : vm(vm), _ref(_ref) {}
 };
 
+typedef std::shared_ptr<Function> _Func;
 typedef std::variant<_Int,_Float,bool,_Str,PyVarList,_CppFunc,_Func,std::shared_ptr<_Iterator>,BoundedMethod,_Range,_Slice,_Pointer> _Value;
 
+const int _SIZEOF_VALUE = sizeof(_Value);
+
 #define UNREACHABLE() throw std::runtime_error("unreachable code! (this should be a bug, please report it)");
 
 struct PyObject {

+ 8 - 8
src/vm.h

@@ -110,7 +110,7 @@ private:
                     PyVar obj = frame->popValue(this);
                     const _Func& fn = PyFunction_AS_C(obj);
                     setAttr(obj, __module__, frame->_module);
-                    frame->f_globals()[fn.name] = obj;
+                    frame->f_globals()[fn->name] = obj;
                 } break;
             case OP_BUILD_CLASS:
                 {
@@ -123,7 +123,7 @@ private:
                         PyVar fn = frame->popValue(this);
                         if(fn == None) break;
                         const _Func& f = PyFunction_AS_C(fn);
-                        setAttr(cls, f.name, fn);
+                        setAttr(cls, f->name, fn);
                     }
                     frame->f_globals()[clsName] = cls;
                 } break;
@@ -369,7 +369,7 @@ public:
             const _Func& fn = PyFunction_AS_C(callable);
             PyVarDict locals;
             int i = 0;
-            for(const auto& name : fn.args){
+            for(const auto& name : fn->args){
                 if(i < args.size()) {
                     locals[name] = args[i++];
                 }else{
@@ -377,13 +377,13 @@ public:
                 }
             }
             // handle *args
-            if(!fn.starredArg.empty()){
+            if(!fn->starredArg.empty()){
                 PyVarList vargs;
                 while(i < args.size()) vargs.push_back(args[i++]);
-                locals[fn.starredArg] = PyTuple(vargs);
+                locals[fn->starredArg] = PyTuple(vargs);
             }
             // handle keyword arguments
-            for(const auto& [name, value] : fn.kwArgs){
+            for(const auto& [name, value] : fn->kwArgs){
                 if(i < args.size()) {
                     locals[name] = args[i++];
                 }else{
@@ -395,9 +395,9 @@ public:
 
             auto it_m = callable->attribs.find(__module__);
             if(it_m != callable->attribs.end()){
-                return _exec(fn.code, it_m->second, locals);
+                return _exec(fn->code, it_m->second, locals);
             }else{
-                return _exec(fn.code, topFrame()->_module, locals);
+                return _exec(fn->code, topFrame()->_module, locals);
             }
         }
         typeError("'" + callable->getTypeName() + "' object is not callable");