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';
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);
}

View File

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

View File

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

View File

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