change Function to ptr

This commit is contained in:
blueloveTH 2022-11-12 00:11:16 +08:00
parent 7ecb8476f9
commit 9e7ef156c5
4 changed files with 26 additions and 23 deletions

View File

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

View File

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

View File

@ -51,7 +51,7 @@ typedef std::shared_ptr<const BasePointer> _Pointer;
typedef PyVar (*_CppFunc)(VM*, PyVarList); typedef PyVar (*_CppFunc)(VM*, PyVarList);
typedef std::shared_ptr<CodeObject> _Code; typedef std::shared_ptr<CodeObject> _Code;
struct _Func { struct Function {
_Str name; _Str name;
_Code code; _Code code;
std::vector<_Str> args; std::vector<_Str> args;
@ -100,8 +100,11 @@ public:
_Iterator(VM* vm, PyVar _ref) : vm(vm), _ref(_ref) {} _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; 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)"); #define UNREACHABLE() throw std::runtime_error("unreachable code! (this should be a bug, please report it)");
struct PyObject { struct PyObject {

View File

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