Răsfoiți Sursa

Update expr.hpp

blueloveTH 1 an în urmă
părinte
comite
92fcc116af
1 a modificat fișierele cu 71 adăugiri și 11 ștergeri
  1. 71 11
      include/pocketpy/compiler/expr.hpp

+ 71 - 11
include/pocketpy/compiler/expr.hpp

@@ -10,7 +10,48 @@ struct Expr;
 
 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 {
+    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();