Update expr.hpp

This commit is contained in:
blueloveTH 2024-06-20 00:58:27 +08:00
parent dbd75615d9
commit 92fcc116af

View File

@ -10,7 +10,48 @@ struct Expr;
typedef small_vector<Expr*, 4> Expr_vector; typedef small_vector<Expr*, 4> Expr_vector;
static bool default_false(const Expr*) { return false; }
static int default_zero(const Expr*) { return 0; }
static void default_dtor(Expr*) {}
struct ExprVt{
void (*dtor)(Expr*);
/* reflections */
bool (*is_literal)(const Expr*);
bool (*is_json_object)(const Expr*);
bool (*is_attrib)(const Expr*);
bool (*is_subscr)(const Expr*);
bool (*is_compare)(const Expr*);
int (*star_level)(const Expr*);
bool (*is_tuple)(const Expr*);
bool (*is_name)(const Expr*);
/* emit */
void (*emit_)(Expr*, CodeEmitContext*);
bool (*emit_del)(Expr*, CodeEmitContext*);
bool (*emit_store)(Expr*, CodeEmitContext*);
void (*emit_inplace)(Expr*, CodeEmitContext*);
bool (*emit_store_inplace)(Expr*, CodeEmitContext*);
};
void ExprVt__ctor(ExprVt* vt){
vt->dtor = default_dtor;
vt->is_literal = default_false;
vt->is_json_object = default_false;
vt->is_attrib = default_false;
vt->is_subscr = default_false;
vt->is_compare = default_false;
vt->star_level = default_zero;
vt->is_tuple = default_false;
vt->is_name = default_false;
vt->emit_ = NULL; // must be set
vt->emit_del = NULL;
vt->emit_store = NULL;
vt->emit_inplace = NULL;
vt->emit_store_inplace = NULL;
}
struct Expr { struct Expr {
ExprVt* vt;
int line = 0; int line = 0;
virtual ~Expr() = default; virtual ~Expr() = default;
virtual void emit_(CodeEmitContext* ctx) = 0; virtual void emit_(CodeEmitContext* ctx) = 0;
@ -22,34 +63,53 @@ struct Expr {
Expr& operator=(Expr&&) = delete; Expr& operator=(Expr&&) = delete;
virtual bool is_literal() const { return false; } virtual bool is_literal() const { return false; }
virtual bool is_json_object() const { return false; } virtual bool is_json_object() const { return false; }
virtual bool is_attrib() const { return false; } virtual bool is_attrib() const { return false; }
virtual bool is_subscr() const { return false; } virtual bool is_subscr() const { return false; }
virtual bool is_compare() const { return false; } virtual bool is_compare() const { return false; }
virtual int star_level() const { return 0; } virtual int star_level() const { return 0; }
virtual bool is_tuple() const { return false; } virtual bool is_tuple() const { return false; }
virtual bool is_name() const { return false; } virtual bool is_name() const { return false; }
bool is_starred() const { return star_level() > 0; } bool is_starred() const { return star_level() > 0; }
// for OP_DELETE_XXX // for OP_DELETE_XXX
[[nodiscard]] virtual bool emit_del(CodeEmitContext* ctx) { return false; } [[nodiscard]] virtual bool emit_del(CodeEmitContext* ctx) { return false; }
// for OP_STORE_XXX // for OP_STORE_XXX
[[nodiscard]] virtual bool emit_store(CodeEmitContext* ctx) { return false; } [[nodiscard]] virtual bool emit_store(CodeEmitContext* ctx) { return false; }
virtual void emit_inplace(CodeEmitContext* ctx) { emit_(ctx); } virtual void emit_inplace(CodeEmitContext* ctx) { emit_(ctx); }
[[nodiscard]] virtual bool emit_store_inplace(CodeEmitContext* ctx) { return emit_store(ctx); } [[nodiscard]] virtual bool emit_store_inplace(CodeEmitContext* ctx) { return emit_store(ctx); }
}; };
void pk_Expr__emit_(Expr* self, CodeEmitContext* ctx){
assert(self->vt->emit_);
self->vt->emit_(self, ctx);
}
bool pk_Expr__emit_del(Expr* self, CodeEmitContext* ctx){
if(!self->vt->emit_del) return false;
return self->vt->emit_del(self, ctx);
}
bool pk_Expr__emit_store(Expr* self, CodeEmitContext* ctx){
if(!self->vt->emit_store) return false;
return self->vt->emit_store(self, ctx);
}
void pk_Expr__emit_inplace(Expr* self, CodeEmitContext* ctx){
if(!self->vt->emit_inplace){
pk_Expr__emit_(self, ctx);
return;
}
self->vt->emit_inplace(self, ctx);
}
bool pk_Expr__emit_store_inplace(Expr* self, CodeEmitContext* ctx){
if(!self->vt->emit_store_inplace){
return pk_Expr__emit_store(self, ctx);
}
return self->vt->emit_store_inplace(self, ctx);
}
inline void delete_expr(Expr* p) noexcept{ inline void delete_expr(Expr* p) noexcept{
if(!p) return; if(!p) return;
p->~Expr(); p->~Expr();