fix a bug

This commit is contained in:
blueloveTH 2023-04-05 14:38:14 +08:00
parent 6452acf327
commit 9077da4d6c
6 changed files with 37 additions and 31 deletions

View File

@ -15,7 +15,7 @@ __NEXT_STEP:;
* For example, frame->popx() returns a strong reference which may be dangerous * For example, frame->popx() returns a strong reference which may be dangerous
* `Args` containing strong references is safe if it is passed to `call` or `fast_call` * `Args` containing strong references is safe if it is passed to `call` or `fast_call`
*/ */
heap._auto_collect(this); //heap._auto_collect(this);
const Bytecode& byte = frame->next_bytecode(); const Bytecode& byte = frame->next_bytecode();
switch (byte.op) switch (byte.op)
@ -38,7 +38,7 @@ __NEXT_STEP:;
case OP_LOAD_ELLIPSIS: frame->push(Ellipsis); DISPATCH(); case OP_LOAD_ELLIPSIS: frame->push(Ellipsis); DISPATCH();
case OP_LOAD_BUILTIN_EVAL: frame->push(builtins->attr(m_eval)); DISPATCH(); case OP_LOAD_BUILTIN_EVAL: frame->push(builtins->attr(m_eval)); DISPATCH();
case OP_LOAD_FUNCTION: { case OP_LOAD_FUNCTION: {
const FunctionDecl* decl = &frame->co->func_decls[byte.arg]; FuncDecl_ decl = frame->co->func_decls[byte.arg];
PyObject* obj = VAR(Function({decl, frame->_module, frame->_locals})); PyObject* obj = VAR(Function({decl, frame->_module, frame->_locals}));
frame->push(obj); frame->push(obj);
} DISPATCH(); } DISPATCH();

View File

@ -60,7 +60,7 @@ struct CodeObject {
std::set<StrName> global_names; std::set<StrName> global_names;
std::vector<CodeBlock> blocks = { CodeBlock{NO_BLOCK, -1} }; std::vector<CodeBlock> blocks = { CodeBlock{NO_BLOCK, -1} };
std::map<StrName, int> labels; std::map<StrName, int> labels;
std::vector<FunctionDecl> func_decls; std::vector<FuncDecl_> func_decls;
// may be.. just use a large NameDict? // may be.. just use a large NameDict?
uint32_t perfect_locals_capacity = 2; uint32_t perfect_locals_capacity = 2;
@ -71,8 +71,8 @@ struct CodeObject {
void _mark() const { void _mark() const {
for(PyObject* v : consts) OBJ_MARK(v); for(PyObject* v : consts) OBJ_MARK(v);
for(auto& decl: func_decls){ for(auto& decl: func_decls){
decl.kwargs._mark(); decl->kwargs._mark();
decl.code->_mark(); decl->code->_mark();
} }
} }
}; };

View File

@ -169,14 +169,12 @@ class Compiler {
// PASS // PASS
void exprLambda(){ void exprLambda(){
auto e = make_expr<LambdaExpr>(); auto e = make_expr<LambdaExpr>(name_scope());
e->decl.name = "<lambda>";
e->scope = name_scope();
if(!match(TK(":"))){ if(!match(TK(":"))){
_compile_f_args(e->decl, false); _compile_f_args(e->decl, false);
consume(TK(":")); consume(TK(":"));
} }
e->decl.code = push_context(lexer->src, "<lambda>"); e->decl->code = push_context(lexer->src, e->decl->name.str());
EXPR(false); // https://github.com/blueloveTH/pocketpy/issues/37 EXPR(false); // https://github.com/blueloveTH/pocketpy/issues/37
ctx()->emit(OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE); ctx()->emit(OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE);
pop_context(); pop_context();
@ -754,7 +752,7 @@ class Compiler {
ctx()->emit(OP_END_CLASS, BC_NOARG, BC_KEEPLINE); ctx()->emit(OP_END_CLASS, BC_NOARG, BC_KEEPLINE);
} }
void _compile_f_args(FunctionDecl& func, bool enable_type_hints){ void _compile_f_args(FuncDecl_ decl, bool enable_type_hints){
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");
@ -769,7 +767,7 @@ class Compiler {
consume(TK("@id")); consume(TK("@id"));
const Str& name = prev().str(); const Str& name = prev().str();
if(func.has_name(name)) SyntaxError("duplicate argument name"); if(decl->has_name(name)) SyntaxError("duplicate argument name");
// eat type hints // eat type hints
if(enable_type_hints && match(TK(":"))) consume(TK("@id")); if(enable_type_hints && match(TK(":"))) consume(TK("@id"));
@ -778,16 +776,16 @@ class Compiler {
switch (state) switch (state)
{ {
case 0: func.args.push_back(name); break; case 0: decl->args.push_back(name); break;
case 1: func.starred_arg = name; state+=1; break; case 1: decl->starred_arg = name; state+=1; break;
case 2: { case 2: {
consume(TK("=")); consume(TK("="));
PyObject* value = read_literal(); PyObject* value = read_literal();
if(value == nullptr){ if(value == nullptr){
SyntaxError(Str("expect a literal, not ") + TK_STR(curr().type)); SyntaxError(Str("expect a literal, not ") + TK_STR(curr().type));
} }
func.kwargs.set(name, value); decl->kwargs.set(name, value);
func.kwargs_order.push_back(name); decl->kwargs_order.push_back(name);
} break; } break;
case 3: SyntaxError("**kwargs is not supported yet"); break; case 3: SyntaxError("**kwargs is not supported yet"); break;
} }
@ -796,38 +794,38 @@ class Compiler {
void compile_function(){ void compile_function(){
// TODO: bug, if there are multiple decorators, will cause error // TODO: bug, if there are multiple decorators, will cause error
FunctionDecl func; FuncDecl_ decl = make_sp<FuncDecl>();
StrName obj_name; StrName obj_name;
consume(TK("@id")); consume(TK("@id"));
func.name = prev().str(); decl->name = prev().str();
if(!ctx()->is_compiling_class && match(TK("::"))){ if(!ctx()->is_compiling_class && match(TK("::"))){
consume(TK("@id")); consume(TK("@id"));
obj_name = func.name; obj_name = decl->name;
func.name = prev().str(); decl->name = prev().str();
} }
consume(TK("(")); consume(TK("("));
if (!match(TK(")"))) { if (!match(TK(")"))) {
_compile_f_args(func, true); _compile_f_args(decl, true);
consume(TK(")")); consume(TK(")"));
} }
if(match(TK("->"))){ if(match(TK("->"))){
if(!match(TK("None"))) consume(TK("@id")); if(!match(TK("None"))) consume(TK("@id"));
} }
func.code = push_context(lexer->src, func.name.str()); decl->code = push_context(lexer->src, decl->name.str());
compile_block_body(); compile_block_body();
pop_context(); pop_context();
ctx()->emit(OP_LOAD_FUNCTION, ctx()->add_func_decl(func), prev().line); ctx()->emit(OP_LOAD_FUNCTION, ctx()->add_func_decl(decl), prev().line);
if(!ctx()->is_compiling_class){ if(!ctx()->is_compiling_class){
if(obj_name.empty()){ if(obj_name.empty()){
auto e = make_expr<NameExpr>(func.name, name_scope()); auto e = make_expr<NameExpr>(decl->name, name_scope());
e->emit_store(ctx()); e->emit_store(ctx());
} else { } else {
ctx()->emit(OP_LOAD_NAME, ctx()->add_name(obj_name), prev().line); ctx()->emit(OP_LOAD_NAME, ctx()->add_name(obj_name), prev().line);
int index = ctx()->add_name(func.name); int index = ctx()->add_name(decl->name);
ctx()->emit(OP_STORE_ATTR, index, prev().line); ctx()->emit(OP_STORE_ATTR, index, prev().line);
} }
}else{ }else{
ctx()->emit(OP_STORE_CLASS_ATTR, ctx()->add_name(func.name), BC_KEEPLINE); ctx()->emit(OP_STORE_CLASS_ATTR, ctx()->add_name(decl->name), BC_KEEPLINE);
} }
} }

View File

@ -96,7 +96,7 @@ struct CodeEmitContext{
return co->consts.size() - 1; return co->consts.size() - 1;
} }
int add_func_decl(FunctionDecl decl){ int add_func_decl(FuncDecl_ decl){
co->func_decls.push_back(decl); co->func_decls.push_back(decl);
return co->func_decls.size() - 1; return co->func_decls.size() - 1;
} }
@ -477,9 +477,15 @@ struct SetCompExpr: CompExpr{
}; };
struct LambdaExpr: Expr{ struct LambdaExpr: Expr{
FunctionDecl decl; FuncDecl_ decl;
NameScope scope; NameScope scope;
Str str() const override { return "<lambda>"; } Str str() const override { return "<lambda>"; }
LambdaExpr(NameScope scope){
this->decl = make_sp<FuncDecl>();
this->decl->name = "<lambda>";
this->scope = scope;
}
void emit(CodeEmitContext* ctx) override { void emit(CodeEmitContext* ctx) override {
int index = ctx->add_func_decl(decl); int index = ctx->add_func_decl(decl);

View File

@ -24,7 +24,7 @@ struct NativeFunc {
PyObject* operator()(VM* vm, Args& args) const; PyObject* operator()(VM* vm, Args& args) const;
}; };
struct FunctionDecl { struct FuncDecl {
StrName name; StrName name;
CodeObject_ code; CodeObject_ code;
std::vector<StrName> args; std::vector<StrName> args;
@ -40,8 +40,10 @@ struct FunctionDecl {
} }
}; };
using FuncDecl_ = shared_ptr<FuncDecl>;
struct Function{ struct Function{
const FunctionDecl* decl; FuncDecl_ decl;
PyObject* _module; PyObject* _module;
NameDict_ _closure; NameDict_ _closure;
}; };

View File

@ -626,8 +626,8 @@ inline Str VM::disassemble(CodeObject_ co){
ss << '\n' << consts.str() << '\n' << names.str(); ss << '\n' << consts.str() << '\n' << names.str();
for(auto& decl: co->func_decls){ for(auto& decl: co->func_decls){
ss << "\n\n" << "Disassembly of " << decl.name.str() << ":\n"; ss << "\n\n" << "Disassembly of " << decl->name.str() << ":\n";
ss << disassemble(decl.code); ss << disassemble(decl->code);
} }
return Str(ss.str()); return Str(ss.str());
} }