]> Nishi Git Mirror - gwion.git/commitdiff
:art: Improve templates and typedefs
authorJérémie Astor <fennecdjay@gmail.com>
Sun, 3 Apr 2022 21:38:06 +0000 (23:38 +0200)
committerJérémie Astor <fennecdjay@gmail.com>
Sun, 3 Apr 2022 21:38:06 +0000 (23:38 +0200)
src/emit/emit.c
src/env/type.c
src/lib/opfunc.c
src/parse/check.c
src/parse/operator.c
src/parse/scan0.c
src/parse/scan1.c
src/parse/scan2.c
src/parse/template.c
tests/ctor/missing.gw [deleted file]

index 678eae0c622dada98394692040fc6b82506b0e5a..44c5bf6e607012ed9d65659bc8f78159499fb29d 100644 (file)
@@ -485,7 +485,7 @@ m_bool emit_instantiate_object(const Emitter emit, const Type type,
     if(!tflag(type, tflag_typedef)) {
       const Instr instr = emit_add_instr(emit, ObjectInstantiate);
       instr->m_val2     = (m_uint)type;
-    }
+    } // maybe we should instantiate the first actual type
     CHECK_BB(emit_pre_ctor(emit, type));
   }
   return GW_OK;
@@ -2546,6 +2546,11 @@ ANN static m_bool emit_stmt_loop(const Emitter emit, const Stmt_Loop stmt) {
 
 ANN static m_bool emit_type_def(const Emitter emit, const Type_Def tdef) {
   if (tdef->when) CHECK_BB(emit_func_def(emit, tdef->when_def));
+
+  if (!is_fptr(emit->gwion, tdef->type) && !tflag(tdef->type, tflag_cdef)) {
+    if(!tflag(tdef->type->info->parent, tflag_emit))
+                    return emit_class_def(emit, tdef->type->info->parent->info->cdef);
+  }
   return (!is_fptr(emit->gwion, tdef->type) && tdef->type->info->cdef)
              ? emit_class_def(emit, tdef->type->info->cdef)
              : GW_OK;
index 599b0c040a7172b2f5f167ac03361089e3ecbf71..8801e95e9ad19dddaee82e3483736b8f14e74585 100644 (file)
@@ -22,6 +22,8 @@ ANN void free_type(const Type a, struct Gwion_ *const gwion) {
     else if (tflag(a, tflag_cdef))
       class_def_cleaner(gwion, a->info->cdef);
   }
+  if (tflag(a, tflag_cdef) && a->info->parent)
+    type_remref(a->info->parent, gwion);
   if (a->effects.ptr) vector_release(&a->effects);
   if (a->nspc) nspc_remref(a->nspc, gwion);
   if (a->info->tuple) free_tupleform(a->info->tuple, gwion);
index a3ca7f07234a22ad3f483365dd9181f8beaf2e04..41fbf8502ee6d86c7b424c4cfdd94c769885e4f8 100644 (file)
@@ -136,9 +136,9 @@ OP_CHECK(opck_new) {
     self->d.exp_call.tmpl = NULL;
     self->exp_type = ae_exp_call;
     CHECK_BN(traverse_exp(env, self));
-    const Type tbase = func->type->info->value->from->owner_class;
-    if(!tflag(base->type, tflag_union) && tbase != base->type)
-      ERR_N(base->pos, "'%s' has no matching constructor", base->type->name);
+//    const Type tbase = func->type->info->value->from->owner_class;
+//    if(!tflag(base->type, tflag_union) && tbase != base->type)
+//      ERR_N(base->pos, "'%s' has no matching constructor", base->type->name);
     return self->type;
   }
   if (GET_FLAG(t, abstract) &&
index 8cf11d709de563935dc1b63fd674d860f722114b..d93ab1c601e9ec0364068448f253d951f3cdd460 100644 (file)
@@ -1105,6 +1105,11 @@ ANN m_bool check_type_def(const Env env, const Type_Def tdef) {
     ret_id->type             = tdef->type;
     tdef->when_def           = fdef;
   }
+  if (!is_fptr(env->gwion, tdef->type) && !tflag(tdef->type, tflag_cdef)) {
+    if(!tflag(tdef->type->info->parent, tflag_check))
+                    return check_class_def(env, tdef->type->info->parent->info->cdef);
+  }
+
   return (!is_fptr(env->gwion, tdef->type) && tdef->type->info->cdef)
              ? check_class_def(env, tdef->type->info->cdef)
              : GW_OK;
@@ -1948,11 +1953,14 @@ ANN static m_bool _check_class_def(const Env env, const Class_Def cdef) {
     if (cflag(cdef, cflag_struct) || class_def_has_body(env, cdef->body))
       set_tflag(t, tflag_ctor);
   }
+/*
+  // enforce new to be defined in every child class
   if(t->info->parent->nspc && nspc_lookup_value0(t->info->parent->nspc, insert_symbol("new")) && !nspc_lookup_value0(t->nspc, insert_symbol("new"))) {
     env_err(env, cdef->pos, "must define 'new' operator");
     env_warn(env, t->info->parent->info->value->from->loc, "defined here");
     return GW_ERROR;
   }
+*/
   if (!GET_FLAG(cdef, abstract)) CHECK_BB(check_abstract(env, cdef));
   if (cdef->traits) {
     ID_List list        = cdef->traits;
index ec73bd33df7f0a4c2111a1507f45aa8b4f078a10..4d98d22344aa216e3966c2cfb5c129d119fbca5e 100644 (file)
@@ -216,7 +216,7 @@ ANN bool tmpl_match(const Env env, const struct Op_Import *opi,
   Specialized_List sl  = base->tmpl->list;
   const Arg_List   args = base->args;
   Arg *arg0 = mp_vector_at(args, Arg, 0);
-  Arg *arg1 = mp_vector_at(args, Arg, 1);
+  Arg *arg1 = args->len > 1 ? mp_vector_at(args, Arg, 1) : NULL;
   uint32_t idx = 0;
   if (opi->lhs) {
     if (!_tmpl_match(env, opi->lhs, arg0->td, mp_vector_at(sl, Specialized, idx), &idx)) return false;
@@ -235,16 +235,20 @@ ANN bool tmpl_match(const Env env, const struct Op_Import *opi,
 }
 
 //! make template operator Func_def
-ANN Type op_def(const Env env, struct Op_Import *const opi,
+ANN static Type op_def(const Env env, struct Op_Import *const opi,
                 const Func_Def fdef) {
   const Func_Def tmpl_fdef    = cpy_func_def(env->gwion->mp, fdef);
   tmpl_fdef->base->tmpl->base = 0;
   tmpl_fdef->base->tmpl->call = new_mp_vector(env->gwion->mp,
-    sizeof(Type_Decl*), !!opi->lhs + !!opi->rhs);
+    sizeof(Type_Decl*), fdef->base->tmpl->list->len);
   if (opi->lhs) {
-     mp_vector_set(tmpl_fdef->base->tmpl->call, Type_Decl*, 0, type2td(env->gwion, opi->lhs, opi->pos));
-     if(opi->rhs)
-       mp_vector_set(tmpl_fdef->base->tmpl->call, Type_Decl*, 1, type2td(env->gwion, opi->rhs, opi->pos));
+     uint32_t idx = 0;
+     const Type lhs = find_type(env, mp_vector_at(fdef->base->args, Arg, 0)->td);
+     if(!lhs)
+       mp_vector_set(tmpl_fdef->base->tmpl->call, Type_Decl*, idx++, type2td(env->gwion, opi->lhs, opi->pos));
+     const Type rhs = find_type(env, mp_vector_at(fdef->base->args, Arg, 1)->td);
+     if(!rhs)
+       mp_vector_set(tmpl_fdef->base->tmpl->call, Type_Decl*, idx, type2td(env->gwion, opi->rhs, opi->pos));
   } else
      mp_vector_set(tmpl_fdef->base->tmpl->call, Type_Decl*, 0, type2td(env->gwion, opi->rhs, opi->pos));
   if (traverse_func_def(env, tmpl_fdef) < 0) {
index 9e1e5f7777dfe435d1dc9089ecc92f4e5f2859d0..1c8eb9c6c62516f52ad7ca40a6e030524475fce0 100644 (file)
@@ -153,6 +153,7 @@ ANN static m_bool typedef_complex(const Env env, const Type_Def tdef,
   CHECK_BB(scan0_class_def(env, cdef));
   tdef->type      = cdef->base.type;
   cdef->base.tmpl = tdef->tmpl; // check cpy
+  set_tflag(tdef->type, tflag_cdef);
   mk_class(env, tdef->type, tdef->pos);
   return GW_OK;
 }
@@ -180,14 +181,14 @@ ANN m_bool scan0_type_def(const Env env, const Type_Def tdef) {
     env_push_global(env);
   }
   if (!is_func(env->gwion, base)) {
-    if (!tdef->ext->types && (!tdef->ext->array || !tdef->ext->array->exp))
+    if (!tdef->ext->types && (!tdef->ext->array || !tdef->ext->array->exp)) {
       typedef_simple(env, tdef, base);
-    else
+    else
       CHECK_BB(typedef_complex(env, tdef, base));
   } else
     typedef_fptr(env, tdef, base);
   if (tdef->when) set_tflag(tdef->type, tflag_contract);
-  if (!tdef->distinct && !tdef->when)
+  if (tdef->type != base && !tdef->distinct && !tdef->when)
     scan0_implicit_similar(env, base, tdef->type);
   if (tdef->distinct || tdef->when) {
 //    tdef->type->info->parent = base->info->parent;
@@ -198,14 +199,15 @@ ANN m_bool scan0_type_def(const Env env, const Type_Def tdef) {
     op_cpy(env, &opi);
     scan0_explicit_distinct(env, base, tdef->type);
     type_addref(tdef->type); // maybe because of scope_iter in nspc_free_values
-  } else
+  } else if(tdef->ext->array)
     set_tflag(tdef->type, tflag_typedef);
   if(tflag(base, tflag_ref)) {
     set_tflag(tdef->type, tflag_ref);
     set_tflag(tdef->type, tflag_infer);
   }
   if (global) env_pop(env, 0);
-  tdef->type->info->base_type = base;
+  if (tdef->type != base)
+    tdef->type->info->base_type = base;
   return GW_OK;
 }
 
@@ -346,6 +348,7 @@ ANN static Type scan0_class_def_init(const Env env, const Class_Def cdef) {
   CHECK_BO(scan0_defined(env, cdef->base.xid, cdef->pos));
   const Type parent = cdef_parent(env, cdef);
   if (parent == (Type)GW_ERROR) return NULL;
+  if(parent) type_addref(parent);
   if (cdef->traits) CHECK_BO(find_traits(env, cdef->traits, cdef->pos));
   const Type t = scan0_type(env, s_name(cdef->base.xid), parent);
   if (cflag(cdef, cflag_struct)) {
index 04b224157973dc05de0542dc399347600f86d730..a18ccf2912d173fa425fa58117b617ebce0bdb80 100644 (file)
@@ -477,6 +477,13 @@ ANN m_bool scan1_fptr_def(const Env env, const Fptr_Def fptr) {
 ANN m_bool scan1_type_def(const Env env, const Type_Def tdef) {
   if (!tdef->type) tdef->type = nspc_lookup_type0(env->curr, tdef->xid);
   if (tdef->when) CHECK_BB(scan1_exp(env, tdef->when));
+  if (!is_fptr(env->gwion, tdef->type) && !tflag(tdef->type, tflag_cdef)) {
+    if(!tflag(tdef->type->info->parent, tflag_scan1))
+                    return scan1_class_def(env, tdef->type->info->parent->info->cdef);
+  }
+  if (!is_fptr(env->gwion, tdef->type) && !tdef->type->info->cdef) {
+    if(!tflag(tdef->type->info->parent, tflag_scan1))exit(12);
+  }
   return (!is_fptr(env->gwion, tdef->type) && tdef->type->info->cdef)
              ? scan1_cdef(env, tdef->type)
              : GW_OK;
index 993aca8a931889004eaab4e3a8dd06b0b68f4de3..da9eff7ee9284243654160c5197301ecad36399e 100644 (file)
@@ -89,6 +89,10 @@ ANN m_bool scan2_fptr_def(const Env env NUSED, const Fptr_Def fptr) {
 ANN static m_bool scan2_func_def_op(const Env env, const Func_Def f);
 ANN m_bool        scan2_type_def(const Env env, const Type_Def tdef) {
   if (tdef->when) CHECK_BB(scan2_exp(env, tdef->when));
+  if (!is_fptr(env->gwion, tdef->type) && !tflag(tdef->type, tflag_cdef)) {
+    if(!tflag(tdef->type->info->parent, tflag_scan2))
+                    return scan2_class_def(env, tdef->type->info->parent->info->cdef);
+  }
   if (!tdef->type->info->cdef) return GW_OK;
   return (!is_fptr(env->gwion, tdef->type) && tdef->type->info->cdef)
                     ? scan2_class_def(env, tdef->type->info->cdef)
index 00392f1000d5549ac9356d938af1f69cb83113d5..eaf5b67b27a31944513d40926bcab5af977111e8 100644 (file)
@@ -20,7 +20,6 @@ ANN static m_bool _push_types(const Env env, const Nspc nspc,
   for(uint32_t i = 0; i < sl->len; i++) {
     if (i >= tl->len) return GW_OK;
     Type_Decl *td = *mp_vector_at(tl, Type_Decl*, i);
-//    const Type t = td ? known_type(env, td) : NULL;
     const Type t = known_type(env, td);
     if (!t) return GW_OK;
     Specialized *spec = mp_vector_at(sl, Specialized, i);
@@ -114,7 +113,7 @@ static ANN Type maybe_func(const Env env, const Type t, const Type_Decl *td) {
         t->name)
 }
 
-ANN Type _scan_type(const Env env, const Type t, Type_Decl *td) {
+ANN static Type _scan_type(const Env env, const Type t, Type_Decl *td) {
   if (tflag(t, tflag_tmpl) && !is_func(env->gwion, t)) {
     if (tflag(t, tflag_ntmpl) && !td->types) return t;
     if(!td->types) {
diff --git a/tests/ctor/missing.gw b/tests/ctor/missing.gw
deleted file mode 100644 (file)
index ff73ef5..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#! [contains] must define 'new' operator
-class C {
-  operator new() {}
-}
-class D extends C {}
-<<< "lol" >>>;