]> Nishi Git Mirror - gwion.git/commitdiff
:art: Arrat:[T]
authorJérémie Astor <fennecdjay@gmail.com>
Tue, 19 Jan 2021 14:58:29 +0000 (15:58 +0100)
committerJérémie Astor <fennecdjay@gmail.com>
Tue, 19 Jan 2021 14:58:29 +0000 (15:58 +0100)
26 files changed:
ast
include/emit.h
include/env/nspc.h
include/env/type.h
include/env/value.h
include/gwi.h
include/operator.h
src/emit/emit.c
src/env/type.c
src/import/import_cdef.c
src/import/import_checker.c
src/import/import_fdef.c
src/lib/array.c
src/lib/engine.c
src/lib/instr.c
src/lib/lib_func.c
src/lib/object.c
src/lib/object_op.c
src/lib/ptr.c
src/parse/check.c
src/parse/operator.c
src/parse/scan0.c
src/parse/scan1.c
src/parse/scan2.c
src/parse/scanx.c
src/parse/template.c

diff --git a/ast b/ast
index 21e5a7e33d5c13c56f61322c7b40fa2c6603f3b6..2b7ad3f0e5b241640e7be0576332e3fec0296662 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit 21e5a7e33d5c13c56f61322c7b40fa2c6603f3b6
+Subproject commit 2b7ad3f0e5b241640e7be0576332e3fec0296662
index a144705dca4c4927998a3ab40af0ce5b1942d756..00a88035025c901a5fe8602a26f82a13e27ab16d 100644 (file)
@@ -19,7 +19,8 @@ struct EmitterInfo_ {
   char *escape;
   VM_Code (*emit_code)(const Emitter);
   VM_Code code;
-  m_bool memoize;
+  uint memoize;
+//  uint unroll;
 };
 
 struct Emitter_ {
index 1cf9b65a651abd27033fa6c43ab508c7674b0c5e..3ea6d7e0b6e18da78054388ccbcac4fd7aef2b6f 100644 (file)
@@ -73,8 +73,8 @@ ANN void did_you_mean_type(const Type, const char*);
 #define did_you_mean_type(a, b) if(strlen(b) < DID_YOU_MEAN_LIMIT) did_you_mean_type(a,b);
 
 ANN static inline void nspc_allocdata(MemPool mp, const Nspc nspc) {
-  if(nspc->info->class_data_size)
-//    nspc->info->class_data = (m_bit*)xcalloc(1, nspc->info->class_data_size);
+  if(nspc->info->class_data_size) {
     nspc->info->class_data = (m_bit*)mp_calloc2(mp, nspc->info->class_data_size);
+  }
 }
 #endif
index 68bbec1f11e282708acb3887643531086166ba29..00283758a6cd97e806fbf4374c2931c75ea4baa7 100644 (file)
@@ -9,8 +9,8 @@ struct TypeInfo_ {
     Union_Def udef;
     Class_Def cdef;
     Func      func;
-    Type      base_type;
   };
+  Type      base_type;
   struct TupleForm_* tuple;
   struct VM_Code_ *gack;
   struct Context_ *ctx;
@@ -57,8 +57,6 @@ ANN m_bool isa(const Type, const Type) __attribute__((pure));
 ANN m_bool isres(const Env, const Symbol, const loc_t pos);
 ANN Type array_type(const Env, const Type, const m_uint);
 ANN Type find_common_anc(const Type, const Type) __attribute__((pure));
-ANN m_uint id_list_len(ID_List);
-ANN void type_path(const m_str, const ID_List);
 ANN Type typedef_base(Type) __attribute__((pure));
 ANN Type array_base(Type) __attribute__((pure));
 ANN m_bool type_ref(Type) __attribute__((pure));
@@ -66,6 +64,10 @@ ANN Type actual_type(const struct Gwion_* gwion, const Type t);
 ANN static inline m_uint env_push_type(const Env env, const Type type) { return env_push(env, type, type->nspc); }
 ANN m_bool is_fptr(const struct Gwion_*, const Type t);
 ANN m_bool is_class(const struct Gwion_*, const Type t);
+ANN __attribute__((returns_nonnull))
+static inline Type _class_base(Type t) {
+  return t->info->base_type;
+}
 ANN m_uint get_depth(const Type type);
 ANN void inherit(const Type);
 
@@ -77,13 +79,10 @@ ANN static inline Type get_gack(Type t) {
   return t; // unreachable
 }
 
-__attribute__((returns_nonnull))
-ANN Type get_type(const Type t);
-
 typedef enum {
   et_void, et_int, et_bool, et_char, et_float,
   et_error, et_compound, et_object, et_shred, et_fork, et_event, et_ugen, et_string, et_ptr, et_array, et_gack,
-  et_function, et_fptr, et_vararg, et_lambda, et_class, et_union, et_undefined, et_auto, et_none,
+  et_function, et_fptr, et_vararg, et_lambda, et_class, et_union, et_auto, et_none,
   MAX_TYPE
 } type_enum;
 #endif
index 6d8450119fa1cf5aa8acf770fab388c0c12cf38b..066cbbd774d828fd3831bbce7cdd301149a06b03 100644 (file)
@@ -19,13 +19,13 @@ enum vflag {
 //  vflag_used = 1 << 3
 } __attribute__((packed));
 
-union __attribute__((transparent_union)) value_data {
+union value_data {
   m_uint num;
   m_float fnum;
   m_uint* ptr;
   struct M_Object_ *obj;
   Func func_ref;
-} __attribute__((transparent_union));
+};
 
 struct Value_ {
   Type type;
index 08dd3f74f25b45eebd1fe5764b3139536d6b3f0b..fbac94e4873671963dc10bf9d1bee40a1ddfbfc4 100644 (file)
@@ -6,6 +6,7 @@ struct Gwi_ {
   Ast body;
   struct ImportCK *ck;
   struct OperCK *oper; // _misc
+  uint tmpls;
   loc_t loc;
 };
 
index 7f08b7fdbb7a833b66eda6d40431b75df68b0365..1ab598f0fef088579086c48339c919833e6a0115 100644 (file)
@@ -65,10 +65,8 @@ ANN static inline void operator_resume(struct Op_Import *opi) {
 }
 
 ANN static inline void set_decl_ref(const Exp e) {
-  if(e->exp_type == ae_exp_decl) {
-    SET_FLAG(e->d.exp_decl.td, late);
+  if(e->exp_type == ae_exp_decl)
     SET_FLAG(e->d.exp_decl.list->self->value, late);
-  }
 }
 
 
index 2cc84734138fcf166bd2fe007ea6387bae436d7c..d4b3924e653c6a592b1fe2d6eba00e3475156f21 100644 (file)
@@ -294,10 +294,10 @@ ANEW ANN static ArrayInfo* new_arrayinfo(const Emitter emit, const Type t) {
   const Type base = array_base(t);
   ArrayInfo* info = mp_calloc(emit->gwion->mp, ArrayInfo);
   vector_init(&info->type);
-  for(m_uint i = 1; i < t->array_depth; ++i)
+  info->depth = get_depth(t);
+  for(long i = 1; i < info->depth; ++i)
     vector_add(&info->type, (vtype)array_type(emit->env, base, i));
   vector_add(&info->type, (vtype)t);
-  info->depth = !tflag(t, tflag_typedef) ? t->array_depth : t->info->parent->array_depth;
   info->base = base;
   return info;
 }
@@ -311,7 +311,7 @@ ANN static inline void arrayinfo_ctor(const Emitter emit, ArrayInfo *info) {
 }
 
 ANN2(1,2) static ArrayInfo* emit_array_extend_inner(const Emitter emit, const Type t, const Exp e, const uint is_ref) {
-  CHECK_BO(extend_indices(emit, e, t->array_depth))
+  CHECK_BO(extend_indices(emit, e, get_depth(t)))
   ArrayInfo* info = new_arrayinfo(emit, t);
   const Instr alloc = emit_add_instr(emit, ArrayAlloc);
   alloc->m_val = (m_uint)info;
@@ -501,7 +501,7 @@ ANN static m_bool emit_prim_array(const Emitter emit, const Array_Sub *data) {
   regseti(emit, count);
   const Instr instr = emit_add_instr(emit, ArrayInit);
   instr->m_val = (m_uint)type;
-  instr->m_val2 = type->array_depth == 1 ? array_base(type)->size : SZ_INT;
+  instr->m_val2 = array_base(type)->size;
   emit_gc(emit, -SZ_INT);
   emit_notpure(emit);
   return GW_OK;
@@ -806,12 +806,11 @@ ANN static m_bool emit_class_def(const Emitter, const Class_Def);
 ANN static m_bool emit_cdef(const Emitter, const Type);
 
 ANN static inline m_bool ensure_emit(const Emitter emit, const Type t) {
-  const Type base = get_type(t);
-  if(tflag(base, tflag_emit) || !(tflag(base, tflag_cdef) || tflag(base, tflag_udef)))
+  if(tflag(t, tflag_emit) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef)))
     return GW_OK;//clean callers
   struct EnvSet es = { .env=emit->env, .data=emit, .func=(_exp_func)emit_cdef,
     .scope=emit->env->scope->depth, .flag=tflag_emit };
-  return envset_run(&es, base);
+  return envset_run(&es, t);
 }
 
 ANN static m_bool emit_decl(const Emitter emit, const Exp_Decl* decl) {
@@ -828,15 +827,15 @@ ANN static m_bool emit_decl(const Emitter emit, const Exp_Decl* decl) {
       CHECK_BB(emit_exp_decl_non_static(emit, decl, list->self, r, var))
     else
       CHECK_BB(emit_exp_decl_global(emit, decl, list->self, r, var))
-    if(GET_FLAG(v->type, abstract) && !GET_FLAG(decl->td, late) && GET_FLAG(v, late)) {
-     env_warn(emit->env, decl->td->pos, _("Type '%s' is abstract, use late"), v->type->name);
+    if(GET_FLAG(array_base(v->type), abstract) && !GET_FLAG(decl->td, late) && GET_FLAG(v, late)) {
+      env_warn(emit->env, decl->td->pos, _("Type '%s' is abstract, use late"), v->type->name);
     }
   } while((list = list->next));
   return GW_OK;
 }
 
 ANN /*static */m_bool emit_exp_decl(const Emitter emit, const Exp_Decl* decl) {
-  const Type t = get_type(decl->type);
+  const Type t = decl->type;
   CHECK_BB(ensure_emit(emit, t))
   const m_bool global = GET_FLAG(decl->td, global);
   const m_uint scope = !global ? emit->env->scope->depth : emit_push_global(emit);
@@ -1332,7 +1331,7 @@ ANN m_bool emit_exp_spork(const Emitter emit, const Exp_Unary* unary) {
 
 ANN static m_bool emit_exp_unary(const Emitter emit, const Exp_Unary* unary) {
   const Type t = exp_self(unary)->type;
-  const Type base = get_type(actual_type(emit->gwion, t));
+  const Type base = actual_type(emit->gwion, t);
   CHECK_BB(ensure_emit(emit, base))
   // no pos ?
   struct Op_Import opi = { .op=unary->op, .data=(uintptr_t)unary, .op_type=op_unary };
@@ -1435,7 +1434,7 @@ ANN static m_bool emit_exp_lambda(const Emitter emit, const Exp_Lambda * lambda)
 }
 
 ANN static m_bool emit_exp_td(const Emitter emit, Type_Decl* td) {
-  regpushi(emit, (m_uint)exp_self(td)->type->info->base_type);
+  regpushi(emit, (m_uint)_class_base(exp_self(td)->type));
   return GW_OK;
 }
 
@@ -1450,11 +1449,10 @@ ANN2(1) /*static */m_bool emit_exp(const Emitter emit, /* const */Exp e) {
       CHECK_BB(emit_implicit_cast(emit, exp, exp->cast_to))
     if(isa(e->type, emit->gwion->type[et_object]) > 0 &&
         (e->cast_to ? isa(e->cast_to, emit->gwion->type[et_object]) > 0 : 1) &&
-         e->exp_type == ae_exp_decl && GET_FLAG(e->d.exp_decl.td, late) && !exp_getvar(e)) {
+         e->exp_type == ae_exp_decl && GET_FLAG(e->d.exp_decl.td, late) && exp_getuse(e) && !exp_getvar(e)) {
       const Instr instr = emit_add_instr(emit, GWOP_EXCEPT);
       instr->m_val = -SZ_INT;
     }
-
   } while((exp = exp->next));
   return GW_OK;
 }
index ff93ad87c6d05273305a7a729b3d0796f83dce40..cb09c10ee0b41ae32fd9b6f2764ce6a7574afe6a 100644 (file)
@@ -45,7 +45,6 @@ ANN Type type_copy(MemPool p, const Type type) {
   a->info->owner       = type->info->owner;
   a->info->owner_class = type->info->owner_class;
   a->size           = type->size;
-  a->info->base_type = type->info->base_type;
   a->array_depth    = type->array_depth;
   a->info->gack        = type->info->gack;
   return a;
@@ -79,14 +78,16 @@ ANN Type typedef_base(Type t) {
 
 ANN Type array_base(Type type) {
   const Type t = typedef_base(type);
-  return t->array_depth ? t->info->base_type : t;
+//  return t->array_depth ? t->info->base_type : t;
+  return t->array_depth ? array_base(t->info->base_type) : t;
 }
 
-ANN static Symbol array_sym(const Env env, const Type src, const m_uint depth) {
-  size_t len = strlen(src->name);
+ANN /*static */Symbol array_sym(const Env env, const Type src, const m_uint depth) {
+  const Type t = array_base(src);
+  size_t len = strlen(t->name);
   char name[len + 2* depth + 1];
-  strcpy(name, src->name);
-  m_uint i = depth + 1;
+  strcpy(name, t->name);
+  m_uint i = src->array_depth + depth + 1;
   while(--i) {
     strcpy(name+len, "[]");
     len += 2;
@@ -94,29 +95,19 @@ ANN static Symbol array_sym(const Env env, const Type src, const m_uint depth) {
   return insert_symbol(name);
 }
 
+#include "instr.h"
+#include "operator.h"
+#include "import.h"
 ANN Type array_type(const Env env, const Type src, const m_uint depth) {
   const Symbol sym = array_sym(env, src, depth);
   const Type type = nspc_lookup_type1(src->info->owner, sym);
   if(type)
     return type;
-  const Type parent = src->info->parent ?
-    array_type(env, src->info->parent, depth) : env->gwion->type[et_array];
-  const Type t = new_type(env->gwion->mp, s_name(sym), parent);
-  t->array_depth = depth + src->array_depth;
-  t->info->base_type = array_base(src) ?: src;
-  t->info->owner = src->info->owner;
-  if(depth > 1 || isa(src, env->gwion->type[et_compound]) > 0) {
-    t->nspc = new_nspc(env->gwion->mp, s_name(sym));
-    inherit(t);
-    t->nspc->info->class_data_size = SZ_INT;
-    nspc_allocdata(env->gwion->mp, t->nspc);
-    *(f_release**)(t->nspc->info->class_data) = (depth > 1 || !tflag(src, tflag_struct)) ?
-      object_release : struct_release;
-  } else
-  nspc_addref((t->nspc = parent->nspc));
-  mk_class(env, t);
-  nspc_add_type_front(src->info->owner, sym, t);
-  return t;
+  const size_t tdepth = depth + src->array_depth;
+  const Type base = tdepth > 1 ? array_type(env, src, tdepth-1) : src;
+  struct TemplateScan ts = { .t=base, /*.td=td*/ };
+  struct Op_Import opi = { .op=insert_symbol("@scan"), .lhs=env->gwion->type[et_array], .data=(uintptr_t)&ts, .op_type=op_scan };
+  return op_check(env, &opi);
 }
 
 ANN m_bool type_ref(Type t) {
index 8d93641681569fc75537930ee4e399c9d40dd266..6ca93ef0041f03806af8e9998ce97975e904e881 100644 (file)
@@ -36,6 +36,16 @@ ANN2(1,2) static void import_class_ini(const Env env, const Type t) {
   env_push_type(env, t);
 }
 
+ANN2(1) void add_template(const Env env, const Type t) {
+  Tmpl* tmpl = t->info->cdef->base.tmpl;
+  if(tmpl) {
+    nspc_push_type(env->gwion->mp, env->curr);//
+    ID_List il = tmpl->list;
+    do nspc_add_type(env->curr, il->xid, env->gwion->type[et_auto]);
+    while((il = il->next));
+  }
+}
+
 ANN2(1) void gwi_class_xtor(const Gwi gwi, const f_xtor ctor, const f_xtor dtor) {
   const Type t = gwi->gwion->env->class_def;
   if(ctor)
@@ -51,6 +61,10 @@ ANN static inline void gwi_type_flag(const Type t) {
 ANN static Type type_finish(const Gwi gwi, const Type t) {
   gwi_add_type(gwi, t);
   import_class_ini(gwi->gwion->env, t);
+  if(t->info->cdef && t->info->cdef->base.tmpl) {
+    gwi->tmpls++;
+    add_template(gwi->gwion->env, t);
+  }
   return t;
 }
 
@@ -108,6 +122,11 @@ ANN m_int gwi_class_end(const Gwi gwi) {
   if(!gwi->gwion->env->class_def)
     GWI_ERR_B(_("import: too many class_end called."))
   nspc_allocdata(gwi->gwion->mp, gwi->gwion->env->class_def->nspc);
+  const Type t = gwi->gwion->env->class_def;
+  if(tflag(t, tflag_tmpl)) {
+    --gwi->tmpls;
+    nspc_pop_type(gwi->gwion->mp, gwi->gwion->env->curr);
+  }
   env_pop(gwi->gwion->env, 0);
   return GW_OK;
 }
index 1fbfc6b8daa1b3899b64e534ef115e00b21a61da..3e46de7901f31990e4f9fc7078103d4cdc6a3958 100644 (file)
@@ -245,8 +245,10 @@ ANN static m_bool td_info_run(const Env env, struct td_info* info) {
 
 ANEW ANN m_str type2str(const Gwion gwion, const Type t, const loc_t pos NUSED) {
   GwText text = { .mp=gwion->mp };
-  if(t->info->owner_class)
+  if(t->info->owner_class) {
     td_fullname(gwion->env, &text, t->info->owner_class);
+    text_add(&text, ".");
+  }
   text_add(&text, t->name);
   return text.str;
 }
index f8b39276a7c93855f83cdc4c4f9bdc1e2a6d202e..8ecb4cbec3ad7345a3f29d9e2fc9b70c16207624 100644 (file)
@@ -72,11 +72,10 @@ ANN static m_bool error_fdef(const Gwi gwi, const Func_Def fdef) {
 ANN m_int gwi_func_valid(const Gwi gwi, ImportCK *ck) {
   const Func_Def fdef = import_fdef(gwi, ck);
   if(safe_tflag(gwi->gwion->env->class_def, tflag_tmpl))
-    /*return*/ section_fdef(gwi, fdef);
+    return section_fdef(gwi, fdef);
   if(traverse_func_def(gwi->gwion->env, fdef) < 0)
     return error_fdef(gwi, fdef);
   builtin_func(gwi->gwion->mp, fdef->base->func, ck->addr);
-  ck_end(gwi);
   return GW_OK;
 }
 
@@ -84,9 +83,9 @@ ANN m_int gwi_func_end(const Gwi gwi, const f_xfun addr, const ae_flag flag) {
   CHECK_BB(ck_ok(gwi, ck_fdef))
   gwi->ck->addr = addr;
   gwi->ck->flag = flag;
-  if(gwi_func_valid(gwi, gwi->ck) > 0)
-    return GW_OK;
-  return GW_ERROR;
+  const m_bool ret = gwi_func_valid(gwi, gwi->ck);
+  ck_end(gwi);
+  return ret;
 }
 
 ANN m_int gwi_func_arg(const Gwi gwi, const restrict m_str t, const restrict m_str n) {
index ddcdf9c9a4f8b3f69ac9fd6ea463b97da623837b..d5a1a13b450930656358360dee6bb0364b5cb037 100644 (file)
@@ -48,24 +48,29 @@ void free_m_vector(MemPool p, M_Vector a) {
 }
 
 static DTOR(array_dtor) {
-  const Type t = o->type_ref;
   if(*(void**)(o->data + SZ_INT))
     xfree(*(void**)(o->data + SZ_INT));
   struct M_Vector_* a = ARRAY(o);
-  if(!a)
-    return;
-  if(t->nspc->info->class_data_size) {
-    for(m_uint i = 0; i < ARRAY_LEN(a); ++i)
-      (*(f_release**)t->nspc->info->class_data)(shred, array_base(t), ARRAY_PTR(a) + i * ARRAY_SIZE(a));
-  }
   free_m_vector(shred->info->mp, a);
 }
 
+static DTOR(array_dtor_obj) {
+  struct M_Vector_* a = ARRAY(o);
+  for(m_uint i = 0; i < ARRAY_LEN(a); ++i)
+    release(*(M_Object*)(ARRAY_PTR(a) + i * SZ_INT), shred);
+}
+
+static DTOR(array_dtor_struct) {
+  struct M_Vector_* a = ARRAY(o);
+  for(m_uint i = 0; i < ARRAY_LEN(a); ++i)
+    struct_release(shred, array_base(o->type_ref), &*(m_bit*)(ARRAY_PTR(a) + i * SZ_INT));
+}
+
 ANN M_Object new_array(MemPool p, const Type t, const m_uint length) {
   const M_Object a = new_object(p, NULL, t);
   const m_uint depth = !tflag(t, tflag_typedef) ? t->array_depth : t->info->parent->array_depth;
   const m_uint size = depth > 1 ? SZ_INT : array_base(t)->size;
-  ARRAY(a) = new_m_vector(p, size,length);
+  ARRAY(a) = new_m_vector(p, size, length);
   return a;
 }
 
@@ -111,16 +116,76 @@ ANN void m_vector_rem(const M_Vector v, m_uint index) {
 }
 
 static MFUN(vm_vector_rem) {
+  const m_int index = *(m_int*)(shred->mem + SZ_INT);
+  const M_Vector v = ARRAY(o);
+  if(index < 0 || (m_uint)index >= ARRAY_LEN(v))
+    return;
+  m_vector_rem(v, (vtype)index);
+}
+
+static MFUN(vm_vector_rem_obj) {
+  const m_int index = *(m_int*)(shred->mem + SZ_INT);
+  const M_Vector v = ARRAY(o);
+  if(index < 0 || (m_uint)index >= ARRAY_LEN(v))
+    return;
+  release(*(M_Object*)(ARRAY_PTR(v) + index * ARRAY_SIZE(v)), shred);
+  m_vector_rem(v, (vtype)index);
+}
+
+static MFUN(vm_vector_rem_struct) {
   const m_int index = *(m_int*)(shred->mem + SZ_INT);
   const M_Vector v = ARRAY(o);
   if(index < 0 || (m_uint)index >= ARRAY_LEN(v))
     return;
   const Type t = o->type_ref;
-  if(t->nspc->info->class_data_size)
-    (*(f_release**)t->nspc->info->class_data)(shred, array_base(t), ARRAY_PTR(v) + index * ARRAY_SIZE(v));
+  struct_release(shred, array_base(t), ARRAY_PTR(v) + index * ARRAY_SIZE(v));
   m_vector_rem(v, (vtype)index);
 }
 
+static MFUN(vm_vector_insert) {
+  const m_int index = *(m_int*)(shred->mem + SZ_INT);
+  const M_Vector v = ARRAY(o);
+  if(index < 0 || (m_uint)index > ARRAY_LEN(v))
+    return;
+  const size_t size = ARRAY_SIZE(v);
+  if(++ARRAY_LEN(v) >= ARRAY_CAP(v)) {
+    const m_uint cap = ARRAY_CAP(v) *=2;
+    v->ptr = (m_bit*)xrealloc(v->ptr, ARRAY_OFFSET + cap * size);
+  }
+  memmove(ARRAY_PTR(v) + (index+1) * size, ARRAY_PTR(v) + index*size, (ARRAY_LEN(v) - index + 1)* size);
+  memcpy(ARRAY_PTR(v) + index*size, shred->mem + SZ_INT*2, size);
+}
+
+static MFUN(vm_vector_insert_obj) {
+  const m_int index = *(m_int*)(shred->mem + SZ_INT);
+  const M_Vector v = ARRAY(o);
+  if(index < 0 || (m_uint)index > ARRAY_LEN(v))
+    return;
+  const size_t size = SZ_INT;
+  if(++ARRAY_LEN(v) >= ARRAY_CAP(v)) {
+    const m_uint cap = ARRAY_CAP(v) *=2;
+    v->ptr = (m_bit*)xrealloc(v->ptr, ARRAY_OFFSET + cap * size);
+  }
+  memmove(ARRAY_PTR(v) + (index+1) *size, ARRAY_PTR(v) + index*size, (ARRAY_LEN(v) - index + 1)* size);
+  memcpy(ARRAY_PTR(v) + index*size, shred->mem + SZ_INT*2, size);
+  ++(*(M_Object*)(shred->mem + SZ_INT*2))->ref;
+}
+
+static MFUN(vm_vector_insert_struct) {
+  const m_int index = *(m_int*)(shred->mem + SZ_INT);
+  const M_Vector v = ARRAY(o);
+  if(index < 0 || (m_uint)index > ARRAY_LEN(v))
+    return;
+  const size_t size = ARRAY_SIZE(v);
+  if(++ARRAY_LEN(v) >= ARRAY_CAP(v)) {
+    const m_uint cap = ARRAY_CAP(v) *=2;
+    v->ptr = (m_bit*)xrealloc(v->ptr, ARRAY_OFFSET + cap * size);
+  }
+  memmove(ARRAY_PTR(v) + (index+1) *size, ARRAY_PTR(v) + index*size, (ARRAY_LEN(v) - index + 1)* size);
+  memcpy(ARRAY_PTR(v) + index*size, shred->mem + SZ_INT*2, size);
+  struct_addref(shred->info->vm->gwion, array_base(o->type_ref),  shred->mem + SZ_INT*2);
+}
+
 ANN m_bit* m_vector_addr(const M_Vector v, const m_uint i) {
   return &*(m_bit*)(ARRAY_PTR(v) + i * ARRAY_SIZE(v));
 }
@@ -137,16 +202,10 @@ static MFUN(vm_vector_cap) {
   *(m_uint*)RETURN = ARRAY_CAP(ARRAY(o));
 }
 
-ANN static Type get_array_type(Type t) {
-  while(t->array_depth && t->info->base_type)
-    t = t->info->base_type;
-  return t;
-}
-
 #define ARRAY_OPCK(a, b, pos)                  \
-  const Type l = get_array_type(a->type);      \
-  const Type r = get_array_type(b->type);      \
-  if(isa(l, r) < 0)                            \
+  const Type l = array_base(a->type);          \
+  const Type r = array_base(b->type);          \
+  if(isa(r, l) < 0)                            \
     ERR_N(pos, _("array types do not match."))
 
 static OP_CHECK(opck_array_at) {
@@ -169,9 +228,9 @@ static OP_CHECK(opck_array_at) {
 
 ANN static Type check_array_shift(const Env env,
     const Exp a, const Exp b, const m_str str, const loc_t pos) {
-  if(a->type == env->gwion->type[et_error] &&
+/*  if(a->type == env->gwion->type[et_error] &&
       b->type->array_depth > 1)
-    return a->type;
+    return a->type;*/
   ARRAY_OPCK(a, b, pos)
   if(a->type->array_depth == b->type->array_depth + 1)
     return a->type;
@@ -264,8 +323,8 @@ static OP_EMIT(opem_array_sl) {
 // check me. use common ancestor maybe
 static OP_CHECK(opck_array_cast) {
   const Exp_Cast* cast = (Exp_Cast*)data;
-  Type l = array_base(cast->exp->type);
-  Type r = array_base(exp_self(cast)->type);
+  const Type l = array_base(cast->exp->type);
+  const Type r = array_base(exp_self(cast)->type);
   if(get_depth(cast->exp->type) == get_depth(exp_self(cast)->type) && isa(l->info->base_type, r->info->base_type) > 0)
     return l;
   return NULL;
@@ -389,8 +448,66 @@ static OP_EMIT(opem_array_access) {
   return exp ? emit_array_access(emit, info) : GW_ERROR;
 }
 
+ANN /*static */Symbol array_sym(const Env env, const Type src, const m_uint depth);
+#include "template.h"
+static OP_CHECK(opck_array_scan) {
+  struct TemplateScan *ts = (struct TemplateScan*)data;
+  const Type t_array = env->gwion->type[et_array];
+  const Class_Def c = t_array->info->cdef;
+  const Type base = ts->t != t_array ?
+    ts->t : known_type(env, ts->td->types->td);
+  const Symbol sym = array_sym(env, array_base(base), base->array_depth + 1);
+  const Type type = nspc_lookup_type1(base->info->owner, sym);
+  if(type)
+    return type;
+  const Class_Def cdef = cpy_class_def(env->gwion->mp, c);
+  cdef->base.ext = type2td(env->gwion, t_array, (loc_t){});
+  cdef->base.xid = sym;
+  cdef->base.tmpl->base = 1; // could store depth here?
+  cdef->base.tmpl->call = new_type_list(env->gwion->mp, type2td(env->gwion, base, (loc_t){}), NULL);
+  const m_uint scope = env_push(env, NULL, base->info->owner);
+  (void)scan0_class_def(env, cdef);
+  const Type t = cdef->base.type;
+  (void)traverse_cdef(env, t);
+  env_pop(env, scope);
+  if(GET_FLAG(base, abstract))
+    SET_FLAG(t, abstract);
+  else
+    UNSET_FLAG(t, abstract);
+  set_tflag(t, tflag_emit);
+  t->array_depth = base->array_depth + 1;
+  t->info->base_type = array_base(base);
+  set_tflag(t, tflag_cdef | tflag_tmpl);
+  void* rem = isa(base, env->gwion->type[et_compound]) > 0 ?
+    !tflag(base, tflag_struct) ? vm_vector_rem_obj : vm_vector_rem_struct : vm_vector_rem;
+  builtin_func(env->gwion->mp, (Func)vector_at(&t->nspc->info->vtable, 0), rem);
+  void* insert = isa(base, env->gwion->type[et_compound]) > 0 ?
+    !tflag(base, tflag_struct) ? vm_vector_insert_obj : vm_vector_insert_struct : vm_vector_insert;
+  builtin_func(env->gwion->mp, (Func)vector_at(&t->nspc->info->vtable, 1), insert);
+  builtin_func(env->gwion->mp, (Func)vector_at(&t->nspc->info->vtable, 2), vm_vector_size);
+  builtin_func(env->gwion->mp, (Func)vector_at(&t->nspc->info->vtable, 3), vm_vector_depth);
+  builtin_func(env->gwion->mp, (Func)vector_at(&t->nspc->info->vtable, 4), vm_vector_cap);
+  if(isa(base, env->gwion->type[et_compound]) > 0) {
+    t->nspc->dtor = new_vmcode(env->gwion->mp, NULL, SZ_INT, 1, "array component dtor");
+    set_tflag(t, tflag_dtor);
+    t->nspc->dtor->native_func = (m_uint) (!tflag(base, tflag_struct) ?
+        array_dtor_obj : array_dtor_struct);
+  }
+  unset_tflag(t, tflag_ctor);
+  return t;
+}
+
+static OP_CHECK(opck_array_implicit) {
+  const struct Implicit* imp = (struct Implicit*)data;
+  if(imp->t->array_depth != imp->e->type->array_depth)
+    return env->gwion->type[et_error];
+  if(isa(array_base(imp->e->type), array_base(imp->t)) < 0)
+    return env->gwion->type[et_error];
+  return imp->t;
+}
+
 GWION_IMPORT(array) {
-  const Type t_array  = gwi_class_ini(gwi, "@Array", NULL);
+  const Type t_array  = gwi_class_ini(gwi, "Array:[T]", "Object");
   gwi->gwion->type[et_array] = t_array;
   gwi_class_xtor(gwi, NULL, array_dtor);
   GWI_BB(gwi_item_ini(gwi, "@internal", "@array"))
@@ -398,6 +515,16 @@ GWION_IMPORT(array) {
   GWI_BB(gwi_item_ini(gwi, "@internal", "@ctor_data"))
   GWI_BB(gwi_item_end(gwi, 0, num, 0))
 
+  // put functions using T first
+  GWI_BB(gwi_func_ini(gwi, "bool", "remove"))
+  GWI_BB(gwi_func_arg(gwi, "int", "index"))
+  GWI_BB(gwi_func_end(gwi, vm_vector_rem, ae_flag_none))
+
+  GWI_BB(gwi_func_ini(gwi, "bool", "insert"))
+  GWI_BB(gwi_func_arg(gwi, "int", "index"))
+  GWI_BB(gwi_func_arg(gwi, "T", "data"))
+  GWI_BB(gwi_func_end(gwi, vm_vector_insert, ae_flag_none))
+
   GWI_BB(gwi_func_ini(gwi, "int", "size"))
   GWI_BB(gwi_func_end(gwi, vm_vector_size, ae_flag_none))
   GWI_BB(gwi_func_ini(gwi, "int", "depth"))
@@ -406,33 +533,34 @@ GWION_IMPORT(array) {
   GWI_BB(gwi_func_ini(gwi, "int", "cap"))
   GWI_BB(gwi_func_end(gwi, vm_vector_cap, ae_flag_none))
 
-  GWI_BB(gwi_func_ini(gwi, "int", "remove"))
-  GWI_BB(gwi_func_arg(gwi, "int", "index"))
-  GWI_BB(gwi_func_end(gwi, vm_vector_rem, ae_flag_none))
-
   GWI_BB(gwi_class_end(gwi))
-  GWI_BB(gwi_oper_ini(gwi, "@Array", "@Array", NULL))
+  GWI_BB(gwi_oper_ini(gwi, "Array", "Array", NULL))
   GWI_BB(gwi_oper_add(gwi, opck_array_at))
   GWI_BB(gwi_oper_end(gwi, "@=>", NULL))
-  GWI_BB(gwi_oper_ini(gwi, "@Array", (m_str)OP_ANY_TYPE, NULL))
+  GWI_BB(gwi_oper_add(gwi, opck_array_implicit))
+  GWI_BB(gwi_oper_end(gwi, "@implicit", NULL))
+  GWI_BB(gwi_oper_ini(gwi, "Array", (m_str)OP_ANY_TYPE, NULL))
   GWI_BB(gwi_oper_add(gwi, opck_array_sl))
   GWI_BB(gwi_oper_emi(gwi, opem_array_sl))
   GWI_BB(gwi_oper_end(gwi, "<<", NULL))
-  GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "@Array", NULL))
+  GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "Array", NULL))
   GWI_BB(gwi_oper_add(gwi, opck_array_sr))
   GWI_BB(gwi_oper_emi(gwi, opem_array_sr))
   GWI_BB(gwi_oper_end(gwi, ">>", NULL))
-  GWI_BB(gwi_oper_ini(gwi, "@Array", "@Array", NULL))
+  GWI_BB(gwi_oper_ini(gwi, "Array", "Array", NULL))
   GWI_BB(gwi_oper_add(gwi, opck_array_cast))
   GWI_BB(gwi_oper_end(gwi, "$", NULL))
-  GWI_BB(gwi_oper_ini(gwi, "int", "@Array", "int"))
+  GWI_BB(gwi_oper_ini(gwi, "int", "Array", "int"))
   GWI_BB(gwi_oper_add(gwi, opck_array_slice))
   GWI_BB(gwi_oper_emi(gwi, opem_array_slice))
   GWI_BB(gwi_oper_end(gwi, "@slice", NULL))
-  GWI_BB(gwi_oper_ini(gwi, "int", "@Array", NULL))
+  GWI_BB(gwi_oper_ini(gwi, "int", "Array", NULL))
   GWI_BB(gwi_oper_add(gwi, opck_array))
   GWI_BB(gwi_oper_emi(gwi, opem_array_access))
   GWI_BB(gwi_oper_end(gwi, "@array", NULL))
+  GWI_BB(gwi_oper_ini(gwi, "Array", NULL, NULL))
+  GWI_BB(gwi_oper_add(gwi, opck_array_scan))
+  GWI_BB(gwi_oper_end(gwi, "@scan", NULL))
   gwi_register_freearg(gwi, ArrayAlloc, freearg_array);
   return GW_OK;
 }
index ec85614c9cd439fb3acd21c09a17976a565b8c11..a4e6d33672d24a03a5ea9c6403d195799bf52a46 100644 (file)
@@ -79,8 +79,6 @@ ANN static m_bool import_core_libs(const Gwi gwi) {
   GWI_BB(gwi_set_global_type(gwi, t_class, et_class))
   GWI_BB(gwi_gack(gwi, t_class, gack_class))
 
-  const Type t_undefined = gwi_mk_type(gwi, "@Undefined", SZ_INT, NULL);
-  GWI_BB(gwi_set_global_type(gwi, t_undefined, et_undefined))
   const Type t_auto = gwi_mk_type(gwi, "auto", SZ_INT, NULL);
   set_tflag(t_auto, tflag_infer);
   GWI_BB(gwi_set_global_type(gwi, t_auto, et_auto))
@@ -110,7 +108,7 @@ ANN static m_bool import_core_libs(const Gwi gwi) {
   struct SpecialId_ spid = { .type=t_now, .exec=RegPushNow, .is_const=1 };
   gwi_specialid(gwi, "now", &spid);
 
-  const Type t_compound = gwi_mk_type(gwi, "@Compound", 0, NULL);
+  const Type t_compound = gwi_mk_type(gwi, "@Compound", SZ_INT, NULL);
   GWI_BB(gwi_gack(gwi, t_compound, gack_compound))
   GWI_BB(gwi_set_global_type(gwi, t_compound, et_compound))
 
index f022ddb1adc1ebd72ea087cec5771cc8431a4cbc..c4f63f43ee72ccfd9f2cc886cb5e34b27f2961bc 100644 (file)
@@ -27,7 +27,7 @@ ANN static Func_Def from_base(const Env env, struct dottmpl_ *const dt, const Ns
   const Symbol sym = func_symbol(env, nspc->name, s_name(fdef->base->xid),
     "template", dt->base->base->tmpl->base);
   DECL_OO(const Value, v, = nspc_lookup_value0(nspc, sym) ?: nspc_lookup_value0(nspc, fdef->base->xid))
-  if(isa(v->type, env->gwion->type[et_class]) > 0)
+  if(is_class(env->gwion, v->type))
     return NULL;
   if(vflag(v, vflag_builtin)) {
     dt->xfun = v->d.func_ref->def->d.dl_func_ptr;
index 55ba5e94fa3f933859444c72e189f446657fdc8b..6ea745ec04d83d4d35420e63b9316b782c097ffc 100644 (file)
@@ -56,8 +56,8 @@ ANN static m_bool fptr_tmpl_push(const Env env, struct FptrInfo *info) {
           t1 = info->rhs->def->base->tmpl->list;
   nspc_push_type(env->gwion->mp, env->curr);
   while(t0) {
-    nspc_add_type(env->curr, t0->xid, env->gwion->type[et_undefined]);
-    nspc_add_type(env->curr, t1->xid, env->gwion->type[et_undefined]);
+    nspc_add_type(env->curr, t0->xid, env->gwion->type[et_auto]);
+    nspc_add_type(env->curr, t1->xid, env->gwion->type[et_auto]);
     t0 = t0->next;
     t1 = t1->next;
   }
index fcea517f19e45dc5d05c71ff6dea8f2d4f089c92..be66223d3d8bb532617e25cde56604284e44a870 100644 (file)
@@ -76,8 +76,7 @@ ANN void __release(const M_Object o, const VM_Shred shred) {
           compound_release(shred, v->type, o->data + v->from->offset);
       }
     }
-    if(tflag(t, tflag_dtor) && t->nspc->dtor) {
-    // check flag for array types
+    if(tflag(t, tflag_dtor)) {
       if(t->nspc->dtor->builtin)
         ((f_xtor)t->nspc->dtor->native_func)(o, NULL, shred);
       else {
index 5d88e83e61a7fff947723553708b24410bb2169a..5daf42e4fd0f59000424616eea4d19c6098adad5 100644 (file)
@@ -56,15 +56,6 @@ static OP_CHECK(opck_object_cast) {
   return exp_self(cast)->type;
 }
 
-static OP_CHECK(opck_implicit_null2obj) {
-  const struct Implicit* imp = (struct Implicit*)data;
-  return imp->t;
-}
-
-static OP_EMIT(opem_implicit_null2obj) {
-  return GW_OK;
-}
-
 ANN /*static*/ Type scan_class(const Env env, const Type t, const Type_Decl * td);
 
 static Type opck_object_scan(const Env env, const struct TemplateScan *ts) {
@@ -162,7 +153,7 @@ OP_CHECK(opck_object_dot) {
   const Exp_Dot *member = (Exp_Dot*)data;
   const m_str str = s_name(member->xid);
   const m_bool base_static = is_class(env->gwion, member->base->type);
-  const Type the_base = base_static ? member->base->type->info->base_type : member->base->type;
+  const Type the_base = base_static ? _class_base(member->base->type) : member->base->type;
 //  if(!the_base->nspc)
 //    ERR_N(&member->base->pos,
 //          _("type '%s' does not have members - invalid use in dot expression of %s"),
@@ -231,7 +222,7 @@ OP_EMIT(opem_object_dot) {
 ANN static m_bool scantmpl_class_def(const Env env, struct tmpl_info *info) {
   const Class_Def c = info->base->info->cdef;
   const Class_Def cdef = new_class_def(env->gwion->mp, c->flag, info->name, c->base.ext ? cpy_type_decl(env->gwion->mp, c->base.ext) : NULL,
-      c->body ?cpy_ast(env->gwion->mp, c->body) : NULL, c->pos);
+      c->body ? cpy_ast(env->gwion->mp, c->body) : NULL, c->pos);
   cdef->cflag = c->cflag;
   cdef->base.tmpl = mk_tmpl(env, c->base.tmpl, info->td->types);
   const m_bool ret = scan0_class_def(env, cdef);
@@ -325,9 +316,9 @@ GWION_IMPORT(object_op) {
   GWI_BB(gwi_oper_end(gwi, "!=", NeqObject))
   GWI_BB(gwi_oper_add(gwi, opck_object_cast))
   GWI_BB(gwi_oper_end(gwi, "$", NULL))
-  GWI_BB(gwi_oper_add(gwi, opck_implicit_null2obj))
-  GWI_BB(gwi_oper_emi(gwi, opem_implicit_null2obj))
-  GWI_BB(gwi_oper_end(gwi, "@implicit", NULL))
+//.  GWI_BB(gwi_oper_add(gwi, opck_implicit_null2obj))
+//  GWI_BB(gwi_oper_emi(gwi, opem_implicit_null2obj))
+//  GWI_BB(gwi_oper_end(gwi, "@implicit", NULL))
   GWI_BB(gwi_oper_ini(gwi, NULL, "Object", "bool"))
   GWI_BB(gwi_oper_emi(gwi, opem_not_object))
   GWI_BB(gwi_oper_end(gwi, "!", IntNot))
index 896c3cdb6fc8e90a0a86f2f4b2768bf9fc61b0d7..7f2ac1c9cf9d96a85ef5156ffb6c32d4d2ecace8 100644 (file)
@@ -63,9 +63,8 @@ static OP_CHECK(opck_ptr_cast) {
   if(!cast->td->types || !cast->td->types->td)
     ERR_N(exp_self(cast)->pos, "'Ptr' needs types to cast")
   DECL_ON(const Type, t, = known_type(env, cast->td))
-  const Type _t = get_type(t);
-  if(_t->info->cdef && !tflag(_t, tflag_check))
-    CHECK_BN(ensure_traverse(env, _t))
+  if(t->info->cdef && !tflag(t, tflag_check))
+    CHECK_BN(ensure_traverse(env, t))
   const Type to = known_type(env, cast->td->types->td);
   exp_setvar(cast->exp, 1);
   if(isa(cast->exp->type, to) > 0)
@@ -82,7 +81,7 @@ static OP_CHECK(opck_ptr_implicit) {
     if(access)
       ERR_N(e->pos, _("can't cast %s value to Ptr"), access);
     exp_setvar(e, 1);
-    const Type t = get_type(imp->t);
+    const Type t = imp->t;
     if(!tflag(t, tflag_check))
       CHECK_BN(traverse_class_def(env, t->info->cdef))
     return imp->t;
index fb2a0cfab6f72480799f811215d58becba2272c7..7680c1bb2ed966d4a9725f06c36ca6b7275afb68 100644 (file)
@@ -103,9 +103,11 @@ ANN static m_bool check_var_td(const Env env, const Var_Decl var, Type_Decl *con
   return GW_OK;
 }
 
-ANN static void set_late(const Gwion gwion, const Exp_Decl *decl, const Value v) {
-  if(!exp_getvar(exp_self(decl)) && (GET_FLAG(v->type, abstract) ||
-      GET_FLAG(decl->td, late) || is_fptr(gwion, v->type))) {
+ANN static void set_late(const Gwion gwion, const Exp_Decl *decl, const Var_Decl var) {
+  const Value v = var->value;
+  const uint array_ref = (decl->td->array && !decl->td->array->exp) || (var->array && !var->array->exp);
+  if(!exp_getvar(exp_self(decl)) && (GET_FLAG(array_base(v->type), abstract) ||
+      GET_FLAG(decl->td, late) || is_fptr(gwion, v->type) || array_ref)) {
     SET_FLAG(v, late);
   } else
     UNSET_FLAG(v, late);
@@ -119,7 +121,7 @@ ANN static m_bool check_decl(const Env env, const Exp_Decl *decl) {
     CHECK_BB(check_var_td(env, var, decl->td))
     if(is_fptr(env->gwion, decl->type))
       CHECK_BB(check_fptr_decl(env, var))
-    set_late(env->gwion, decl, list->self->value);
+    set_late(env->gwion, decl, list->self);
     set_vflag(var->value, vflag_valid);
     //set_vflag(var->value, vflag_used));
     nspc_add_value(env->curr, var->xid, var->value);
@@ -128,21 +130,19 @@ ANN static m_bool check_decl(const Env env, const Exp_Decl *decl) {
 }
 
 ANN static inline m_bool ensure_check(const Env env, const Type t) {
-  const Type base = get_type(t);
-  if(tflag(base, tflag_check) || !(tflag(base, tflag_cdef) || tflag(base, tflag_udef)))
+  if(tflag(t, tflag_check) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef)))
     return GW_OK;
   struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)check_cdef,
     .scope=env->scope->depth, .flag=tflag_check };
-  return envset_run(&es, base);
+  return envset_run(&es, t);
 }
 
 ANN m_bool ensure_traverse(const Env env, const Type t) {
-  const Type base = get_type(t);
-  if(tflag(base, tflag_check) || !(tflag(base, tflag_cdef) || tflag(base, tflag_udef)))
+  if(tflag(t, tflag_check) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef)))
     return GW_OK;
   struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)traverse_cdef,
     .scope=env->scope->depth, .flag=tflag_check };
-  return envset_run(&es, base);
+  return envset_run(&es, t);
 }
 
 ANN static inline m_bool inferable(const Env env, const Type t, const loc_t pos) {
@@ -161,9 +161,8 @@ ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) {
   if(!decl->type)
     ERR_O(decl->td->pos, _("can't find type"));
   {
-    const Type t = get_type(decl->type);
-    CHECK_BO(inferable(env, t, decl->td->pos))
-    CHECK_BO(ensure_check(env, t))
+    CHECK_BO(inferable(env, decl->type, decl->td->pos))
+    CHECK_BO(ensure_check(env, decl->type))
   }
   const m_bool global = GET_FLAG(decl->td, global);
   const m_uint scope = !global ? env->scope->depth : env_push_global(env);
@@ -438,7 +437,7 @@ ANN2(1,2) static Func find_func_match_actual(const Env env, Func func, const Exp
         CHECK_OO(func->next);
         return find_func_match_actual(env, func->next, args, implicit, specific);
       }
-      if(e1->type == env->gwion->type[et_undefined] ||
+      if(e1->type == env->gwion->type[et_auto] ||
             (func->def->base->tmpl && is_fptr(env->gwion, func->value_ref->type) > 0)) {
         const Type owner = func->value_ref->from->owner_class;
         if(owner)
@@ -720,6 +719,8 @@ ANN static Type check_exp_binary(const Env env, const Exp_Binary* bin) {
   const Type ret = op_check(env, &opi);
   if(!ret && is_auto && exp_self(bin)->exp_type == ae_exp_binary)
     bin->rhs->d.exp_decl.list->self->value->type = env->gwion->type[et_auto];
+  exp_setuse(bin->lhs, 1);
+  exp_setuse(bin->rhs, 1);
   return ret;
 }
 
@@ -735,6 +736,7 @@ ANN static Type check_exp_post(const Env env, const Exp_Postfix* post) {
   struct Op_Import opi = { .op=post->op, .lhs=check_exp(env, post->exp),
     .data=(uintptr_t)post, .pos=exp_self(post)->pos, .op_type=op_postfix };
   CHECK_OO(opi.lhs)
+  exp_setuse(post->exp, 1);
   const Type t = op_check(env, &opi);
   if(t && isa(t, env->gwion->type[et_object]) < 0)
     exp_setmeta(exp_self(post), 1);
@@ -784,12 +786,14 @@ ANN static Type check_exp_call(const Env env, Exp_Call* exp) {
 
 ANN static Type check_exp_unary(const Env env, const Exp_Unary* unary) {
   const Type rhs = unary->unary_type == unary_exp ? check_exp(env, unary->exp) : NULL;
-  if(unary->unary_type == unary_exp)
+  if(unary->unary_type == unary_exp) {
     CHECK_OO(rhs)
+    exp_setuse(unary->exp, 1);
+  }
   struct Op_Import opi = { .op=unary->op, .rhs=rhs,
     .data=(uintptr_t)unary, .pos=exp_self(unary)->pos, .op_type=op_unary };
   DECL_OO(const Type, ret, = op_check(env, &opi))
-  const Type t = get_type(actual_type(env->gwion, ret));
+  const Type t = actual_type(env->gwion, ret);
   CHECK_BO(ensure_traverse(env, t))
   return ret;
 }
@@ -911,13 +915,12 @@ ANN static inline Type foreach_type(const Env env, const Exp exp) {
 }
 
 ANN static m_bool do_stmt_each(const Env env, const Stmt_Each stmt) {
-  DECL_OB(const Type, ptr, = foreach_type(env, stmt->exp))
-  const Type base = get_type(ptr);
+  DECL_OB(const Type, base, = foreach_type(env, stmt->exp))
   CHECK_BB(ensure_traverse(env, base))
-  char c[15 + strlen(ptr->name)];
-  sprintf(c, "@Foreach:[%s]", ptr->name);
+  char c[15 + strlen(base->name)];
+  sprintf(c, "@Foreach:[%s]", base->name);
   const Type ret = str2type(env->gwion, c, stmt->exp->pos);
-  if(ptr->array_depth)
+  if(base->array_depth)
     set_tflag(ret, tflag_typedef);
   stmt->v = new_value(env->gwion->mp, ret, s_name(stmt->sym));
   set_vflag(stmt->v, vflag_valid);
@@ -1246,12 +1249,13 @@ HANDLE_SECTION_FUNC(check, m_bool, Env)
 ANN static m_bool check_parent(const Env env, const Class_Def cdef) {
   const Type parent = cdef->base.type->info->parent;
   const Type_Decl *td = cdef->base.ext;
-  if(td->array)
+//  if(td->array)
+  if(td->array && td->array->exp)
     CHECK_BB(check_subscripts(env, td->array, 1))
   CHECK_BB(ensure_check(env, parent))
-  if(tflag(parent, tflag_typedef)) {
-    set_tflag(cdef->base.type, tflag_typedef);
-  }
+//  if(tflag(parent, tflag_typedef)) {
+//    set_tflag(cdef->base.type, tflag_typedef);
+//  }
   return GW_OK;
 }
 
index 670847b68fe6db5dd3b19ad266034b6bb8418e7c..027e357d24f155bd600a3f98ae12b276eb3de8ed 100644 (file)
@@ -134,6 +134,13 @@ ANN m_bool add_op(const Gwion gwion, const struct Op_Import* opi) {
   return GW_OK;
 }
 
+ANN static inline Type op_parent(const Env env, const Type t) {
+  const size_t depth = t->array_depth;
+  return !depth || !array_base(t)->info->parent ?
+      t->info->parent :
+      array_type(env, array_base(t)->info->parent, depth);
+}
+
 ANN static Type op_check_inner(struct OpChecker* ock, const uint i) {
   Type t, r = ock->opi->rhs;
   do {
@@ -165,7 +172,7 @@ for(int i = 0; i < 2; ++i) {
           return NULL;
         return ret;
       }
-    } while(l && (l = l->info->parent));
+    } while(l && (l = op_parent(env, l)));
   } while((nspc = nspc->parent));
 }
   if(opi->op == insert_symbol(env->gwion->st, "$") && opi->rhs == opi->lhs)
@@ -222,8 +229,8 @@ ANN m_bool op_emit(const Emitter emit, const struct Op_Import* opi) {
           } else if(mo->func || mo->instr)
             return handle_instr(emit, mo);
         }
-      } while(r && (r = r->info->parent));
-    } while(l && (l = l->info->parent));
+      } while(r && (r = op_parent(emit->env, r)));
+    } while(l && (l = op_parent(emit->env, l)));
   } while((nspc = nspc->parent));
   }
   return GW_ERROR;
index 1b96133e1064ba814806f3a33bd9059ffac6cca1..2972a5a9bd260cae33eadff6a0af7492a4acf269 100644 (file)
@@ -312,8 +312,10 @@ ANN static Type scan0_class_def_init(const Env env, const Class_Def cdef) {
   if(parent == (Type)GW_ERROR)
     return NULL;
   const Type t = scan0_type(env, s_name(cdef->base.xid), parent);
-  if(cflag(cdef, cflag_struct))
+  if(cflag(cdef, cflag_struct)) {
+    t->size = 0;
     set_tflag(t, tflag_struct);
+  }
   t->info->tuple = new_tupleform(env->gwion->mp, parent);
   t->info->owner = env->curr;
   t->info->owner_class = env->class_def;
@@ -366,7 +368,6 @@ ANN m_bool scan0_class_def(const Env env, const Class_Def c) {
     c->base.type = cdef->base.type;
     c->base.type->info->cdef = cdef;
     set_tflag(c->base.type, tflag_cdef);
-    set_tflag(cdef->base.type, tflag_scan0);// redundant
   }
   return ret;
 }
index 14ac1bd31df0950db5eb97660978459a8dc617fa..d644ee850626c203e370d42c4b869520b8623e20 100644 (file)
@@ -24,21 +24,19 @@ ANN static inline m_bool type_cyclic(const Env env, const Type t, const Type_Dec
 }
 
 ANN static inline m_bool ensure_scan1(const Env env, const Type t) {
-  const Type base = get_type(t);
-  if(tflag(base, tflag_scan1) || !(tflag(base, tflag_cdef) || tflag(base, tflag_udef)))
+  if(tflag(t, tflag_scan1) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef)))
     return GW_OK;
   struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan1_cdef,
     .scope=env->scope->depth, .flag=tflag_scan1 };
-  return envset_run(&es, base);
+  return envset_run(&es, t);
 }
 
 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);
+  DECL_OO(const Type, t, = known_type(env, td))
   if(!env->func && env->class_def && !GET_FLAG(td, late))
     CHECK_BO(type_cyclic(env, t, td))
   CHECK_BO(ensure_scan1(env, t))
-  return type;
+  return t;
 }
 
 ANN static Type void_type(const Env env, Type_Decl* td) {
@@ -76,6 +74,7 @@ static inline uint array_ref(const Array_Sub array) {
 
 ANN static m_bool scan1_decl(const Env env, const Exp_Decl* decl) {
   Var_Decl_List list = decl->list;
+  const uint decl_ref = array_ref(decl->td->array);
   do {
     const Var_Decl var = list->self;
     CHECK_BB(isres(env, var->xid, exp_self(decl)->pos))
@@ -86,7 +85,7 @@ ANN static m_bool scan1_decl(const Env env, const Exp_Decl* decl) {
         CHECK_BB(scan1_exp(env, var->array->exp))
       t = array_type(env, decl->type, var->array->depth);
     }
-    if(t->array_depth && GET_FLAG(array_base(t), abstract) && ((var->array && var->array->exp)
+    if(GET_FLAG(array_base(t), abstract) && ((var->array && var->array->exp)
                                                   || (decl->td->array && decl->td->array->exp)))
       ERR_B(var->pos, _("arrays of abstract type '%s' must be declared empty"),
         array_base(t)->name);
@@ -95,8 +94,8 @@ ANN static m_bool scan1_decl(const Env env, const Exp_Decl* decl) {
     if(GET_FLAG(t, abstract) && !GET_FLAG(decl->td, late))
      SET_FLAG(v, late);
     v->type = t;
-    if(array_ref(var->array))
-      SET_FLAG(decl->td, late);
+    if(decl_ref || array_ref(var->array))
+      SET_FLAG(v, late);
     v->flag |= decl->td->flag;
     if(!env->scope->depth) {
       valuefrom(env, v->from);
@@ -130,8 +129,6 @@ ANN int is_global(const Nspc nspc, Nspc global) {
 ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) {
   CHECK_BB(env_storage(env, decl->td->flag, exp_self(decl)->pos))
   ((Exp_Decl*)decl)->type = scan1_exp_decl_type(env, (Exp_Decl*)decl);
-  if(array_ref(decl->td->array))
-    SET_FLAG(decl->td, late);
   CHECK_OB(decl->type)
   const m_bool global = GET_FLAG(decl->td, global);
   if(global) {
@@ -360,7 +357,7 @@ ANN static m_bool scan1_args(const Env env, Arg_List list) {
 
 ANN static m_bool _scan1_fdef_base_tmpl(const Env env, Func_Base *base) {
   ID_List id = base->tmpl->list;
-  do nspc_add_type(env->curr, id->xid, env->gwion->type[et_undefined]);
+  do nspc_add_type(env->curr, id->xid, env->gwion->type[et_auto]);
   while((id = id->next));
   CHECK_OB((base->ret_type = known_type(env, base->td)))
   if(base->args) {
@@ -594,7 +591,7 @@ ANN static Type scan1_get_parent(const Env env, const Type_Def tdef) {
 
 ANN static m_bool scan1_parent(const Env env, const Class_Def cdef) {
   const loc_t pos = cdef->base.ext->pos;
-  if(cdef->base.ext->array)
+  if(cdef->base.ext->array && cdef->base.ext->array->exp)
     CHECK_BB(scan1_exp(env, cdef->base.ext->array->exp))
   DECL_OB(const Type , parent, = scan1_get_parent(env, &cdef->base))
   if(isa(parent, env->gwion->type[et_object]) < 0)
index af5ed0fc62b70684498d95ba30e662d6ca7d3fb5..7407540fdb2db1fa19d572c21f24f02522f3fd0d 100644 (file)
@@ -15,16 +15,15 @@ ANN static m_bool scan2_stmt(const Env, const Stmt);
 ANN static m_bool scan2_stmt_list(const Env, Stmt_List);
 
 ANN static inline m_bool ensure_scan2(const Env env, const Type t) {
-  const Type base = get_type(t);
-  if(tflag(base, tflag_scan2) || !(tflag(base, tflag_cdef) || tflag(base, tflag_udef)))
+  if(tflag(t, tflag_scan2) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef)))
     return GW_OK;
   struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan2_cdef,
     .scope=env->scope->depth, .flag=tflag_scan2 };
-  return envset_run(&es, base);
+  return envset_run(&es, t);
 }
 
 ANN static m_bool scan2_decl(const Env env, const Exp_Decl* decl) {
-  const Type t = get_type(decl->type);
+  const Type t = decl->type;
   CHECK_BB(ensure_scan2(env, t))
   Var_Decl_List list = decl->list;
   do {
@@ -272,7 +271,7 @@ ANN static m_bool scan2_func_def_overload(const Env env, const Func_Def f, const
     if(!fbflag(f->base, fbflag_internal))
       ERR_B(f->pos, _("function name '%s' is already used by another value"), overload->name)
   }
-  const Func obase = !fptr ? overload->d.func_ref : overload->type->info->base_type->info->func;
+  const Func obase = !fptr ? overload->d.func_ref : _class_base(overload->type)->info->func;
   if(GET_FLAG(obase->def->base, final))
     ERR_B(f->pos, _("can't overload final function %s"), overload->name)
   const m_bool base = tmpl_base(f->base->tmpl);
@@ -526,7 +525,7 @@ 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->info->parent;
   CHECK_BB(ensure_scan2(env, parent))
-  if(cdef->base.ext->array)
+  if(cdef->base.ext->array && cdef->base.ext->array->exp)
     CHECK_BB(scan2_exp(env, cdef->base.ext->array->exp))
   return GW_OK;
 }
index 7230326cfff51a214b6f601357cd881bda1b74a2..2f5ef8a1b466ab7d12841ec8a58acbc6aad60bec 100644 (file)
@@ -41,15 +41,8 @@ scanx_body(const Env e, const Class_Def c, const _exp_func f, void* d) {
   return ret;
 }
 
-__attribute__((returns_nonnull))
-ANN Type get_type(const Type t) {
-  const Type type = !t->array_depth ? t : array_base(t);
-  return type;
-}
-
-ANN m_bool scanx_cdef(const Env env, void* opt, const Type base,
+ANN m_bool scanx_cdef(const Env env, void* opt, const Type t,
     const _exp_func f_cdef, const _exp_func f_union) {
-  const Type t = get_type(base);
   if(t->info->parent !=  env->gwion->type[et_union])
      return f_cdef(opt, t->info->cdef);
   const m_bool ret = f_union(opt, t->info->udef);
index 28f0f5d04b7dd33829bd02e12d3f634ecac690c9..85babe9ba345b56ec1a2950099a8cc3949a10a2e 100644 (file)
@@ -104,11 +104,7 @@ ANN Type _scan_type(const Env env, const Type t, Type_Decl* td) {
     return op_check(env, &opi);
   } else if(td->types)
     return maybe_func(env, t, td);
-  Type_Decl *next = td->next;
-  td->next = NULL;
-  const Type ret = find_type(env, td);
-  td->next = next;
-  return ret;
+  return find_type(env, td);
 }
 
 ANN Type scan_type(const Env env, const Type t, Type_Decl* td) {