This commit is contained in:
blueloveTH 2023-04-05 19:25:43 +08:00
parent 14433b1210
commit cf5fadd3b0
4 changed files with 61 additions and 52 deletions

View File

@ -238,6 +238,7 @@ __NEXT_STEP:;
frame->push(std::move(ret)); frame->push(std::move(ret));
} DISPATCH(); } DISPATCH();
case OP_RETURN_VALUE: return frame->popx(); case OP_RETURN_VALUE: return frame->popx();
case OP_YIELD_VALUE: return _py_op_yield;
/*****************************************/ /*****************************************/
case OP_LIST_APPEND: { case OP_LIST_APPEND: {
PyObject* obj = frame->popx(); PyObject* obj = frame->popx();
@ -352,35 +353,39 @@ __NEXT_STEP:;
cls->attr().set(name, obj); cls->attr().set(name, obj);
} DISPATCH(); } DISPATCH();
/*****************************************/ /*****************************************/
/*****************************************/
/*****************************************/
// case OP_SETUP_DECORATOR: DISPATCH();
// case OP_ASSERT: {
// PyObject* _msg = frame->pop_value(this);
// Str msg = CAST(Str, asStr(_msg));
// PyObject* expr = frame->pop_value(this);
// if(asBool(expr) != True) _error("AssertionError", msg);
// } DISPATCH();
// case OP_EXCEPTION_MATCH: {
// const auto& e = CAST(Exception&, frame->top());
// StrName name = frame->co->names[byte.arg].first;
// frame->push(VAR(e.match_type(name)));
// } DISPATCH();
// case OP_RAISE: {
// PyObject* obj = frame->pop_value(this);
// Str msg = obj == None ? "" : CAST(Str, asStr(obj));
// StrName type = frame->co->names[byte.arg].first;
// _error(type, msg);
// } DISPATCH();
// case OP_RE_RAISE: _raise(); DISPATCH();
// case OP_YIELD_VALUE: return _py_op_yield;
// // TODO: using "goto" inside with block may cause __exit__ not called // // TODO: using "goto" inside with block may cause __exit__ not called
// case OP_WITH_ENTER: call(frame->pop_value(this), __enter__, no_arg()); DISPATCH(); // case OP_WITH_ENTER: call(frame->pop_value(this), __enter__, no_arg()); DISPATCH();
// case OP_WITH_EXIT: call(frame->pop_value(this), __exit__, no_arg()); DISPATCH(); // case OP_WITH_EXIT: call(frame->pop_value(this), __exit__, no_arg()); DISPATCH();
// case OP_TRY_BLOCK_ENTER: frame->on_try_block_enter(); DISPATCH(); /*****************************************/
// case OP_TRY_BLOCK_EXIT: frame->on_try_block_exit(); DISPATCH(); case OP_TRY_BLOCK_ENTER: frame->on_try_block_enter(); DISPATCH();
default: throw std::runtime_error(Str("opcode ") + OP_NAMES[byte.op] + " is not implemented"); case OP_TRY_BLOCK_EXIT: frame->on_try_block_exit(); DISPATCH();
/*****************************************/
case OP_ASSERT: {
PyObject* obj = frame->top();
Str msg;
if(is_type(obj, tp_tuple)){
auto& t = CAST(Tuple&, obj);
if(t.size() != 2) ValueError("assert tuple must have 2 elements");
obj = t[0];
msg = CAST(Str&, asStr(t[1]));
}
bool ok = asBool(obj);
frame->pop();
if(!ok) _error("AssertionError", msg);
} DISPATCH();
case OP_EXCEPTION_MATCH: {
const auto& e = CAST(Exception&, frame->top());
StrName name = frame->co->names[byte.arg];
frame->push(VAR(e.match_type(name)));
} DISPATCH();
case OP_RAISE: {
PyObject* obj = frame->popx();
Str msg = obj == None ? "" : CAST(Str, asStr(obj));
StrName type = frame->co->names[byte.arg];
_error(type, msg);
} DISPATCH();
case OP_RE_RAISE: _raise(); DISPATCH();
default: throw std::runtime_error(OP_NAMES[byte.op] + std::string(" is not implemented"));
} }
UNREACHABLE(); UNREACHABLE();
} }

View File

@ -578,13 +578,14 @@ class Compiler {
} }
void compile_decorated(){ void compile_decorated(){
EXPR(false); std::vector<Expr_> decorators;
// TODO: support multiple decorator do{
// use a while loop to consume '@' EXPR();
decorators.push_back(ctx()->s_expr.popx());
if(!match_newlines_repl()) SyntaxError(); if(!match_newlines_repl()) SyntaxError();
ctx()->emit(OP_SETUP_DECORATOR, BC_NOARG, prev().line); }while(match(TK("@")));
consume(TK("def")); consume(TK("def"));
compile_function(); compile_function(decorators);
} }
bool try_compile_assignment(){ bool try_compile_assignment(){
@ -593,6 +594,7 @@ class Compiler {
switch (curr().type) { switch (curr().type) {
case TK("+="): case TK("-="): case TK("*="): case TK("/="): case TK("//="): case TK("%="): case TK("+="): case TK("-="): case TK("*="): case TK("/="): case TK("//="): case TK("%="):
case TK("<<="): case TK(">>="): case TK("&="): case TK("|="): case TK("^="): { case TK("<<="): case TK(">>="): case TK("&="): case TK("|="): case TK("^="): {
if(ctx()->is_compiling_class) SyntaxError();
inplace = true; inplace = true;
advance(); advance();
auto e = make_expr<BinaryExpr>(); auto e = make_expr<BinaryExpr>();
@ -802,7 +804,7 @@ class Compiler {
} while (match(TK(","))); } while (match(TK(",")));
} }
void compile_function(){ void compile_function(const std::vector<Expr_>& decorators={}){
// TODO: bug, if there are multiple decorators, will cause error // TODO: bug, if there are multiple decorators, will cause error
FuncDecl_ decl = make_sp<FuncDecl>(); FuncDecl_ decl = make_sp<FuncDecl>();
StrName obj_name; StrName obj_name;
@ -825,6 +827,12 @@ class Compiler {
compile_block_body(); compile_block_body();
pop_context(); pop_context();
ctx()->emit(OP_LOAD_FUNCTION, ctx()->add_func_decl(decl), prev().line); ctx()->emit(OP_LOAD_FUNCTION, ctx()->add_func_decl(decl), prev().line);
// add decorators
for(auto it=decorators.rbegin(); it!=decorators.rend(); ++it){
(*it)->emit(ctx());
ctx()->emit(OP_ROT_TWO, BC_NOARG, (*it)->line);
ctx()->emit(OP_CALL, 1, (*it)->line);
}
if(!ctx()->is_compiling_class){ if(!ctx()->is_compiling_class){
if(obj_name.empty()){ if(obj_name.empty()){
auto e = make_expr<NameExpr>(decl->name, name_scope()); auto e = make_expr<NameExpr>(decl->name, name_scope());

View File

@ -140,6 +140,10 @@ struct NameExpr: Expr{
bool emit_store(CodeEmitContext* ctx) override { bool emit_store(CodeEmitContext* ctx) override {
int index = ctx->add_name(name); int index = ctx->add_name(name);
if(ctx->is_compiling_class){
ctx->emit(OP_STORE_CLASS_ATTR, index, line);
return true;
}
switch(scope){ switch(scope){
case NAME_LOCAL: case NAME_LOCAL:
ctx->emit(OP_STORE_LOCAL, index, line); ctx->emit(OP_STORE_LOCAL, index, line);

View File

@ -1,23 +1,5 @@
#ifdef OPCODE #ifdef OPCODE
/**************************/
OPCODE(WITH_ENTER)
OPCODE(WITH_EXIT)
OPCODE(ASSERT)
OPCODE(EXCEPTION_MATCH)
OPCODE(RAISE)
OPCODE(RE_RAISE)
OPCODE(STORE_FUNCTION)
OPCODE(TRY_BLOCK_ENTER)
OPCODE(TRY_BLOCK_EXIT)
OPCODE(YIELD_VALUE)
OPCODE(SETUP_DECORATOR)
/**************************/ /**************************/
OPCODE(NO_OP) OPCODE(NO_OP)
/**************************/ /**************************/
@ -74,6 +56,7 @@ OPCODE(CALL_UNPACK)
OPCODE(CALL_KWARGS) OPCODE(CALL_KWARGS)
OPCODE(CALL_KWARGS_UNPACK) OPCODE(CALL_KWARGS_UNPACK)
OPCODE(RETURN_VALUE) OPCODE(RETURN_VALUE)
OPCODE(YIELD_VALUE)
/**************************/ /**************************/
OPCODE(LIST_APPEND) OPCODE(LIST_APPEND)
OPCODE(DICT_ADD) OPCODE(DICT_ADD)
@ -92,9 +75,18 @@ OPCODE(IMPORT_STAR)
OPCODE(UNPACK_SEQUENCE) OPCODE(UNPACK_SEQUENCE)
OPCODE(UNPACK_EX) OPCODE(UNPACK_EX)
/**************************/ /**************************/
// TODO: examine this
OPCODE(BEGIN_CLASS) OPCODE(BEGIN_CLASS)
OPCODE(END_CLASS) OPCODE(END_CLASS)
OPCODE(STORE_CLASS_ATTR) OPCODE(STORE_CLASS_ATTR)
/**************************/ /**************************/
OPCODE(WITH_ENTER)
OPCODE(WITH_EXIT)
/**************************/
OPCODE(TRY_BLOCK_ENTER)
OPCODE(TRY_BLOCK_EXIT)
OPCODE(ASSERT)
OPCODE(EXCEPTION_MATCH)
OPCODE(RAISE)
OPCODE(RE_RAISE)
/**************************/
#endif #endif