]> Nishi Git Mirror - gwion.git/commitdiff
:bug: Fix match for strings and the like
authorfennecdjay <fennecdjay@gmail.com>
Tue, 28 Jun 2022 05:10:47 +0000 (07:10 +0200)
committerfennecdjay <fennecdjay@gmail.com>
Tue, 28 Jun 2022 05:10:47 +0000 (07:10 +0200)
src/emit/emit.c
src/lib/closure.c
src/lib/deep_equal.c
src/parse/check.c

index b3f3e7a45cbd37366b26c0307ec28b35073573d6..cc689565779ef446ac7e5b0fa48fcc5c406cdda6 100644 (file)
@@ -2471,6 +2471,7 @@ ANN static m_bool case_value(const Emitter emit, const Exp base, const Exp e) {
   return GW_OK;
 }
 
+ANN Symbol case_basic_op(const Env env, const Type base, const Exp e);
 #define CASE_PASS (Symbol)1
 ANN static Symbol case_op(const Emitter emit, const Exp base, const Exp e,
                           const Vector vec, const uint n) {
@@ -2513,7 +2514,7 @@ ANN static Symbol case_op(const Emitter emit, const Exp base, const Exp e,
       }
     }
   }
-  if (!n) return insert_symbol("?=");
+  if (!n) return case_basic_op(emit->env, base->type, e);
   regpush(emit, SZ_INT);
   CHECK_BO(emit_exp(emit, e));
   const Exp_Binary bin  = {.lhs = base, .rhs = e, .op = insert_symbol("?=")};
index f15d53abfb8fa9e9e580455faa773ad621b38768..61091efa9bce885b156da4005a46424431149c70 100644 (file)
@@ -1,4 +1,3 @@
-#include <string.h>
 #include "gwion_util.h"
 #include "gwion_ast.h"
 #include "gwion_env.h"
index 2e6448b046a88cc09e1e1da4b3ac17cc989e71ca..5857500e9fa6fcf4857c25647b7418acc31cc35f 100644 (file)
@@ -55,7 +55,9 @@ static void type_get_member(const Gwion gwion, const Type t, const Vector v) {
 
 // get members of a type, starting from parents
 static void compound_get_member(const Env env, const Type t, const Vector v) {
-  if(t->info->parent && t->info->parent->nspc)
+  const Type parent = t->info->parent && t->info->parent->nspc
+                    ? t->info->parent : NULL;
+  if(parent)
     compound_get_member(env, t->info->parent, v);
   type_get_member(env->gwion, t, v);
 }
@@ -97,7 +99,6 @@ static bool deep_check(const Env env, const Exp_Binary *bin,
                        const Vector l, const Vector r) {
   const m_uint lsz = vector_size(l),
                rsz = vector_size(r);
-//  if(lsz && rsz >= lsz) {
   if(rsz >= lsz) {
     for(m_uint i = 0; i < lsz; i++) {
       const Value lval = (Value)vector_at(l, i),
@@ -114,6 +115,17 @@ static bool deep_check(const Env env, const Exp_Binary *bin,
 
 static OP_CHECK(opck_deep_equal) {
   Exp_Binary *const bin = data;
+  const Symbol base_op = !strcmp(s_name(bin->op), "?=")
+      ? insert_symbol(env->gwion->st, "==") : insert_symbol(env->gwion->st, "!=");
+  struct Op_Import opi = {.op   = base_op,
+                          .lhs  = bin->lhs->type,
+                          .rhs  = bin->rhs->type,
+                          .data = (uintptr_t)bin,
+                          .pos  = exp_self(bin)->pos};
+  if(op_get(env, &opi)) {
+    bin->op = base_op;
+    return op_check(env, &opi);
+  }
   struct Vector_ l, r;
   check_deep_equal_exp(env, bin->lhs, &l);
   check_deep_equal_exp(env, bin->rhs, &r);
@@ -122,8 +134,7 @@ static OP_CHECK(opck_deep_equal) {
   vector_release(&r);
   if(ret) return env->gwion->type[et_bool];
   const Symbol op = bin->op;
-  bin->op = !strcmp(s_name(bin->op), "?=")
-    ? insert_symbol(env->gwion->st, "==") : insert_symbol(env->gwion->st, "!=");
+  bin->op = base_op;
   env_set_error(env,  true);
   const Type ret_type = check_exp(env, exp_self(bin));
   env_set_error(env,  false);
index 3b470fe2029e44faf49b74e97e02fcca7375b3a2..3c867395465ec678c7b28a0128f6c1edbd4651a9 100644 (file)
@@ -1369,6 +1369,18 @@ ANN static Value match_value(const Env env, const Type base,
   return v;
 }
 
+ANN Symbol case_basic_op(const Env env, const Type base, const Exp e) {
+  const Symbol _op = insert_symbol("==");
+  struct Op_Import opi = {.op   = _op,
+                          .lhs  = base,
+                          .rhs  = e->type,
+                          .data = (uintptr_t)NULL,
+                          .pos  = e->pos};
+  return op_get(env, &opi)
+         ? insert_symbol("==")
+         : insert_symbol("?=");
+}
+
 ANN static Symbol case_op(const Env env, const Type base, const Exp e) {
   if (e->exp_type == ae_exp_primary) {
     if (e->d.prim.prim_type == ae_prim_id) {
@@ -1391,7 +1403,7 @@ ANN static Symbol case_op(const Env env, const Type base, const Exp e) {
       }
     }
   }
-  return insert_symbol("?=");
+  return case_basic_op(env, base, e);
 }
 
 ANN static m_bool match_case_exp(const Env env, Exp e) {
@@ -1409,13 +1421,8 @@ ANN static m_bool match_case_exp(const Env env, Exp e) {
       CHECK_OB(t);
       Exp_Binary       bin  = {.lhs = cpy_exp(env->gwion->mp, base), .rhs = cpy_exp(env->gwion->mp, e), .op = op};
       struct Exp_      ebin = {.d = {.exp_binary = bin}, .exp_type = ae_exp_binary, .pos = e->pos };
-      struct Op_Import opi  = {.op   = op,
-                              .lhs  = base->type,
-                              .rhs  = e->type,
-                              .data = (uintptr_t)&ebin.d.exp_binary,
-                              .pos  = e->pos};
-      traverse_exp(env, &ebin);
-      const Type ret = op_check(env, &opi);
+      CHECK_BB(traverse_exp(env, &ebin));
+      const Type ret = ebin.type;
       if(ebin.exp_type == ae_exp_binary) {
         free_exp(env->gwion->mp, bin.lhs);
         free_exp(env->gwion->mp, bin.rhs);