]> Nishi Git Mirror - gwion.git/commitdiff
:art: use @scan operator
authorJérémie Astor <astor.jeremie@wanadoo.fr>
Fri, 6 Mar 2020 19:03:40 +0000 (20:03 +0100)
committerJérémie Astor <astor.jeremie@wanadoo.fr>
Fri, 6 Mar 2020 19:03:45 +0000 (20:03 +0100)
include/operator.h
include/parse.h
include/template.h
src/lib/object.c
src/lib/tuple.c
src/parse/check.c
src/parse/operator.c
src/parse/scan1.c
src/parse/template.c
src/parse/traverse.c
tests/new/dtor.gw

index a0466b5eaba957b7a03479689016e942ac8ad7b9..eae103e53cf5a15583382c7e433d5a4be2144d22 100644 (file)
@@ -27,6 +27,12 @@ struct Implicit {
   Type  t;
   loc_t pos;
 };
+
+struct TemplateScan {
+  const Type  t;
+  const Type_Decl  *td;
+};
+
 ANN m_bool add_op(const Gwion gwion, const struct Op_Import*);
 ANN Type   op_check(const Env, struct Op_Import*);
 ANN struct Instr_* op_emit(const Emitter, const struct Op_Import*);
index c9f628085fab298816337b5609ac51d6a745e63d..09f955a053264103ad311c9e7b7c40abf3c28654 100644 (file)
@@ -67,11 +67,18 @@ ANN m_bool scanx_cdef(const Env, void *,const Class_Def,
 #define xxx_cdef(prefix)                                                  \
 static inline m_bool prefix##_cdef(const Env env, const Class_Def cdef) { \
   return scanx_cdef(env, env, cdef,                                       \
-      (_exp_func)prefix##_class_def, (_exp_func)prefix##_union_def);     \
+      (_exp_func)prefix##_class_def, (_exp_func)prefix##_union_def);      \
 }
-xxx_cdef(scan1)
-xxx_cdef(scan2)
-xxx_cdef(check)
+
+#define xxx_cdef_flag(prefix)                                             \
+static inline m_bool prefix##_cdef(const Env env, const Class_Def cdef) { \
+  SET_FLAG(cdef, prefix);                                                 \
+  return scanx_cdef(env, env, cdef,                                       \
+      (_exp_func)prefix##_class_def, (_exp_func)prefix##_union_def);      \
+}
+xxx_cdef_flag(scan1)
+xxx_cdef_flag(scan2)
+xxx_cdef_flag(check)
 xxx_cdef(traverse)
 
 ANN m_bool scanx_fdef(const Env, void *, const Func_Def, const _exp_func);
index a733a99bfb003735f9144a340d6ba417b3abf123..b8db06a204bce7e1debe53dc533ef53e147ac53f 100644 (file)
@@ -1,5 +1,6 @@
 #ifndef __TEMPLATE
 #define __TEMPLATE
 ANN m_bool template_push_types(const Env, const Tmpl*);
+ANN Tmpl* mk_tmpl(const Env, const Tmpl*, const Type_List);
 #define POP_RET(a) { nspc_pop_type(env->gwion->mp, env->curr); return (a); }
 #endif
index 21d271b94cc459c5d5db3a786c7456c9a72e2c28..5c3cebf813d6de505f4558eceed3b075e1deebd6 100644 (file)
@@ -11,6 +11,7 @@
 #include "import.h"
 #include "emit.h"
 #include "traverse.h"
+#include "template.h"
 #include "parse.h"
 #include "specialid.h"
 
@@ -225,6 +226,15 @@ static GACK(gack_object) {
   INTERP_PRINTF("%p", *(M_Object*)VALUE);
 }
 
+ANN static Type scan_class(const Env env, const Type t, const Type_Decl* td);
+
+static OP_CHECK(opck_object_scan) {
+  struct TemplateScan *ts = (struct TemplateScan*)data;
+  if(ts->td->types)
+    return scan_class(env, ts->t, ts->td);
+  ERR_O(td_pos(ts->td), _("you must provide template types for type '%s'"), ts->t->name)
+}
+
 GWION_IMPORT(object) {
 const Type t_object  = gwi_mk_type(gwi, "Object", SZ_INT, NULL);
 gwi_add_type(gwi, t_object);
@@ -264,9 +274,127 @@ gwi_add_type(gwi, t_object);
   GWI_BB(gwi_oper_ini(gwi, NULL, "Object", "bool"))
   GWI_BB(gwi_oper_add(gwi, opck_unary_meta2))
   GWI_BB(gwi_oper_end(gwi, "!", IntNot))
+  GWI_BB(gwi_oper_ini(gwi, "Object", NULL, NULL))
+  GWI_BB(gwi_oper_add(gwi, opck_object_scan))
+  GWI_BB(gwi_oper_end(gwi, "@scan", NULL))
   gwi_item_ini(gwi, "@null", "null");
   gwi_item_end(gwi, 0, NULL);
   struct SpecialId_ spid = { .ck=check_this, .exec=RegPushMem, .is_const=1 };
   gwi_specialid(gwi, "this", &spid);
   return GW_OK;
 }
+struct tmpl_info {
+  const  Class_Def cdef;
+  Type_List        call;
+  struct Vector_   type;
+  struct Vector_   size;
+  uint8_t index;
+};
+
+ANN static inline size_t tmpl_set(struct tmpl_info* info, const Type t) {
+  vector_add(&info->type, (vtype)t);
+  const size_t len = strlen(t->name);
+  vector_add(&info->size, len);
+  return len;
+}
+
+ANN static ssize_t template_size(const Env env, struct tmpl_info* info) {
+  ID_List base = info->cdef->base.tmpl->list;
+  Type_List call = info->call;
+  size_t size = tmpl_set(info, info->cdef->base.type);
+  do {
+    DECL_OB(const Type, t, = known_type(env, call->td))
+    size += tmpl_set(info, t);
+  } while((call = call->next) && (base = base->next) && ++size);
+  return size + 16 + 3;
+}
+
+ANN static inline m_str tmpl_get(struct tmpl_info* info, m_str str) {
+  const Type t = (Type)vector_at(&info->type, info->index);
+  strcpy(str, t->name);
+  return str += vector_at(&info->size, info->index);
+}
+
+ANN static void template_name(struct tmpl_info* info, m_str s) {
+  m_str str = s;
+  str = tmpl_get(info, str);
+  *str++ = '<';
+  *str++ = '~';
+  const m_uint size = vector_size(&info->type);
+  for(info->index = 1; info->index < size; ++info->index) {
+    str = tmpl_get(info, str);
+    if(info->index < size - 1)
+      *str++ = ',';
+    else {
+      *str++ = '~';
+      *str++ = '>';
+    }
+  }
+  *str = '\0';
+}
+
+ANEW ANN static Symbol template_id(const Env env, const Class_Def c, const Type_List call) {
+  struct tmpl_info info = { .cdef=c, .call=call };
+  vector_init(&info.type);
+  vector_init(&info.size);
+  ssize_t sz = template_size(env, &info);
+  char name[sz];
+  if(sz > GW_ERROR)
+    template_name(&info, name);
+  vector_release(&info.type);
+  vector_release(&info.size);
+  return sz > GW_ERROR ? insert_symbol(env->gwion->st, name) : NULL;
+}
+
+ANN m_bool template_match(ID_List base, Type_List call) {
+  while((call = call->next) && (base = base->next));
+  return !call ? GW_OK : GW_ERROR;
+}
+
+ANN static Class_Def template_class(const Env env, const Class_Def def, const Type_List call) {
+  DECL_OO(const Symbol, name, = template_id(env, def, call))
+  if(env->class_def && name == insert_symbol(env->gwion->st, env->class_def->name))
+     return env->class_def->e->def;
+  const Type t = nspc_lookup_type1(env->curr, name);
+  if(t)
+    return t->e->def;
+  const Class_Def c = cpy_class_def(env->gwion->mp, def);
+  c->base.xid = name;
+  SET_FLAG(c, template | ae_flag_ref);
+  return c;
+
+}
+
+extern ANN m_bool scan0_class_def(const Env, const Class_Def);
+extern ANN m_bool scan1_class_def(const Env, const Class_Def);
+extern ANN m_bool traverse_func_def(const Env, const Func_Def);
+extern ANN m_bool traverse_class_def(const Env, const Class_Def);
+
+ANN static m_bool class2udef(const Env env, const Class_Def a, const Type t) {
+  a->union_def = new_union_def(env->gwion->mp, a->list,
+    loc_cpy(env->gwion->mp, t->e->def->pos));
+  a->union_def->type_xid = a->base.xid;
+  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;
+  return GW_OK;
+}
+
+ANN static Type scan_class(const Env env, const Type t, const Type_Decl* td) {
+  if(template_match(t->e->def->base.tmpl->list, td->types) < 0)
+   ERR_O(td->xid->pos, _("invalid template types number"))
+  DECL_OO(const Class_Def, a, = template_class(env, t->e->def, td->types))
+  if(a->base.type)
+    return a->base.type;
+  a->base.tmpl = mk_tmpl(env, t->e->def->base.tmpl, td->types);
+  if(t->e->parent !=  env->gwion->type[et_union])
+    CHECK_BO(scan0_class_def(env, a))
+  else
+    CHECK_BO(class2udef(env, a, t))
+  SET_FLAG(a->base.type, template);
+  if(GET_FLAG(t, builtin))
+    SET_FLAG(a->base.type, builtin);
+  CHECK_BO(scan1_cdef(env, a))
+  return a->base.type;
+}
index 780cd87bb9ff55e9ffa6670db194e68c6b146dce..ca97a433abfe45d40a0e81d0205d517dfde436d3 100644 (file)
@@ -416,6 +416,12 @@ static OP_EMIT(opem_at_unpack) {
   return (Instr)GW_OK;
 }
 
+ANN static Type scan_tuple(const Env env, const Type_Decl *td);
+static OP_CHECK(opck_tuple_scan) {
+  struct TemplateScan *ts = (struct TemplateScan*)data;
+  return ts->td->types ? scan_tuple(env, ts->td) : ts->t;
+}
+
 GWION_IMPORT(tuple) {
   const Type t_tuple = gwi_mk_type(gwi, "Tuple", SZ_INT, "Object");
   gwi_add_type(gwi, t_tuple);
@@ -426,6 +432,8 @@ GWION_IMPORT(tuple) {
   GWI_BB(gwi_oper_add(gwi, tuple_ck))
   GWI_BB(gwi_oper_emi(gwi, tuple_em))
   GWI_BB(gwi_oper_end(gwi, "@ctor", NULL))
+  GWI_BB(gwi_oper_add(gwi, opck_tuple_scan))
+  GWI_BB(gwi_oper_end(gwi, "@scan", NULL))
   GWI_BB(gwi_oper_ini(gwi, "Object", "Tuple", NULL))
   GWI_BB(gwi_oper_add(gwi, opck_at_object_tuple))
   GWI_BB(gwi_oper_end(gwi, "@=>", ObjectAssign))
@@ -475,3 +483,22 @@ GWION_IMPORT(tuple) {
   GWI_BB(gwi_oper_end(gwi, "==", NULL))
   return GW_OK;
 }
+
+static ANN Type scan_tuple(const Env env, const Type_Decl *td) {
+  struct Vector_ v;
+  vector_init(&v);
+  Type_List tl = td->types;
+  do {
+    const Type t = tl->td->xid->xid != insert_symbol("_") ?
+       known_type(env, tl->td) : (Type)1;
+    if(t)
+      vector_add(&v, (m_uint)t);
+    else {
+      vector_release(&v);
+      return env->gwion->type[et_null];
+    }
+  } while((tl = tl->next));
+  const Type ret = tuple_type(env, &v, td_pos(td));
+  vector_release(&v);
+  return ret;
+}
index 67eb2d15e00cf070e08c44e32f90d3336e236054..5f67e708b2942e583c3a4c6b1fe886f1d2551be6 100644 (file)
@@ -978,6 +978,8 @@ ANN static m_bool do_stmt_auto(const Env env, const Stmt_Auto stmt) {
     td.xid   = &id;
     tl.td    = &td0;
     td.types = &tl;
+    td0.xid->pos = stmt->exp->pos;
+    td.xid->pos = stmt->exp->pos;
     if(depth) {
       array.depth = depth;
       td.array = &array;
index e8a2a6535b497fd26b7577bf013d26a4fdff6a77..e83958997b6f803cf89b2eff85dfc7eaa20a57c1 100644 (file)
@@ -144,6 +144,7 @@ ANN m_bool add_op(const Gwion gwion, const struct Op_Import* opi) {
 }
 
 ANN static void set_nspc(struct OpChecker* ock, const Nspc nspc) {
+printf("here %s\n", nspc->name);
   if(ock->opi->op == insert_symbol(ock->env->gwion->st, "@array")) {
     Array_Sub array = (Array_Sub)ock->opi->data;
     array->exp->nspc = nspc;
@@ -164,7 +165,9 @@ ANN static void set_nspc(struct OpChecker* ock, const Nspc nspc) {
     ((Exp)ock->opi->data)->nspc = nspc;
     return;
   }
-  exp_self((union exp_data*)ock->opi->data)->nspc = nspc;
+// use .mut
+  if(ock->opi->op != insert_symbol(ock->env->gwion->st, "@scan"))
+    exp_self((union exp_data*)ock->opi->data)->nspc = nspc;
 }
 
 ANN static Type op_check_inner(struct OpChecker* ock) {
index 4fc66782741af4c8ed5d9cbd959721d9bea25f78..35c7b289983db7f296b982e026f11fb9c48abbf4 100644 (file)
@@ -292,6 +292,8 @@ 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);
index fb84336e07ba4f1aec2a47c534ab0060add6ba6e..0ae30a9fe2a51e2fa356ee5f06aad06489cf3d93 100644 (file)
@@ -7,7 +7,7 @@
 #include "vm.h"
 #include "parse.h"
 #include "gwion.h"
-#include "tuple.h"
+#include "operator.h"
 
 struct tmpl_info {
   const  Class_Def cdef;
@@ -17,80 +17,6 @@ struct tmpl_info {
   uint8_t index;
 };
 
-ANN static inline size_t tmpl_set(struct tmpl_info* info, const Type t) {
-  vector_add(&info->type, (vtype)t);
-  const size_t len = strlen(t->name);
-  vector_add(&info->size, len);
-  return len;
-}
-
-ANN static ssize_t template_size(const Env env, struct tmpl_info* info) {
-  ID_List base = info->cdef->base.tmpl->list;
-  Type_List call = info->call;
-  size_t size = tmpl_set(info, info->cdef->base.type);
-  do {
-    DECL_OB(const Type, t, = known_type(env, call->td))
-    size += tmpl_set(info, t);
-  } while((call = call->next) && (base = base->next) && ++size);
-  return size + 16 + 3;
-}
-
-ANN static inline m_str tmpl_get(struct tmpl_info* info, m_str str) {
-  const Type t = (Type)vector_at(&info->type, info->index);
-  strcpy(str, t->name);
-  return str += vector_at(&info->size, info->index);
-}
-
-ANN static void template_name(struct tmpl_info* info, m_str s) {
-  m_str str = s;
-  str = tmpl_get(info, str);
-  *str++ = '<';
-  *str++ = '~';
-  const m_uint size = vector_size(&info->type);
-  for(info->index = 1; info->index < size; ++info->index) {
-    str = tmpl_get(info, str);
-    if(info->index < size - 1)
-      *str++ = ',';
-    else {
-      *str++ = '~';
-      *str++ = '>';
-    }
-  }
-  *str = '\0';
-}
-
-ANEW ANN static Symbol template_id(const Env env, const Class_Def c, const Type_List call) {
-  struct tmpl_info info = { .cdef=c, .call=call };
-  vector_init(&info.type);
-  vector_init(&info.size);
-  ssize_t sz = template_size(env, &info);
-  char name[sz];
-  if(sz > GW_ERROR)
-    template_name(&info, name);
-  vector_release(&info.type);
-  vector_release(&info.size);
-  return sz > GW_ERROR ? insert_symbol(name) : NULL;
-}
-
-ANN m_bool template_match(ID_List base, Type_List call) {
-  while((call = call->next) && (base = base->next));
-  return !call ? GW_OK : GW_ERROR;
-}
-
-ANN static Class_Def template_class(const Env env, const Class_Def def, const Type_List call) {
-  DECL_OO(const Symbol, name, = template_id(env, def, call))
-  if(env->class_def && name == insert_symbol(env->class_def->name))
-     return env->class_def->e->def;
-  const Type t = nspc_lookup_type1(env->curr, name);
-  if(t)
-    return t->e->def;
-  const Class_Def c = cpy_class_def(env->gwion->mp, def);
-  c->base.xid = name;
-  SET_FLAG(c, template | ae_flag_ref);
-  return c;
-
-}
-
 ANN m_bool template_push_types(const Env env, const Tmpl *tmpl) {
   ID_List list = tmpl->list;
   Type_List call = tmpl->call;
@@ -109,65 +35,13 @@ ANN m_bool template_push_types(const Env env, const Tmpl *tmpl) {
   POP_RET(-1);
 }
 
-extern ANN m_bool scan0_class_def(const Env, const Class_Def);
-extern ANN m_bool scan1_class_def(const Env, const Class_Def);
-extern ANN m_bool traverse_func_def(const Env, const Func_Def);
-extern ANN m_bool traverse_class_def(const Env, const Class_Def);
-
-ANN Type scan_tuple(const Env env, const Type_Decl *td) {
-  struct Vector_ v;
-  vector_init(&v);
-  Type_List tl = td->types;
-  do {
-    const Type t = tl->td->xid->xid != insert_symbol("_") ?
-       known_type(env, tl->td) : (Type)1;
-    if(t)
-      vector_add(&v, (m_uint)t);
-    else {
-      vector_release(&v);
-      return NULL;
-    }
-  } while((tl = tl->next));
-  const Type ret = tuple_type(env, &v, td_pos(td));
-  vector_release(&v);
-  return ret;
-}
-
 ANN Tmpl* mk_tmpl(const Env env, const Tmpl *tm, const Type_List types) {
   Tmpl *tmpl = new_tmpl(env->gwion->mp, tm->list, 0);
   tmpl->call = cpy_type_list(env->gwion->mp, types);
   return tmpl;
 }
 
-ANN static m_bool class2udef(const Env env, const Class_Def a, const Type t) {
-  a->union_def = new_union_def(env->gwion->mp, a->list,
-    loc_cpy(env->gwion->mp, t->e->def->pos));
-  a->union_def->type_xid = a->base.xid;
-  CHECK_BB(scan0_union_def(env, a->union_def))
-  a->base.type = a->union_def->type;
-  a->base.type->e->def = a;
-  return GW_OK;
-}
-
-ANN static Type scan_class(const Env env, const Type t, const Type_Decl* td) {
-  if(template_match(t->e->def->base.tmpl->list, td->types) < 0)
-   ERR_O(td->xid->pos, _("invalid template types number"))
-  DECL_OO(const Class_Def, a, = template_class(env, t->e->def, td->types))
-  if(a->base.type)
-    return a->base.type;
-  a->base.tmpl = mk_tmpl(env, t->e->def->base.tmpl, td->types);
-  if(t->e->parent !=  env->gwion->type[et_union])
-    CHECK_BO(scan0_class_def(env, a))
-  else
-    CHECK_BO(class2udef(env, a, t))
-  SET_FLAG(a->base.type, template);
-  if(GET_FLAG(t, builtin))
-    SET_FLAG(a->base.type, builtin);
-  CHECK_BO(scan1_cdef(env, a))
-  return a->base.type;
-}
-
-ANN Type scan_func(const Env env, const Type t, const Type_Decl* td) {
+static ANN Type scan_func(const Env env, const Type t, const Type_Decl* td) {
   DECL_OO(const m_str, tl_name, = tl2str(env, td->types))
   const Symbol sym = func_symbol(env, t->e->owner->name, t->e->d.func->name, tl_name, 0);
   free_mstr(env->gwion->mp, tl_name);
@@ -194,14 +68,7 @@ ANN Type scan_func(const Env env, const Type t, const Type_Decl* td) {
   return ret;
 }
 
-ANN Type no_types(const Env env, const Type t) {
-  if(t != env->gwion->type[et_tuple])
-    ERR_O(t->e->def->pos,
-        _("you must provide template types for type '%s'"), t->name)
-  return t;
-}
-
-ANN Type maybe_func(const Env env, const Type t, const Type_Decl* td) {
+static ANN Type maybe_func(const Env env, const Type t, const Type_Decl* td) {
   if(isa(t, env->gwion->type[et_function]) > 0 && t->e->d.func->def->base->tmpl)
      return scan_func(env, t, td);
    ERR_O(td->xid->pos,
@@ -212,13 +79,10 @@ ANN Type scan_type(const Env env, const Type t, const Type_Decl* td) {
   if(GET_FLAG(t, template)) {
     if(GET_FLAG(t, ref))
       return t;
-    if(!td->types)
-      return no_types(env, t);
-     if(t->e->def)
-       return scan_class(env, t, td);
-     else
-       return scan_tuple(env, td);
-   } else if(td->types)
-     return maybe_func(env, t, td);
+    struct TemplateScan ts = { .t=t, .td=td };
+    struct Op_Import opi = { .op=insert_symbol("@scan"), .lhs=t, .data=(uintptr_t)&ts, .pos=td_pos(td) };
+    return op_check(env, &opi);
+  } else if(td->types)
+    return maybe_func(env, t, td);
   return t;
 }
index 79a13c5bf4dd13e6741bca55c7d627bb0d084850..ae9fb3e587b7d7b6e6d2286a392ba86179a78072 100644 (file)
@@ -28,7 +28,10 @@ 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))
     CHECK_BB(scan1_union_def(env, def))
+  if(!GET_FLAG(def, scan2))
   CHECK_BB(scan2_union_def(env, def))
+  if(!GET_FLAG(def, check))
+    CHECK_BB(check_union_def(env, def))
   return check_union_def(env, def);
 }
 
index d549ea5032f74d7e53950c5f6414ece5a2637772..94de83a15eada46e09691d031f2b08d399f637ff 100644 (file)
@@ -1,11 +1,11 @@
 class <~A~>C {
-  operator @dtor void { <<< __func__ >>>; }
+  operator @dtor void () { <<< __func__ >>>; }
 }
 class <~A~>D extends <~A~>C {
-  operator @dtor { <<< __func__ >>>; }
+  operator @dtor void () { <<< __func__ >>>; }
 }
 class E extends <~int~>D {
-  operator @dtor { <<< __func__ >>>; }
+  operator @dtor void () { <<< __func__ >>>; }
 }
 
 E e;