This commit is contained in:
BLUELOVETH 2023-04-03 13:09:46 +00:00
parent 4ae187ab8f
commit 190d2a0589
2 changed files with 45 additions and 24 deletions

View File

@ -575,6 +575,8 @@ class Compiler {
void compile_decorated(){
EXPR(false);
// TODO: support multiple decorator
// use a while loop to consume '@'
if(!match_newlines(mode()==REPL_MODE)) SyntaxError();
ctx()->emit(OP_SETUP_DECORATOR, BC_NOARG, prev().line);
consume(TK("def"));
@ -582,40 +584,30 @@ class Compiler {
}
bool try_compile_assignment(){
Expr_ lhs = ctx()->s_expr.popx();
Expr* lhs_p = ctx()->s_expr.top().get();
bool inplace;
switch (curr().type) {
// case TK("+="): lhs->emit(ctx()); advance(); emit(OP_BINARY_OP, 0); break;
// case TK("-="): lhs->emit(ctx()); advance(); emit(OP_BINARY_OP, 1); break;
// case TK("*="): lhs->emit(ctx()); advance(); emit(OP_BINARY_OP, 2); break;
// case TK("/="): lhs->emit(ctx()); advance(); emit(OP_BINARY_OP, 3); break;
// case TK("//="): lhs->emit(ctx()); advance(); emit(OP_BINARY_OP, 4); break;
// case TK("%="): lhs->emit(ctx()); advance(); emit(OP_BINARY_OP, 5); break;
// case TK("<<="): lhs->emit(ctx()); advance(); emit(OP_BITWISE_OP, 0); break;
// case TK(">>="): lhs->emit(ctx()); advance(); emit(OP_BITWISE_OP, 1); break;
// case TK("&="): lhs->emit(ctx()); advance(); emit(OP_BITWISE_OP, 2); break;
// case TK("|="): lhs->emit(ctx()); advance(); emit(OP_BITWISE_OP, 3); break;
// case TK("^="): lhs->emit(ctx()); advance(); emit(OP_BITWISE_OP, 4); break;
// case TK("="): advance(); break;
case TK("+="): case TK("-="): case TK("*="): case TK("/="): case TK("//="): case TK("%="):
case TK("<<="): case TK(">>="): case TK("&="): case TK("|="): case TK("^="): {
inplace = true;
advance();
auto e = make_expr<BinaryExpr>();
e->op = prev().type;
e->lhs = lhs; // here should be a copy
e->op = prev().type - 1; // -1 to remove =
e->lhs = ctx()->s_expr.popx();
EXPR_TUPLE();
e->rhs = ctx()->s_expr.popx();
// ...
ctx()->s_expr.push(std::move(e));
} break;
case TK("="): advance(); break;
case TK("="):
inplace = false;
advance();
EXPR_TUPLE();
break;
default: return false;
}
if(prev().type == TK("=")){
EXPR_TUPLE();
Expr_ rhs = ctx()->s_expr.popx();
// do assign here
// lhs = rhs
return true;
}
ctx()->emit_expr();
bool ok = lhs_p->emit_store(ctx());
if(!ok) SyntaxError();
return true;
}

View File

@ -421,15 +421,44 @@ struct CompExpr: Expr{
Expr_ vars; // loop vars
Expr_ iter; // loop iter
Expr_ cond; // optional if condition
virtual Opcode op0() = 0;
virtual Opcode op1() = 0;
void emit(CodeEmitContext* ctx){
ctx->emit(op0(), 0, line);
iter->emit(ctx);
ctx->emit(OP_GET_ITER, BC_NOARG, BC_KEEPLINE);
ctx->enter_block(FOR_LOOP);
ctx->emit(OP_FOR_ITER, BC_NOARG, BC_KEEPLINE);
bool ok = vars->emit_store(ctx);
if(!ok) SyntaxError(); // this error occurs in `vars` instead of this line, but...nevermind
if(cond){
cond->emit(ctx);
int patch = ctx->emit(OP_POP_JUMP_IF_FALSE, BC_NOARG, BC_KEEPLINE);
ctx->emit(op1(), BC_NOARG, BC_KEEPLINE);
ctx->patch_jump(patch);
}else{
ctx->emit(op1(), BC_NOARG, BC_KEEPLINE);
}
ctx->emit(OP_LOOP_CONTINUE, BC_NOARG, BC_KEEPLINE);
ctx->exit_block();
}
};
struct ListCompExpr: CompExpr{
Opcode op0() override { return OP_BUILD_LIST; }
Opcode op1() override { return OP_LIST_APPEND; }
};
struct DictCompExpr: CompExpr{
Opcode op0() override { return OP_BUILD_DI CT; }
Opcode op1() override { return OP_DICT_ADD; }
};
struct SetCompExpr: CompExpr{
Opcode op0() override { return OP_BUILD_SET; }
Opcode op1() override { return OP_SET_ADD; }
};
struct LambdaExpr: Expr{