]> Nishi Git Mirror - gwion.git/commitdiff
:bug: Fix cyclic types and imporve flaging
authorJérémie Astor <astor.jeremie@wanadoo.fr>
Thu, 7 May 2020 16:57:37 +0000 (18:57 +0200)
committerJérémie Astor <astor.jeremie@wanadoo.fr>
Thu, 7 May 2020 16:57:37 +0000 (18:57 +0200)
src/emit/emit.c
src/env/env.c
src/env/type.c
src/import/tdef.c
src/lib/object_op.c
src/parse/check.c
src/parse/scan0.c
src/parse/scan1.c
src/parse/scan2.c
src/parse/traverse.c

index 888bd3fcff6867ffc7fb82be197482738062756d..93af7968d76905c2b5f055c3555e0d07769ee1a3 100644 (file)
@@ -1568,7 +1568,6 @@ ANN static m_bool emit_union_def(const Emitter emit, const Union_Def udef) {
     const Var_Decl_List var_decl_list = new_var_decl_list(emit->gwion->mp, var_decl, NULL);
     const Exp exp = new_exp_decl(emit->gwion->mp, type_decl, var_decl_list);
     exp->d.exp_decl.type = udef->value->type;
-    SET_FLAG(udef->value->type, emit);
     var_decl->value = udef->value;
     const m_bool ret = emit_exp_decl(emit, &exp->d.exp_decl);
     free_exp(emit->gwion->mp, exp);
@@ -1582,7 +1581,6 @@ ANN static m_bool emit_union_def(const Emitter emit, const Union_Def udef) {
     scope = emit_push_type(emit, udef->value->type);
   } else if(udef->type_xid) {
     union_allocdata(emit->gwion->mp, udef);
-    SET_FLAG(udef->type, emit);
     scope = emit_push_type(emit, udef->type);
   } else if(global) {
     // TODO: use mpool allocation
@@ -1604,6 +1602,7 @@ ANN static m_bool emit_union_def(const Emitter emit, const Union_Def udef) {
   emit_union_offset(udef->l, udef->o);
   if(udef->xid || udef->type_xid || global)
     emit_pop(emit, scope);
+  union_flag(udef, ae_flag_emit);
   return GW_OK;
 }
 
@@ -1994,11 +1993,10 @@ ANN static m_bool emit_struct_body2(const Emitter emit, Section *const section)
     emit_section(emit, section) : GW_OK;
 }
 
-ANN static m_bool emit_class_def(const Emitter emit, const Class_Def c) {
-  if(tmpl_base(c->base.tmpl))
+ANN static m_bool emit_class_def(const Emitter emit, const Class_Def cdef) {
+  if(tmpl_base(cdef->base.tmpl))
     return GW_OK;
-  const Type t = c->base.type;
-  const Class_Def cdef = t->e->def;
+  const Type t = cdef->base.type;
   if(GET_FLAG(t, emit))
     return GW_OK;
   if(cdef->base.ext && t->e->parent->e->def && !GET_FLAG(t->e->parent, emit))
@@ -2013,7 +2011,6 @@ ANN static m_bool emit_class_def(const Emitter emit, const Class_Def c) {
     } else
       CHECK_BB(scanx_body(emit->env, cdef, (_exp_func)emit_struct_body2, emit))
   }
-  SET_FLAG(t, emit);
   return GW_OK;
 }
 
index c0d606b4eb5163d3985734d40c9d2cf2b385cbd7..40065470266120056190d688652126d195007808 100644 (file)
@@ -87,10 +87,6 @@ ANN void env_add_type(const Env env, const Type type) {
   const Value v = new_value(env->gwion->mp, v_type, s_name(sym));
   SET_FLAG(v, checked | ae_flag_const | ae_flag_global | ae_flag_builtin);
   nspc_add_value(env->curr, insert_symbol(type->name), v);
-//  valuefrom(env, v->from);
-//  typefrom(env, type->e->from);
-//  v->from->owner = type->e->from->owner = env->curr;
-//  type->e->owner = env->curr;
   v->from->owner = type->e->owner = env->curr;
   v->from->owner_class = type->e->owner_class = env->class_def; // t owner_class ?
   type->xid = ++env->scope->type_xid;
index 46fe3001787951510a39558b794e221f856b2f83..829cff69474b10f5c7902833d81bcdaebb88bb79 100644 (file)
@@ -7,8 +7,7 @@
 #include "gwion.h"
 
 ANN static inline m_bool freeable(const Type a) {
-  return !GET_FLAG(a, nonnull) &&
-      (GET_FLAG(a, template) || GET_FLAG(a, global));
+  return !GET_FLAG(a, nonnull) && GET_FLAG(a, template);
 }
 
 ANN static void free_type(Type a, Gwion gwion) {
index 4fa9d0501726a3894ac450143056c86185e37eee..46bd7bcbba0297b2110369e52cbdff201775ad83 100644 (file)
@@ -21,9 +21,6 @@ ANN m_int gwi_typedef_ini(const Gwi gwi, const restrict m_str type, const restri
   gwi->ck->name = name;
   CHECK_BB(check_typename_def(gwi, gwi->ck))
   return (gwi->ck->td = str2decl(gwi, type)) ? GW_OK : GW_ERROR;
-//  if(check_typename_def(gwi, gwi->ck) > 0)
-//    return (gwi->ck->td = str2decl(gwi, type)) ? GW_OK : GW_ERROR;
-//  return GW_ERROR;
 }
 
 ANN Type gwi_typedef_end(const Gwi gwi, const ae_flag flag) {
index a900ad8d3fa497f18927f77f916c4ada688a1c52..7bf90320d409a5dcc17d99dd82a79a3330785788 100644 (file)
@@ -378,7 +378,6 @@ ANN static m_bool class2udef(const Env env, const Class_Def a, const Type t) {
   if(GET_FLAG(t, global))
     SET_FLAG(a->union_def, global);
   CHECK_BB(scan0_union_def(env, a->union_def))
-  SET_FLAG(a, scan0);
   a->base.type = a->union_def->type;
   a->base.type->e->def = a;
   a->union_def->tmpl = cpy_tmpl(env->gwion->mp, a->base.tmpl);
index 93bc124471e4647d8770e4d46bc276d0851eb667..6c8cefae021cb513cf26479d9af795b9e67f59b7 100644 (file)
@@ -167,14 +167,6 @@ ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) {
     ERR_O(td_pos(decl->td), _("can't find type"));
   {
     const Type t = get_type(decl->type);
-    if(env->class_def && !env->scope->depth){
-      Type parent = t;
-      while(parent) {
-        if(parent == env->class_def && !GET_FLAG(decl->td, ref))
-          ERR_O(decl->td->pos, "declaration cycle detected. (declare as ref?)")
-        parent = parent->e->parent;
-      }
-    }
     if(!GET_FLAG(t, check) && t->e->def)
       CHECK_BO(ensure_check(env, t))
   }
@@ -1363,11 +1355,10 @@ ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) {
   return ret;
 }
 
-ANN m_bool check_class_def(const Env env, const Class_Def c) {
-  if(tmpl_base(c->base.tmpl))
+ANN m_bool check_class_def(const Env env, const Class_Def cdef) {
+  if(tmpl_base(cdef->base.tmpl))
     return GW_OK;
-  const Type t = c->base.type;
-  const Class_Def cdef = t->e->def;
+  const Type t = cdef->base.type;
   if(t->e->owner_class && !GET_FLAG(t->e->owner_class, check))
     CHECK_BB(check_class_def(env, t->e->owner_class->e->def))
   if(GET_FLAG(t, check))return GW_OK;
index 1cc3d60e25c6cdabc98004f6c26bc2e6833630fd..0af9b5b35c695c795531a3d625189ef6104255fc 100644 (file)
@@ -231,10 +231,9 @@ ANN static Type union_type(const Env env, const Symbol s, const m_bool add) {
   t->e->owner_class = env->class_def;
   t->e->parent = env->gwion->type[et_union];
   add_type(env, env->curr, t);
-  if(add) {
+  if(add)
     mk_class(env, t);
-  }
-  SET_FLAG(t, union | ae_flag_scan0);
+  SET_FLAG(t, union);
   return t;
 }
 
@@ -246,7 +245,6 @@ ANN static void union_tmpl(const Env env, const Union_Def udef) {
     udef->type->e->def = cdef;
     cdef->base.tmpl = cpy_tmpl(env->gwion->mp, udef->tmpl);
     cdef->base.type = udef->type;
-//    cdef->list = cpy_decl_list(env->gwion->mp, udef->l);
     SET_FLAG(cdef, union);
     SET_FLAG(udef->type, pure);
     SET_FLAG(udef, template);
@@ -296,6 +294,7 @@ ANN m_bool scan0_union_def(const Env env, const Union_Def udef) {
     union_tmpl(env, udef);
   if(GET_FLAG(udef, global))
     env_pop(env, scope);
+  union_flag(udef, ae_flag_scan0);
   return GW_OK;
 }
 
@@ -314,9 +313,26 @@ ANN static void cdef_flag(const Class_Def cdef, const Type t) {
     SET_FLAG(t, typedef);
 }
 
+ANN static Type get_parent(const Env env, const Class_Def cdef) {
+  if(GET_FLAG(cdef, struct))
+    return NULL;
+  if(!cdef->base.ext)
+    return env->gwion->type[et_object];
+  if(tmpl_base(cdef->base.tmpl))
+    return nspc_lookup_type1(env->curr, cdef->base.ext->xid);
+  if(cdef->base.tmpl)
+    template_push_types(env, cdef->base.tmpl);
+  const Type t = known_type(env, cdef->base.ext);
+  if(cdef->base.tmpl)
+    nspc_pop_type(env->gwion->mp, env->curr);
+  return t ?: (Type)GW_ERROR;
+}
+
 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 = !GET_FLAG(cdef, struct) ? env->gwion->type[et_object] : NULL;
+  const Type parent = get_parent(env, cdef);
+  if(parent == (Type)GW_ERROR)
+    return NULL;
   const Type t = scan0_type(env, ++env->scope->type_xid, s_name(cdef->base.xid), parent);
   if(GET_FLAG(cdef, struct)) {
     SET_FLAG(t, struct);
@@ -360,7 +376,7 @@ ANN static m_bool scan0_class_def_inner(const Env env, const Class_Def cdef) {
 }
 
 ANN m_bool scan0_class_def(const Env env, const Class_Def c) {
-  const Class_Def cdef = !(GET_FLAG(c, global) || (c->base.tmpl && !c->base.tmpl->call)) ?
+  const Class_Def cdef = !tmpl_base(c->base.tmpl) ?
     c : cpy_class_def(env->gwion->mp, c);
   if(GET_FLAG(cdef, global)) {
     vector_add(&env->scope->nspc_stack, (vtype)env->curr);
index 2cef2840530a2cb362e98b78da92a764003cbd28..a78ae058e65b5f59c3129cd4b4b0432d3f29e1c4 100644 (file)
@@ -9,6 +9,22 @@
 ANN static m_bool scan1_stmt_list(const Env env, Stmt_List list);
 ANN static m_bool scan1_stmt(const Env env, Stmt stmt);
 
+ANN static inline m_bool type_cyclic(const Env env, const Type t, const Type_Decl *td) {
+  Type parent = t->e->parent;
+  while(parent) {
+    if(parent == env->class_def)
+      ERR_B(td_pos(td), _("%s declared inside %s\n. (make it a ref ?)"), t->name, t == env->class_def ? "itself" : env->class_def->name);
+    parent = parent->e->parent;
+  }
+  return GW_OK;
+}
+
+ANN static inline m_bool ensure_scan1(const Env env, const Type t) {
+  struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan1_cdef,
+    .scope=env->scope->depth, .flag=ae_flag_scan1 };
+  return envset_run(&es, t);
+}
+
 ANN static m_bool type_recursive(const Env env, const Type_Decl *td, const Type t) {
   if(env->class_def && !env->scope->depth) {
     const m_int idx = vector_find(&env->scope->class_stack, (vtype)t);
@@ -19,11 +35,19 @@ ANN static m_bool type_recursive(const Env env, const Type_Decl *td, const Type
   return GW_OK;
 }
 
-ANN static Type void_type(const Env env, Type_Decl* td) {
+ANN static Type scan1_type(const Env env, Type_Decl* td) {
   DECL_OO(const Type, type, = known_type(env, td))
   const Type t = get_type(type);
-  if(isa(t, env->gwion->type[et_object]) > 0 || GET_FLAG(t, struct))
-    CHECK_BO(type_recursive(env, td, t))
+  CHECK_BO(type_cyclic(env, t, td))
+  if(!GET_FLAG(t, scan1) && t->e->def)
+    CHECK_BO(ensure_scan1(env, t))
+  return type;
+}
+
+ANN static Type void_type(const Env env, Type_Decl* td) {
+  DECL_OO(const Type, type, = scan1_type(env, td))
+  if(isa(type, env->gwion->type[et_object]) > 0 || GET_FLAG(type, struct))
+    CHECK_BO(type_recursive(env, td, type))
   if(type->size)
     return type;
   ERR_O(td_pos(td), _("cannot declare variables of size '0' (i.e. 'void')..."))
@@ -301,7 +325,7 @@ ANN m_bool scan1_fptr_def(const Env env, const Fptr_Def fptr) {
     fptr->type = nspc_lookup_type0(env->curr, fptr->base->xid);
   }
   const Func_Def fdef = fptr->base->func->def;
-  CHECK_OB((fdef->base->ret_type = known_type(env, fdef->base->td)))
+  CHECK_OB((fdef->base->ret_type = scan1_type(env, fdef->base->td)))
   return fdef->base->args ? scan1_args(env, fdef->base->args) : GW_OK;
 }
 
@@ -314,8 +338,6 @@ ANN m_bool scan1_type_def(const Env env, const Type_Def tdef) {
 
 ANN m_bool scan1_union_def_action(const Env env, const Union_Def udef,
     const Decl_List l) {
-  if(GET_FLAG(udef, scan1))
-    return GW_OK;
   const Exp_Decl decl = l->self->d.exp_decl;
   SET_FLAG(decl.td, checked | udef->flag);
   const m_bool global = GET_FLAG(udef, global);
@@ -327,7 +349,6 @@ ANN m_bool scan1_union_def_action(const Env env, const Union_Def udef,
     SET_FLAG(decl.td, static);
   if(udef->tmpl && udef->tmpl->call)
     CHECK_BB(template_push_types(env, udef->tmpl))
-  SET_FLAG(decl.td, ref);
   const m_bool ret = scan1_exp(env, l->self);
   if(udef->tmpl && udef->tmpl->call)
     nspc_pop_type(env->gwion->mp, env->curr);
@@ -339,7 +360,6 @@ ANN m_bool scan1_union_def_action(const Env env, const Union_Def udef,
 
   if(global)
     SET_FLAG(decl.td, global);
-  union_flag(udef, ae_flag_scan1);
   return GW_OK;
 }
 
@@ -360,8 +380,7 @@ ANN m_bool scan1_union_def(const Env env, const Union_Def udef) {
   }
   const m_bool ret = scan1_union_def_inner(env, udef);
   union_pop(env, udef, scope);
-  const Type type = udef->xid || !udef->type_xid ? udef->value->type : udef->type;
-  SET_FLAG(type, scan1);
+  union_flag(udef, ae_flag_scan1);
   return ret;
 }
 
@@ -505,15 +524,15 @@ ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) {
   return ret;
 }
 
-ANN m_bool scan1_class_def(const Env env, const Class_Def c) {
-  if(tmpl_base(c->base.tmpl))
+ANN m_bool scan1_class_def(const Env env, const Class_Def cdef) {
+  if(tmpl_base(cdef->base.tmpl))
+    return GW_OK;
+  const Type t = cdef->base.type;
+  if(GET_FLAG(t, scan1))
     return GW_OK;
-  const Type t = c->base.type;
-  const Class_Def cdef = t->e->def;
-  if(GET_FLAG(t, scan1))return GW_OK;
-  SET_FLAG(cdef, scan1);
+  SET_FLAG(t, scan1);
   if(t->e->owner_class && !GET_FLAG(t->e->owner_class, scan1))
-    CHECK_BB(scan1_class_def(env, t->e->owner_class->e->def))
+    CHECK_BB(ensure_scan1(env, t->e->owner_class))
   SET_FLAG(cdef->base.type, scan1);
   if(cdef->base.ext)
     CHECK_BB(cdef_parent(env, cdef))
index 8f38e9359d62fd1eb3f9a29351420159181fd907..69b3bfeb01ac6f63d5533d1277c3dce1ed8f274a 100644 (file)
@@ -21,7 +21,7 @@ ANN static inline m_bool ensure_scan2(const Env env, const Type t) {
 
 ANN static m_bool scan2_decl(const Env env, const Exp_Decl* decl) {
   const Type t = get_type(decl->type);
-  if(!GET_FLAG(t, scan2) && t->e->def)
+  if(t->e->def && !GET_FLAG(t, scan2))
     CHECK_BB(ensure_scan2(env, t))
   Var_Decl_List list = decl->list;
   do {
@@ -276,7 +276,6 @@ ANN m_bool scan2_union_def(const Env env, const Union_Def udef) {
   const m_uint scope = union_push(env, udef);
   const m_bool ret = scan2_union_decl(env, udef->l);
   union_pop(env, udef, scope);
-  SET_FLAG(udef, scan2);
   union_flag(udef, ae_flag_scan2);
   return ret;
 }
@@ -560,7 +559,8 @@ HANDLE_SECTION_FUNC(scan2, m_bool, Env)
 
 ANN static m_bool scan2_parent(const Env env, const Class_Def cdef) {
   const Type parent = cdef->base.type->e->parent;
-  if(parent->e->def && !GET_FLAG(parent, scan2))
+//  if(parent->e->def && !GET_FLAG(parent, scan2))
+  if(!GET_FLAG(parent, scan2))
     CHECK_BB(scanx_parent(parent, scan2_cdef, env))
   if(cdef->base.ext->array)
     CHECK_BB(scan2_exp(env, cdef->base.ext->array->exp))
@@ -576,11 +576,10 @@ ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) {
   return ret;
 }
 
-ANN m_bool scan2_class_def(const Env env, const Class_Def c) {
-  if(tmpl_base(c->base.tmpl))
+ANN m_bool scan2_class_def(const Env env, const Class_Def cdef) {
+  if(tmpl_base(cdef->base.tmpl))
     return GW_OK;
-  const Type t = c->base.type;
-  const Class_Def cdef = t->e->def;
+  const Type t = cdef->base.type;
   if(GET_FLAG(t, scan2))return GW_OK;
   if(t->e->owner_class && !GET_FLAG(t->e->owner_class, scan2))
     CHECK_BB(scan2_class_def(env, t->e->owner_class->e->def))
index ae9fb3e587b7d7b6e6d2286a392ba86179a78072..a21df7ba3afb59b7a23ae49c1e006310808cc986 100644 (file)
@@ -26,11 +26,11 @@ ANN m_bool traverse_func_def(const Env env, const Func_Def def) {
 }
 
 ANN m_bool traverse_union_def(const Env env, const Union_Def def) {
-  if(!GET_FLAG(def, scan1))
+//  if(!GET_FLAG(def, scan1))
     CHECK_BB(scan1_union_def(env, def))
-  if(!GET_FLAG(def, scan2))
+//  if(!GET_FLAG(def, scan2))
   CHECK_BB(scan2_union_def(env, def))
-  if(!GET_FLAG(def, check))
+//  if(!GET_FLAG(def, check))
     CHECK_BB(check_union_def(env, def))
   return check_union_def(env, def);
 }
@@ -57,11 +57,12 @@ ANN m_bool traverse_type_def(const Env env, const Type_Def def) {
 }
 
 ANN m_bool traverse_class_def(const Env env, const Class_Def def) {
-  if(!GET_FLAG(def, scan1))
+  const Type t = def->base.type;
+  if(!GET_FLAG(t, scan1))
     CHECK_BB(scan1_class_def(env, def))
-  if(!GET_FLAG(def, scan2))
+  if(!GET_FLAG(t, scan2))
     CHECK_BB(scan2_class_def(env, def))
-  if(!GET_FLAG(def, checked))
+  if(!GET_FLAG(t, checked))
     return check_class_def(env, def);
   return GW_OK;
 }