diff --git a/include/pocketpy/compiler/expr.hpp b/include/pocketpy/compiler/expr.hpp index bf38468f..840af49b 100644 --- a/include/pocketpy/compiler/expr.hpp +++ b/include/pocketpy/compiler/expr.hpp @@ -10,7 +10,48 @@ struct Expr; typedef small_vector 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 { + ExprVt* vt; int line = 0; virtual ~Expr() = default; virtual void emit_(CodeEmitContext* ctx) = 0; @@ -22,34 +63,53 @@ struct Expr { Expr& operator=(Expr&&) = delete; virtual bool is_literal() const { return false; } - virtual bool is_json_object() const { return false; } - virtual bool is_attrib() const { return false; } - virtual bool is_subscr() const { return false; } - virtual bool is_compare() const { return false; } - virtual int star_level() const { return 0; } - virtual bool is_tuple() const { return false; } - virtual bool is_name() const { return false; } - bool is_starred() const { return star_level() > 0; } // for OP_DELETE_XXX [[nodiscard]] virtual bool emit_del(CodeEmitContext* ctx) { return false; } - // for OP_STORE_XXX [[nodiscard]] virtual bool emit_store(CodeEmitContext* ctx) { return false; } - virtual void emit_inplace(CodeEmitContext* ctx) { emit_(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{ if(!p) return; p->~Expr();