diff --git a/src/codeobject.h b/src/codeobject.h index 63fa9aa1..7403a3dd 100644 --- a/src/codeobject.h +++ b/src/codeobject.h @@ -93,7 +93,7 @@ struct CodeObject { ss << '\n' << consts.str() << '\n' << names.str() << '\n'; for(int i=0; i(&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); } diff --git a/src/compiler.h b/src/compiler.h index 4f359d23..62138fb1 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -319,14 +319,14 @@ public: } void exprLambda() { - _Func func; - func.name = ""; + _Func func = std::make_shared(); + func->name = ""; if(!match(TK(":"))){ __compileFunctionArgs(func); consume(TK(":")); } - func.code = std::make_shared(parser->src, func.name); - this->codes.push(func.code); + func->code = std::make_shared(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(); 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(parser->src, func.name); - this->codes.push(func.code); + func->code = std::make_shared(parser->src, func->name); + this->codes.push(func->code); compileBlockBody(); this->codes.pop(); emitCode(OP_LOAD_CONST, getCode()->addConst(vm->PyFunction(func))); diff --git a/src/obj.h b/src/obj.h index 9b3add90..64703048 100644 --- a/src/obj.h +++ b/src/obj.h @@ -51,7 +51,7 @@ typedef std::shared_ptr _Pointer; typedef PyVar (*_CppFunc)(VM*, PyVarList); typedef std::shared_ptr _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 _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 { diff --git a/src/vm.h b/src/vm.h index e99c7c0c..c7911a38 100644 --- a/src/vm.h +++ b/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");