]> Nishi Git Mirror - gwion.git/commitdiff
:art: Add Array.map
authorJérémie Astor <fennecdjay@gmail.com>
Tue, 13 Apr 2021 22:32:29 +0000 (00:32 +0200)
committerJérémie Astor <fennecdjay@gmail.com>
Tue, 13 Apr 2021 22:32:55 +0000 (00:32 +0200)
27 files changed:
include/env/envset.h
include/env/type.h
include/gwion.h
include/vm.h
src/compile.c
src/emit/emit.c
src/env/env.c
src/env/env_utils.c
src/env/envset.c
src/env/type.c
src/import/import_cdef.c
src/import/import_checker.c
src/lib/array.c
src/lib/instr.c
src/lib/lib_func.c
src/lib/object_op.c
src/lib/ptr.c
src/lib/ref.c
src/parse/check.c
src/parse/func_resolve_tmpl.c
src/parse/scan0.c
src/parse/scan1.c
src/parse/scan2.c
src/parse/template.c
src/parse/type_decl.c
src/vm/vm_code.c
tests/tree/class_template.gw

index 7d8407207e5f6b81f8d580bc1856f35c39db9178..88f6692972ae1f7af020b8d7e5b8f0bd45bb7f4e 100644 (file)
@@ -16,14 +16,16 @@ ANN2(1,3) m_bool envset_push(struct EnvSet*, const Type, const Nspc);
 ANN2(1) void   envset_pop(struct EnvSet*, const Type);
 
 ANN static inline m_bool extend_push(const Env env, const Type t) {
-  if(t->info->owner_class)
-    CHECK_BB(extend_push(env, t->info->owner_class))
+  const Type owner = t->info->value->from->owner_class;
+  if(owner)
+    CHECK_BB(extend_push(env, owner))
   return env_push_type(env, t);
 }
 
 ANN static inline void extend_pop(const Env env, const Type t) {
   env_pop(env, 0);
-  if(t->info->owner_class)
-    extend_pop(env, t->info->owner_class);
+  const Type owner = t->info->value->from->owner_class;
+  if(owner)
+    extend_pop(env, owner);
 }
 #endif
index 00283758a6cd97e806fbf4374c2931c75ea4baa7..dc87c89c5746fa97080c56786a587fd49bf24cc4 100644 (file)
@@ -3,8 +3,7 @@
 
 struct TypeInfo_ {
   Type parent;
-  Nspc owner;
-  Type owner_class;
+  Value value;
   union {
     Union_Def udef;
     Class_Def cdef;
@@ -13,7 +12,6 @@ struct TypeInfo_ {
   Type      base_type;
   struct TupleForm_* tuple;
   struct VM_Code_ *gack;
-  struct Context_ *ctx;
 };
 
 enum tflag {
index 9ee352d1f8b6048f8514ffb8d998cd589f25fc80..5061063621551459572a9012b4100c3ff0396c52 100644 (file)
@@ -28,11 +28,11 @@ ANN void push_global(const Gwion gwion, const m_str name);
 ANN Nspc pop_global(const Gwion gwion);
 __attribute__((returns_nonnull))
 ANN static inline Value type_value(const Gwion gwion, const Type t) {
-  return (Value)nspc_lookup_value1(t->info->owner, insert_symbol(gwion->st, t->name));
+  return (Value)nspc_lookup_value1(t->info->value->from->owner, insert_symbol(gwion->st, t->name));
 }
 __attribute__((returns_nonnull))
 ANN static inline Type type_class(const Gwion gwion, const Type t) {
-  const Value v = nspc_lookup_value1(t->info->owner, insert_symbol(gwion->st, t->name));
+  const Value v = nspc_lookup_value1(t->info->value->from->owner, insert_symbol(gwion->st, t->name));
   return v->type;
 }
 #endif
index 502a1c20beddb936fb187d407afe10a48586f4b1..5fb074b896fe744dad8c2c6dbe67e1ece010a2de 100644 (file)
@@ -17,13 +17,14 @@ struct VM_Code_ {
     m_uint native_func;
   };
   size_t stack_depth;
+  struct Vector_ tmpl_types;
   void* memoize;
   Closure *closure;
   m_str name;
   uint16_t ref;
   ae_flag flag;
-  int builtin;
-  int callback;
+  bool builtin;
+  bool callback;
 };
 
 typedef struct Shreduler_* Shreduler;
index 7f1c0fd4ef11df04448f8bcc44f60aa3619da88c..aa06e238539aacd95a18aa94f5fbf6262c3d18bb 100644 (file)
@@ -72,8 +72,10 @@ ANN static m_bool _compiler_open(struct Compiler* c) {
 ANN static int is_reg(const m_str path) {
   struct stat s;
   stat(path, &s);
-  return S_ISREG(s.st_mode) || !S_ISFIFO(s.st_mode);
+  return !S_ISDIR(s.st_mode) &&
+    (S_ISREG(s.st_mode) || !S_ISFIFO(s.st_mode));
 }
+
 #else
 ANN static m_bool is_reg(const m_str path) {
   const DWORD dw = GetFileAttributes(path);
@@ -86,7 +88,7 @@ ANN static inline m_bool compiler_open(MemPool p, struct Compiler* c) {
   char name[strlen(c->name) + 1];
   strcpy(name, c->name);
 #ifndef __FUZZING__
-  if(c->type == COMPILE_FILE && !is_reg(name)) {
+  if((c->type == COMPILE_FILE || c->type == COMPILE_NAME) && !is_reg(name)) {
     gw_err(_("'%s': is a not a regular file\n"), name);
     return GW_ERROR;
   }
index 209b8c6831dbce6e93f5702439637ed0943bed05..d2f81fc01d2ac6a2a847725a76acaa9d5b37ecb8 100644 (file)
@@ -2259,8 +2259,18 @@ ANN static m_bool emit_func_def(const Emitter emit, const Func_Def f) {
   const Func former = emit->env->func;
   if(func->code || tmpl_base(fdef->base->tmpl))
     return GW_OK;
-  if(vflag(func->value_ref, vflag_builtin) && safe_tflag(emit->env->class_def, tflag_tmpl))
+  if(vflag(func->value_ref, vflag_builtin) && safe_tflag(emit->env->class_def, tflag_tmpl)) {
+    const Func base = nspc_lookup_func1(func->value_ref->from->owner, f->base->xid);
+    builtin_func(emit->gwion->mp, func, (f_xfun)base->code->native_func);
+    vector_init(&func->code->tmpl_types);
+    vector_add(&func->code->tmpl_types, (m_uint)fdef->base->ret_type);
+    Arg_List args = fdef->base->args;
+    while(args) {
+      vector_add(&func->code->tmpl_types, (m_uint)args->type);
+      args = args->next;
+    }
     return GW_OK;
+  }
   if(fdef_is_file_global(emit, fdef))
     func->value_ref->from->offset = emit_local(emit, emit->gwion->type[et_int]);
   const uint global = GET_FLAG(f->base, global);
@@ -2340,8 +2350,9 @@ ANN static m_bool emit_class_def(const Emitter emit, const Class_Def cdef) {
   if(tflag(t, tflag_emit))
     return GW_OK;
   set_tflag(t, tflag_emit);
-  if(t->info->owner_class)
-    CHECK_BB(ensure_emit(emit, t->info->owner_class))
+  const Type owner = t->info->value->from->owner_class;
+  if(owner)
+    CHECK_BB(ensure_emit(emit, owner))
   if(cdef->base.ext && t->info->parent->info->cdef && !tflag(t->info->parent, tflag_emit)) // ?????
     CHECK_BB(cdef_parent(emit, cdef))
   nspc_allocdata(emit->gwion->mp, t->nspc);
index 947e4bb6fd3c3d715a9491dfab53918b1f1f159f..5eda55172ab00ea6d156115e0943942271aa26c5 100644 (file)
@@ -84,8 +84,6 @@ ANN void env_pop(const Env env, const m_uint scope) {
 }
 
 ANN void env_add_type(const Env env, const Type type, const loc_t loc) {
-  type->info->owner = env->curr;
-  type->info->owner_class = env->class_def; // t owner_class ?
   const Symbol sym = insert_symbol(type->name);
   nspc_add_type_front(env->curr, sym, type);
   const Value v = mk_class(env, type, loc);
index 2bc610cadc7af36ee583ec6d8e0e27df0345ef45..5c195b00d6ef4c9babfd247ca8abdec59b93de19 100644 (file)
@@ -67,7 +67,6 @@ ANN static Type class_type(const Env env, const Type base) {
   const Type t_class = env->gwion->type[et_class];
   const Type t = type_copy(env->gwion->mp, t_class);
   t->info->parent = t_class;
-  t->info->ctx = base->info->ctx;
   t->info->base_type = base;
   set_tflag(t, tflag_infer);
   return t;
@@ -80,7 +79,8 @@ ANN Value mk_class(const Env env, const Type base, const loc_t loc) {
   valuefrom(env, v->from, loc);
   SET_FLAG(v, const);
   set_vflag(v, vflag_valid);
-  nspc_add_value_front(base->info->owner, sym, v);
+  nspc_add_value_front(env->curr, sym, v);
+  t->info->value = base->info->value = v;
   return v;
 }
 
index 4ee189dd2f70c216e802d6a233fa43de6e1f6fc1..70cffea813a861c71bce1cd30a43ea5629010521 100644 (file)
@@ -7,22 +7,23 @@
 
 ANN static void check(struct EnvSet *es, const Type t) {
   const Vector v = &es->env->scope->class_stack;
-  Type owner = t->info->owner_class;
+  Type owner = t->info->value->from->owner_class;
   for(vtype i = vector_size(v) + 1; owner && --i;) {
     if(owner != (Type)vector_at(v, i - 1)) {
       es->run = 1;
       return;
     }
-    owner = owner->info->owner_class;
+    owner = owner->info->value->from->owner_class;
   }
 }
 
 ANN static m_bool push(struct EnvSet *es, const Type t) {
   es->env->scope->depth = 0;
-  if(t->info->owner_class)
-    CHECK_BB(push(es, t->info->owner_class))
+  const Type owner_class = t->info->value->from->owner_class;
+  if(owner_class)
+    CHECK_BB(push(es, owner_class))
   else
-    env_push(es->env, NULL, t->info->ctx ? t->info->ctx->nspc : es->env->curr);
+    env_push(es->env, NULL, t->info->value->from->ctx ? t->info->value->from->ctx->nspc : es->env->curr);
   if(es->func && !(t->tflag & es->flag))
     CHECK_BB(es->func((void*)es->data, t))
   if(tflag(t, tflag_tmpl))
@@ -49,20 +50,22 @@ ANN2(1) void envset_pop(struct EnvSet *es, const Type t) {
     return;
   if(tflag(t, tflag_tmpl))
     nspc_pop_type(es->env->gwion->mp, es->env->curr);
-  if(t->info->owner_class)
-    envset_pop(es, t->info->owner_class);
+  const Type owner_class = t->info->value->from->owner_class;
+  if(owner_class)
+    envset_pop(es, owner_class);
   else
     env_pop(es->env, es->scope);
 }
 
 ANN m_bool envset_run(struct EnvSet *es, const Type t) {
   check(es, t);
+  const Type owner_class = t->info->value->from->owner_class;
   if(es->run)
-    CHECK_BB(push(es, t->info->owner_class))
+    CHECK_BB(push(es, owner_class))
   const m_bool ret = t->info->cdef &&
     !(t->tflag & es->flag) ?
         es->func(es->data, t) : GW_OK;
   if(es->run)
-    envset_pop(es, t->info->owner_class);
+    envset_pop(es, owner_class);
   return ret;
 }
index 4611b4ff34992a7f3504d0f8cc6ae2c18f93e159..21caa22854d092a01933a8100f4b80d74a4148f7 100644 (file)
@@ -41,9 +41,6 @@ Type new_type(MemPool p, const m_str name, const Type parent) {
 
 ANN Type type_copy(MemPool p, const Type type) {
   const Type a         = new_type(p, type->name, type->info->parent);
-  a->nspc              = type->nspc;
-  a->info->owner       = type->info->owner;
-  a->info->owner_class = type->info->owner_class;
   a->size              = type->size;
   a->array_depth       = type->array_depth;
   a->info->gack        = type->info->gack;
@@ -101,7 +98,7 @@ ANN /*static */Symbol array_sym(const Env env, const Type src, const m_uint dept
 #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);
+  const Type type = nspc_lookup_type1(src->info->value->from->owner, sym);
   if(type)
     return type;
   const size_t tdepth = depth + src->array_depth;
index 6ca93ef0041f03806af8e9998ce97975e904e881..ce372094ccf8288ba44f8cf8b2eeba587bacca88 100644 (file)
@@ -31,8 +31,6 @@ ANN2(1,2) static void import_class_ini(const Env env, const Type t) {
   t->nspc->parent = env->curr;
   if(isa(t, env->gwion->type[et_object]) > 0)
     inherit(t);
-  t->info->owner = env->curr;
-  t->info->owner_class = env->class_def;
   env_push_type(env, t);
 }
 
index 3e46de7901f31990e4f9fc7078103d4cdc6a3958..d1ceb775bd8bfeb7bae40f4bdde7a593e4d9b9d9 100644 (file)
@@ -174,7 +174,17 @@ ANN static Type_List td_tmpl(const Gwion gwion, struct td_checker *tdc) {
   return tl;
 }
 
+ANN static inline uint get_n(struct td_checker *tdc, const char c) {
+  uint n = 0;
+  while(*tdc->str == c) {
+    n++;
+    ++tdc->str;
+  }
+  return n;
+}
+
 ANN static Type_Decl* _str2td(const Gwion gwion, struct td_checker *tdc) {
+  const uint ref = get_n(tdc, '&');
   DECL_OO(const Symbol, sym, = __str2sym(gwion, tdc))
   struct AC ac = { .str = tdc->str, .pos=tdc->pos };
   CHECK_BO(ac_run(gwion, &ac))
@@ -182,6 +192,7 @@ ANN static Type_Decl* _str2td(const Gwion gwion, struct td_checker *tdc) {
   Type_List tl = td_tmpl(gwion, tdc);
   if(tl == (Type_List)GW_ERROR)
     return NULL;
+  const uint option = get_n(tdc, '?');
   Type_Decl *next = NULL;
   if(*tdc->str == '.') {
     ++tdc->str;
@@ -196,6 +207,8 @@ ANN static Type_Decl* _str2td(const Gwion gwion, struct td_checker *tdc) {
   Type_Decl *td = new_type_decl(gwion->mp, sym, tdc->pos);
   td->next = next;
   td->types = tl;
+  td->option = option;
+  td->ref = ref;
   if(ac.depth)
     td->array = mk_array(gwion->mp, &ac);
   return td;
@@ -224,7 +237,7 @@ struct td_info {
 };
 
 ANN static void td_fullname(const Env env, GwText *text, const Type t) {
-  const Type owner = t->info->owner_class;
+  const Type owner = t->info->value->from->owner_class;
   if(owner) {
     td_fullname(env, text, owner);
     text_add(text, ".");
@@ -245,8 +258,9 @@ 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) {
-    td_fullname(gwion->env, &text, t->info->owner_class);
+  const Type owner = t->info->value->from->owner_class;
+  if(owner) {
+    td_fullname(gwion->env, &text, owner);
     text_add(&text, ".");
   }
   text_add(&text, t->name);
index b0d4172bd1f43079ec0d55061e9b19ca1e724472..06a3b57818c0aa4af277f84e71fd67657f90b789 100644 (file)
@@ -426,6 +426,61 @@ static OP_EMIT(opem_array_access) {
   return exp ? emit_array_access(emit, info) : GW_ERROR;
 }
 
+static m_bit map_byte[BYTECODE_SZ*4];// = { eOP_MAX, test };
+static const struct VM_Code_ map_run_code = {
+  .name        = "map_run_code",
+  .stack_depth = SZ_INT,
+  .bytecode = map_byte
+};
+
+#define MAP_CODE_OFFSET SZ_INT*10
+static INSTR(test) {
+  *(VM_Code*)(shred->reg) = (*(VM_Code*)MEM(SZ_INT));
+  *(VM_Code*)(shred->reg + SZ_INT) = 0;
+  PUSH_REG(shred, SZ_INT);
+  const M_Object self = *(M_Object*)MEM(0);
+  const M_Vector array = ARRAY(self);
+  const m_uint index = *(m_uint*)MEM(SZ_INT*5);
+   shred->pc++;
+  (*(m_uint*)MEM(SZ_INT*5))++;   // increment the index
+  shred->mem += MAP_CODE_OFFSET; // work in a safe memory space
+  *(m_uint*)(shred->reg + SZ_INT) = 0;
+  *(m_uint*)(shred->mem-SZ_INT) = 0;
+  *(m_uint*)(shred->mem-SZ_INT*2) = 0;
+  *(VM_Code*)(shred->mem-SZ_INT*3) = (VM_Code)&map_run_code;
+  m_vector_get(array, index, &*(m_bit**)(shred->mem + SZ_INT*5));
+}
+
+static INSTR(test2) {
+  shred->mem -= MAP_CODE_OFFSET;
+  const M_Object ret_obj = *(M_Object*)MEM(SZ_INT*2);
+  const M_Vector array = ARRAY(ret_obj);
+  POP_REG(shred, ARRAY_SIZE(array));
+  POP_REG(shred, SZ_INT);
+  const m_uint index = *(m_uint*)MEM(SZ_INT*5);
+  const m_uint size = m_vector_size(array);
+  m_vector_set(array, index - 1, &*(m_bit**)(shred->reg + SZ_INT));
+  if(index == size) {
+    shred->pc = *(m_uint*)MEM(SZ_INT*3);
+    shred->code = *(VM_Code*)MEM(SZ_INT*4);
+    *(M_Object*)(shred->reg) = ret_obj;
+    shred->reg += SZ_INT;
+  } else
+    shred->pc = 0;
+  shredule(shred->tick->shreduler, shred, 0);
+}
+
+static MFUN(vm_vector_map) {
+  const VM_Code code = *(VM_Code*)REG(SZ_INT*2);
+  const M_Object ret = *(M_Object*)MEM(SZ_INT*2) = *(M_Object*)RETURN = new_array(shred->info->vm->gwion->mp, (Type)vector_front(&code->tmpl_types), ARRAY_LEN(ARRAY(o)));
+  vector_add(&shred->gc, (m_uint)ret);
+  *(m_uint*)MEM(SZ_INT*3) = shred->pc;
+  *(VM_Code*)MEM(SZ_INT*4) = shred->code;
+  shred->code = (VM_Code)&map_run_code;
+  shred->pc = 0;
+  shredule(shred->tick->shreduler, shred, 0);
+}
+
 ANN /*static */Symbol array_sym(const Env env, const Type src, const m_uint depth);
 #include "template.h"
 static OP_CHECK(opck_array_scan) {
@@ -435,7 +490,7 @@ static OP_CHECK(opck_array_scan) {
   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);
+  const Type type = nspc_lookup_type1(base->info->value->from->owner, sym);
   if(type)
     return type;
   const Class_Def cdef = cpy_class_def(env->gwion->mp, c);
@@ -444,8 +499,8 @@ static OP_CHECK(opck_array_scan) {
   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 Context ctx = env->context;
-  env->context = base->info->ctx;
-  const m_uint scope = env_push(env, base->info->owner_class, base->info->owner);
+  env->context = base->info->value->from->ctx;
+  const m_uint scope = env_push(env, base->info->value->from->owner_class, base->info->value->from->owner);
   (void)scan0_class_def(env, cdef);
   const Type t = cdef->base.type;
   (void)traverse_cdef(env, t);
@@ -469,6 +524,7 @@ static OP_CHECK(opck_array_scan) {
   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);
   builtin_func(env->gwion->mp, (Func)vector_at(&t->nspc->info->vtable, 5), vm_vector_random);
+  builtin_func(env->gwion->mp, (Func)vector_at(&t->nspc->info->vtable, 6), vm_vector_map);
   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);
@@ -488,7 +544,18 @@ static OP_CHECK(opck_array_implicit) {
   return imp->t;
 }
 
+static void prepare_map_run(void) {
+  *(unsigned*)map_byte = eOP_MAX;
+  *(f_instr*)(map_byte + SZ_INT*2) = test;
+  *(unsigned*)(map_byte+ BYTECODE_SZ) = eSetCode;
+  *(m_uint*)(map_byte + BYTECODE_SZ + SZ_INT*2) = 3;
+  *(unsigned*)(map_byte+ BYTECODE_SZ*2) = eOverflow;
+  *(unsigned*)(map_byte+ BYTECODE_SZ*3) = eOP_MAX;
+  *(f_instr*)(map_byte + BYTECODE_SZ*3 + SZ_INT*2) = test2;
+}
+
 GWION_IMPORT(array) {
+  prepare_map_run();
   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);
@@ -497,6 +564,10 @@ GWION_IMPORT(array) {
   GWI_BB(gwi_item_ini(gwi, "@internal", "@ctor_data"))
   GWI_BB(gwi_item_end(gwi, 0, num, 0))
 
+  GWI_BB(gwi_fptr_ini(gwi, "A", "map_t:[A]"))
+  GWI_BB(gwi_func_arg(gwi, "T", "elem"))
+  GWI_BB(gwi_fptr_end(gwi, ae_flag_global))
+
   // put functions using T first
   GWI_BB(gwi_func_ini(gwi, "bool", "remove"))
   GWI_BB(gwi_func_arg(gwi, "int", "index"))
@@ -518,6 +589,10 @@ GWION_IMPORT(array) {
   GWI_BB(gwi_func_ini(gwi, "T", "random"))
   GWI_BB(gwi_func_end(gwi, vm_vector_random, ae_flag_none))
 
+  GWI_BB(gwi_func_ini(gwi, "A[]", "map:[A]"))
+  GWI_BB(gwi_func_arg(gwi, "map_t:[A]", "data"))
+  GWI_BB(gwi_func_end(gwi, vm_vector_map, ae_flag_none))
+
   GWI_BB(gwi_class_end(gwi))
 
   GWI_BB(gwi_oper_ini(gwi, "Array", "Array", NULL))
index c4f63f43ee72ccfd9f2cc886cb5e34b27f2961bc..a8b9132119416affd57dcdc26e1772a178dc907c 100644 (file)
@@ -55,6 +55,12 @@ ANN static Func_Def traverse_tmpl(const Emitter emit, struct dottmpl_ *const dt,
 INSTR(GTmpl) {
   struct dottmpl_ *dt = (struct dottmpl_*)instr->m_val;
   const Func f = *(Func*)REG(-SZ_INT);
+  if(!f)
+    Except(shred, _("EmptyFuncPointerException"));
+if(f->code) {
+  *(VM_Code*)(shred->reg -SZ_INT) = f->code;
+ return;
+}
   const m_str name = f->name;
   const Emitter emit = shred->info->vm->gwion->emit;
   emit->env->name = "runtime";
index 93e08f06e3ff3a2c81e4a7678604579c0301daeb..30fb15eae01e364dd74c249300cc94aa5e2f744b 100644 (file)
@@ -49,25 +49,40 @@ struct FptrInfo {
   const loc_t pos;
 };
 
+ANN static void _fptr_tmpl_push(const Env env, const Func f) {
+  ID_List il = f->def->base->tmpl ? f->def->base->tmpl->list : NULL;
+  if(il) {
+    Type_List tl = f->def->base->tmpl->call;
+    while(il) {
+      const Type t = tl ? known_type(env, tl->td) : env->gwion->type[et_auto];
+      nspc_add_type(env->curr, il->xid, t);
+      il = il->next;
+      if(tl)
+        tl = tl->next;
+    }
+  }
+}
+
 ANN static m_bool fptr_tmpl_push(const Env env, struct FptrInfo *info) {
   if(!info->rhs->def->base->tmpl)
     return GW_OK;
-  ID_List t0 = info->lhs->def->base->tmpl->list,
-          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_auto]);
-    nspc_add_type(env->curr, t1->xid, env->gwion->type[et_auto]);
-    t0 = t0->next;
-    t1 = t1->next;
-  }
+//  Type owner = info->rhs->value_ref->from->owner_class;
+//  while(owner) {
+//    owner = owner->info->value->from->owner_class;
+//  }
+
+//  _fptr_tmpl_push(env, info->lhs);
+  _fptr_tmpl_push(env, info->rhs);
   return GW_OK;
 }
 
 static m_bool td_match(const Env env, Type_Decl *id[2]) {
   DECL_OB(const Type, t0, = known_type(env, id[0]))
   DECL_OB(const Type, t1, = known_type(env, id[1]))
-  return isa(t0, t1);
+  if(isa(t0, t1) > 0)
+    return GW_OK;
+  return t1 == env->gwion->type[et_auto];
 }
 
 ANN static m_bool fptr_args(const Env env, Func_Base *base[2]) {
@@ -83,8 +98,8 @@ ANN static m_bool fptr_args(const Env env, Func_Base *base[2]) {
 }
 
 ANN static m_bool fptr_check(const Env env, struct FptrInfo *info) {
-  if(!info->lhs->def->base->tmpl != !info->rhs->def->base->tmpl)
-    return GW_ERROR;
+//  if(!info->lhs->def->base->tmpl != !info->rhs->def->base->tmpl)
+//    return GW_ERROR;
   const Type l_type = info->lhs->value_ref->from->owner_class;
   const Type r_type = info->rhs->value_ref->from->owner_class;
   if(!r_type && l_type)
@@ -122,20 +137,24 @@ ANN static Type fptr_type(const Env env, struct FptrInfo *info) {
   for(m_uint i = 0; i <= v->from->offset && !type; ++i) {
     const Symbol sym = (!info->lhs->def->base->tmpl || i != 0) ?
         func_symbol(env, nspc->name, c, stmpl, i) : info->lhs->def->base->xid;
-    if(!is_class(env->gwion, info->lhs->value_ref->type))
-      CHECK_OO((info->lhs = nspc_lookup_func1(nspc, sym)))
-    else {
+    if(!is_class(env->gwion, info->lhs->value_ref->type)) {
+      if(!(info->lhs = nspc_lookup_func1(nspc, sym))) {
+        const Value v = nspc_lookup_value1(nspc, insert_symbol(c));
+        if(isa(v->type, env->gwion->type[et_function]) < 0)
+          return NULL;
+        info->lhs = v->type->info->func;
+      }
+    } else {
       DECL_OO(const Type, t, = nspc_lookup_type1(nspc, info->lhs->def->base->xid))
       info->lhs = actual_type(env->gwion, t)->info->func;
     }
     Func_Base *base[2] =  { info->lhs->def->base, info->rhs->def->base };
-    if(fptr_tmpl_push(env, info) > 0) {
-      if(fptr_rettype(env, info) > 0 &&
-           fptr_arity(info) && fptr_args(env, base) > 0)
+    CHECK_BO(fptr_tmpl_push(env, info))
+    if(fptr_rettype(env, info) > 0 &&
+         fptr_arity(info) && fptr_args(env, base) > 0)
       type = actual_type(env->gwion, info->lhs->value_ref->type) ?: info->lhs->value_ref->type;
-      if(info->rhs->def->base->tmpl)
-        nspc_pop_type(env->gwion->mp, env->curr);
-    }
+    if(info->rhs->def->base->tmpl)
+      nspc_pop_type(env->gwion->mp, env->curr);
   }
   return type;
 }
@@ -143,16 +162,18 @@ ANN static Type fptr_type(const Env env, struct FptrInfo *info) {
 ANN static m_bool _check_lambda(const Env env, Exp_Lambda *l, const Func_Def def) {
   Arg_List base = def->base->args, arg = l->def->base->args;
   while(base && arg) {
-    arg->td = base->td;
+//    arg->td = base->td;
+    arg->td = type2td(env->gwion, known_type(env, base->td), exp_self(l)->pos);
+//    arg->type = known_type(env, base->td);
     base = base->next;
     arg = arg->next;
   }
   if(base || arg)
     ERR_B(exp_self(l)->pos, _("argument number does not match for lambda"))
   l->def->base->flag = def->base->flag;
-  if(GET_FLAG(def->base, global) && !l->owner && def->base->func->value_ref->from->owner_class)
+//  if(GET_FLAG(def->base, global) && !l->owner && def->base->func->value_ref->from->owner_class)
     UNSET_FLAG(l->def->base, global);
-  l->def->base->td = cpy_type_decl(env->gwion->mp, def->base->td);
+  l->def->base->td = type2td(env->gwion, known_type(env, def->base->td), exp_self(l)->pos);
   l->def->base->values = env->curr->info->value;
   const m_bool ret = traverse_func_def(env, l->def);
   if(l->def->base->func) {
@@ -161,18 +182,13 @@ ANN static m_bool _check_lambda(const Env env, Exp_Lambda *l, const Func_Def def
       env->curr->info->value = l->def->base->values;
     }
   }
-  arg = l->def->base->args;
-  while(arg) {
-    arg->td = NULL;
-    arg = arg->next;
-  }
   return ret;
 }
 
 ANN m_bool check_lambda(const Env env, const Type t, Exp_Lambda *l) {
   const Func_Def fdef = t->info->func->def;
   if(!GET_FLAG(t->info->func->value_ref, global))
-    l->owner = t->info->owner_class;
+    l->owner = t->info->value->from->owner_class;
   CHECK_BB(_check_lambda(env, l, fdef))
   exp_self(l)->type = l->def->base->func->value_ref->type;
   return GW_OK;
@@ -182,7 +198,7 @@ ANN static m_bool fptr_do(const Env env, struct FptrInfo *info) {
   if(isa(info->exp->type, env->gwion->type[et_lambda]) < 0) {
     CHECK_BB(fptr_check(env, info))
     if(!(info->exp->type = fptr_type(env, info)))
-      ERR_B(info->lhs->def->base->pos, _("no match found"))
+      ERR_B(info->pos, _("no match found"))
     return GW_OK;
   }
   Exp_Lambda *l = &info->exp->d.exp_lambda;
index 31a4382c196eb24d3943a7301b71b7d3a9f706f9..7f3604bbf88e8b493fb46d8b41e04c12c42a71ed 100644 (file)
@@ -275,11 +275,11 @@ ANN Type scan_class(const Env env, const Type t, const Type_Decl *td) {
     return exists != env->gwion->type[et_error] ? exists : NULL;
   struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan0_cdef,
     .scope=env->scope->depth, .flag=tflag_scan0 };
-  const Type _t = known_type(env, td->types->td);
-  CHECK_BO(envset_push(&es, _t->info->owner_class, _t->info->owner))
+  const Type owner = t->info->value->from->owner_class;
+  CHECK_BO(envset_push(&es, owner, t->info->value->from->owner))
   const Type ret = _scan_class(env, &info);
   if(es.run)
-    envset_pop(&es, _t->info->owner_class);
+    envset_pop(&es, owner);
   return ret;
 }
 
index ebd6eb51a345155c913056fe544cafaac1d7cf71..b981136f50d22f69a16ffc44de715640936842d7 100644 (file)
@@ -23,6 +23,7 @@ static m_bool ptr_access(const Env env, const Exp e) {
 }
 
 ANN static inline Type ptr_base(const Env env, const Type t) {
+  return (Type)vector_front(&t->info->tuple->types);
   return known_type(env, t->info->cdef->base.tmpl->call->td);
 }
 
@@ -81,9 +82,6 @@ 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 = imp->t;
-    if(!tflag(t, tflag_check))
-      CHECK_BN(traverse_class_def(env, t->info->cdef))
     return imp->t;
   }
   return NULL;
@@ -136,17 +134,29 @@ static DTOR(ptr_object_dtor) {
 
 static DTOR(ptr_struct_dtor) {
   const Type base = *(Type*)(shred->mem + SZ_INT);
-  const m_uint scope = env_push(shred->info->vm->gwion->env, base->info->owner_class, base->info->owner);
+  const m_uint scope = env_push(shred->info->vm->gwion->env, base->info->value->from->owner_class, base->info->value->from->owner);
   const Type t = known_type(shred->info->vm->gwion->env, base->info->cdef->base.tmpl->call->td);
   env_pop(shred->info->vm->gwion->env, scope);
   struct_release(shred, t, *(m_bit**)o);
 }
-
+#include "tmpl_info.h"
 static OP_CHECK(opck_ptr_scan) {
   struct TemplateScan *ts = (struct TemplateScan*)data;
-  DECL_ON(const Type, t, = (Type)scan_class(env, ts->t, ts->td))
-  const Type base = known_type(env, t->info->cdef->base.tmpl->call->td);
+  struct tmpl_info info = { .base=ts->t, .td=ts->td, .list=ts->t->info->cdef->base.tmpl->list  };
+  const Type exists = tmpl_exists(env, &info);
+  if(exists)
+    return exists != env->gwion->type[et_error] ? exists : NULL;
+  const Type base = known_type(env, ts->td->types->td);
+  const Type t = new_type(env->gwion->mp, s_name(info.name), base);
   t->info->parent = env->gwion->type[et_ptr];
+  SET_FLAG(t, abstract | ae_flag_final);
+  t->info->tuple = new_tupleform(env->gwion->mp, NULL);
+  t->nspc = new_nspc(env->gwion->mp, t->name);
+  vector_add(&t->info->tuple->types, (m_uint)base);
+  const m_uint scope = env_push(env, base->info->value->from->owner_class, base->info->value->from->owner);
+  mk_class(env, t, (loc_t){});
+  env_pop(env, scope);
+  nspc_add_type_front(t->info->value->from->owner, info.name, t);
   if(isa(base, env->gwion->type[et_compound]) > 0) {
     t->nspc->dtor = new_vmcode(env->gwion->mp, NULL, SZ_INT, 1, "@PtrDtor");
     if(!tflag(base, tflag_struct))
index cf0149a6700b272b4f7d42023e2866bb1ff29670..7bb9ce83de764d521469dd2a48b7062a29c0482e 100644 (file)
@@ -61,17 +61,14 @@ OP_CHECK(opck_foreach_scan) {
     return exists != env->gwion->type[et_error] ? exists : NULL;
   const Type base = known_type(env, ts->td->types->td);
   const Type t = new_type(env->gwion->mp, s_name(info.name), base);
-  t->info->owner = base->info->owner;
-  t->info->owner_class = base->info->owner_class;
-  t->info->ctx = base->info->ctx;
   SET_FLAG(t, abstract | ae_flag_final);
   set_tflag(t, tflag_infer);
-  const m_uint scope = env_push(env, base->info->owner_class, base->info->owner);
-//  mk_class(env, t, (loc_t){});
+  const m_uint scope = env_push(env, base->info->value->from->owner_class, base->info->value->from->owner);
+  mk_class(env, t, (loc_t){});
   base2ref(env, base, t);
   ref2base(env, t, base);
   env_pop(env, scope);
-  nspc_add_type_front(t->info->owner, info.name, t);
+  nspc_add_type_front(t->info->value->from->owner, info.name, t);
   return t;
 }
 
index f5639c5c2817e9d9bd938dbd7e9a952bfcce3327..48804f06346b41fbc65017732a7ef4d3f073c554 100644 (file)
@@ -720,7 +720,7 @@ ANN m_bool func_check(const Env env, Exp_Call *const exp) {
     ERR_B(exp->func->pos, _("Can't call late function pointer at declaration site"))
   const Type t = actual_type(env->gwion, exp->func->type);
   if(isa(t, env->gwion->type[et_function]) > 0 &&
-        exp->func->exp_type == ae_exp_dot && !t->info->owner_class) {
+        exp->func->exp_type == ae_exp_dot && !t->info->value->from->owner_class) {
     if(exp->args)
       CHECK_OB(check_exp(env, exp->args))
     return call2ufcs(env, exp, t->info->func->value_ref) ?
@@ -1421,7 +1421,7 @@ ANN m_bool check_abstract(const Env env, const Class_Def cdef) {
   bool err = false;
   for(m_uint i = 0; i < vector_size(&cdef->base.type->nspc->info->vtable); ++i) {
     Func f = (Func)vector_at(&cdef->base.type->nspc->info->vtable, i);
-    if(GET_FLAG(f->def->base, abstract)) {
+    if(f && GET_FLAG(f->def->base, abstract)) {
       if(!err) {
         err = true;
         gwerr_basic(
@@ -1445,8 +1445,8 @@ ANN m_bool check_class_def(const Env env, const Class_Def cdef) {
   struct Op_Import opi = { .op=insert_symbol("@class_check"), .lhs=t,
         .data=(uintptr_t)cdef, .pos=cdef->pos };
   CHECK_OB(op_check(env, &opi))
-  if(t->info->owner_class)
-    CHECK_BB(ensure_check(env, t->info->owner_class))
+  if(t->info->value->from->owner_class)
+    CHECK_BB(ensure_check(env, t->info->value->from->owner_class))
   if(tflag(t, tflag_check))
     return GW_OK;
   set_tflag(t, tflag_check);
index d75db3b192b4a3fe1cd58cc70f0d2dee9c46c880..75ab3efd7ded01aa35fec702119343d3bee08fcc 100644 (file)
@@ -35,10 +35,15 @@ ANN static inline m_bool tmpl_valid(const Env env, const Func_Def fdef) {
 ANN static Func ensure_tmpl(const Env env, const Func_Def fdef, Exp_Call *const exp) {
   if(!tmpl_valid(env, fdef))
     return NULL;
+  if(exp->args && !exp->args->type)
+    return NULL;
   const Func f = fdef->base->func;
   const Func next = f->next;
   f->next = NULL;
+  const Tmpl tmpl = { .list=fdef->base->tmpl->list, .call=exp->tmpl->call };
+  CHECK_BO(template_push_types(env, &tmpl));
   const Func func = find_func_match(env, f, exp);
+  nspc_pop_type(env->gwion->mp, env->curr);
   f->next = next;
   if(func)
     set_fflag(func, fflag_tmpl | fflag_valid);
@@ -84,14 +89,16 @@ ANN static Func create_tmpl(const Env env, struct ResolverArgs* ra, const m_uint
   const Value value = template_get_ready(env, ra->v, "template", i);
   if(!value)
     return NULL;
+  const Func_Def fdef = (Func_Def)cpy_func_def(env->gwion->mp, value->d.func_ref->def);
   if(vflag(ra->v, vflag_builtin))
     set_vflag(value, vflag_builtin);
-  const Func_Def fdef = (Func_Def)cpy_func_def(env->gwion->mp, value->d.func_ref->def);
   fdef->base->tmpl->call = cpy_type_list(env->gwion->mp, ra->types);
   fdef->base->tmpl->base = i;
   const Func func = ensure_tmpl(env, fdef, ra->e);
   if(!func && !fdef->base->func)
     free_func_def(env->gwion->mp, fdef);
+  if(func && vflag(ra->v, vflag_builtin))
+    set_vflag(func->value_ref, vflag_builtin);
   return func;
 }
 
@@ -115,11 +122,18 @@ ANN static Func find_tmpl(const Env env, const Value v, Exp_Call *const exp, con
   struct ResolverArgs ra = {.v = v, .e = exp, .tmpl_name = tmpl_name, .types = types};
   CHECK_BO(envset_push(&es, v->from->owner_class, v->from->owner))
   (void)env_push(env, v->from->owner_class, v->from->owner);
+if(v->from->owner_class && v->from->owner_class->info->cdef->base.tmpl)
+(void)template_push_types(env, v->from->owner_class->info->cdef->base.tmpl);
+//const Tmpl tmpl = { .list=v->frombase->tmpl->list, .call=ra->types };
+//CHECK_BO(template_push_types(env, &tmpl));
   const Func m_func = !is_fptr(env->gwion, v->type) ?
       func_match(env, &ra) :fptr_match(env, &ra);
+if(v->from->owner_class && v->from->owner_class->info->cdef->base.tmpl)
+nspc_pop_type(env->gwion->mp, env->curr);
+//nspc_pop_type(env->gwion->mp, env->curr);
+  env_pop(env, scope);
   if(es.run)
     envset_pop(&es, v->from->owner_class);
-  env_pop(env, scope);
   env->func = former;
   return m_func;
 }
index 9c743131ddc5c7526ec60132bc30d1f6837d3409..039b1c3d6f6ff6d20a4003be993d44cdfff6a64f 100644 (file)
@@ -22,9 +22,7 @@ static inline void context_global(const Env env) {
 }
 
 static inline Type scan0_type(const Env env, const m_str name, const Type t) {
-  const Type type = new_type(env->gwion->mp, name, t);
-  type->info->ctx = env->context;
-  return type;
+  return new_type(env->gwion->mp, name, t);
 }
 
 ANN static inline m_bool scan0_defined(const Env env, const Symbol s, const loc_t pos) {
@@ -69,22 +67,23 @@ ANN m_bool scan0_fptr_def(const Env env, const Fptr_Def fptr) {
   CHECK_BB(scan0_defined(env, fptr->base->xid, fptr->base->td->pos));
   const m_str name = s_name(fptr->base->xid);
   const Type t = scan0_type(env, name, env->gwion->type[et_fptr]);
-  t->info->owner = !(!env->class_def && GET_FLAG(fptr->base, global)) ?
-    env->curr : env->global_nspc;
-  t->info->owner_class = env->class_def;
-  if(GET_FLAG(fptr->base, global))
-    context_global(env);
+  const bool global = !env->class_def && GET_FLAG(fptr->base, global);
   t->nspc = new_nspc(env->gwion->mp, name);
   t->flag |= fptr->base->flag;
   fptr->type = t;
+  if(global) {
+    context_global(env);
+    env_push_global(env);
+  }
   fptr->value = mk_class(env, t, fptr->base->pos);
+  if(global)
+    env_pop(env, 0);
   valuefrom(env, fptr->value->from, fptr->base->pos);
   fptr_def(env, fptr);
   if(env->class_def)
     fptr_assign(env, fptr);
   set_vflag(fptr->value, vflag_func);
-  add_type(env, t->info->owner, t);
-  mk_class(env, t, fptr->base->pos);
+  add_type(env, t->info->value->from->owner, t);
   type_addref(t);
   return GW_OK;
 }
@@ -119,14 +118,13 @@ ANN static void typedef_simple(const Env env, const Type_Def tdef, const Type ba
   if(GET_FLAG(tdef->ext, global))
     context_global(env);
   add_type(env, nspc, t);
-  t->info->owner = nspc;
-  t->info->owner_class = env->class_def;
   tdef->type = t;
   if(base->nspc)
     nspc_addref((t->nspc = base->nspc));
   t->flag = tdef->ext->flag;
   if(tdef->ext->array && !tdef->ext->array->exp)
     set_tflag(t, tflag_empty);
+  mk_class(env, tdef->type, tdef->pos);
 }
 
 ANN static m_bool typedef_complex(const Env env, const Type_Def tdef, const Type base) {
@@ -136,13 +134,13 @@ ANN static m_bool typedef_complex(const Env env, const Type_Def tdef, const Type
   CHECK_BB(scan0_class_def(env, cdef))
   tdef->type = cdef->base.type;
   cdef->base.tmpl = tdef->tmpl;// check cpy
+  mk_class(env, tdef->type, tdef->pos);
   return GW_OK;
 }
 
 ANN static void typedef_fptr(const Env env, const Type_Def tdef, const Type base) {
   tdef->type = type_copy(env->gwion->mp, base);
   tdef->type->info->func = base->info->func;
-  nspc_addref(tdef->type->nspc);
   tdef->type->name = s_name(tdef->xid);
   tdef->type->info->parent = base;
   add_type(env, env->curr, tdef->type);
@@ -155,6 +153,11 @@ ANN m_bool scan0_type_def(const Env env, const Type_Def tdef) {
   CHECK_BB(env_access(env, tdef->ext->flag, tdef->ext->pos))
   DECL_OB(const Type, base, = tdef->tmpl ? find_type(env, tdef->ext) : known_type(env, tdef->ext))
   CHECK_BB(scan0_defined(env, tdef->xid, tdef->ext->pos))
+  const bool global = GET_FLAG(tdef->ext, global); // TODO: handle global in class
+  if(global) {
+    context_global(env);
+    env_push_global(env);
+  }
   if(isa(base, env->gwion->type[et_function]) < 0) {
     if(!tdef->ext->types && (!tdef->ext->array || !tdef->ext->array->exp))
       typedef_simple(env, tdef, base);
@@ -164,6 +167,8 @@ ANN m_bool scan0_type_def(const Env env, const Type_Def tdef) {
     typedef_fptr(env, tdef, base);
   if(!tdef->distinct && !tdef->when)
     scan0_implicit_similar(env, tdef->type, base);
+  if(global)
+    env_pop(env, 0);
   set_tflag(tdef->type, tflag_typedef);
   return GW_OK;
 }
@@ -185,11 +190,15 @@ ANN static Type enum_type(const Env env, const Enum_Def edef) {
   const Symbol sym = scan0_sym(env, "enum", edef->pos);
   t->name = edef->xid ? s_name(edef->xid) : s_name(sym);
   t->info->parent = env->gwion->type[et_int];
-  const Nspc nspc = GET_FLAG(edef, global) ? env->global_nspc : env->curr;
-  t->info->owner = nspc;
-  t->info->owner_class = env->class_def;
-  add_type(env, nspc, t);
+  const bool global = GET_FLAG(edef, global); // TODO: handle global in class
+  if(global) {
+    context_global(env);
+    env_push_global(env);
+  }
+  add_type(env, env->curr, t);
   mk_class(env, t, edef->pos);
+  if(global)
+    env_pop(env, 0);
 //  scan0_implicit_similar(env, t, env->gwion->type[et_int]);
   return t;
 }
@@ -215,8 +224,7 @@ ANN static Type union_type(const Env env, const Symbol s, const loc_t loc) {
   const m_str name = s_name(s);
   const Type t = new_type(env->gwion->mp, name, env->gwion->type[et_union]);
   t->nspc = new_nspc(env->gwion->mp, name);
-  t->info->owner = t->nspc->parent = env->curr;
-  t->info->owner_class = env->class_def;
+  t->nspc->parent = env->curr;
   t->info->tuple = new_tupleform(env->gwion->mp, NULL); // ???
   add_type(env, env->curr, t);
   mk_class(env, t, loc);
@@ -241,8 +249,11 @@ ANN static void union_tmpl(const Env env, const Union_Def udef) {
 ANN m_bool scan0_union_def(const Env env, const Union_Def udef) {
   CHECK_BB(env_storage(env, udef->flag, udef->pos))
   CHECK_BB(scan0_global(env, udef->flag, udef->pos))
-  const m_uint scope = !GET_FLAG(udef, global) ? env->scope->depth :
-      env_push_global(env);
+  const bool global = GET_FLAG(udef, global); // TODO: handle global in class
+  if(global) {
+    context_global(env);
+    env_push_global(env);
+  }
   if(GET_FLAG(udef, global))
     context_global(env);
   CHECK_BB(scan0_defined(env, udef->xid, udef->pos))
@@ -254,8 +265,8 @@ ANN m_bool scan0_union_def(const Env env, const Union_Def udef) {
   SET_ACCESS(udef, udef->type);
   if(udef->tmpl)
     union_tmpl(env, udef);
-  if(GET_FLAG(udef, global))
-    env_pop(env, scope);
+  if(global)
+    env_pop(env, 0);
   set_tflag(udef->type, tflag_scan0);
   return GW_OK;
 }
@@ -280,7 +291,7 @@ ANN static Type get_parent_base(const Env env, Type_Decl *td) {
   while(owner) {
     if(t == owner)
       ERR_O(td->pos, _("'%s' as parent inside itself\n."), owner->name);
-    owner = owner->info->owner_class;
+    owner = owner->info->value->from->owner_class;
   }
   return t;
 }
@@ -318,13 +329,11 @@ ANN static Type scan0_class_def_init(const Env env, const Class_Def cdef) {
     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;
   t->nspc = new_nspc(env->gwion->mp, t->name);
   t->nspc->parent = env->curr;
   t->info->cdef = cdef;
   t->flag |= cdef->flag;
-  add_type(env, t->info->owner, t);
+//  add_type(env, t->info->value->from->owner, t);
   cdef_flag(cdef, t);
   if(cdef->base.ext && cdef->base.ext->array)
     set_tflag(t, tflag_typedef);
@@ -364,9 +373,10 @@ HANDLE_SECTION_FUNC(scan0, m_bool, Env)
 ANN static m_bool scan0_class_def_inner(const Env env, const Class_Def cdef) {
   CHECK_OB((cdef->base.type = scan0_class_def_init(env, cdef)))
   set_tflag(cdef->base.type, tflag_scan0);
+  (void)mk_class(env, cdef->base.type, cdef->pos);
+  add_type(env, cdef->base.type->info->value->from->owner, cdef->base.type);
   if(cdef->body)
     CHECK_BB(env_body(env, cdef, scan0_section))
-  (void)mk_class(env, cdef->base.type, cdef->pos);
   return GW_OK;
 }
 
index 683cda1ee8c6341159cc3a8de491c5e4898b623f..62e507c6d4545d8a5e4339081ad7658883f74932 100644 (file)
@@ -19,7 +19,7 @@ ANN static inline m_bool type_cyclic(const Env env, const Type t, const Type_Dec
         ERR_B(td->pos, _("%s declared inside %s"), t->name, owner->name);
       parent = parent->info->parent;
     }
-  } while((owner = owner->info->owner_class));
+  } while((owner = owner->info->value->from->owner_class));
   return GW_OK;
 }
 
@@ -52,7 +52,7 @@ ANN static Type scan1_exp_decl_type(const Env env, Exp_Decl* decl) {
   DECL_OO(const Type ,t, = void_type(env, decl->td))
   if(decl->td->xid == insert_symbol("auto") && decl->type)
     return decl->type;
-  if(GET_FLAG(t, private) && t->info->owner != env->curr)
+  if(GET_FLAG(t, private) && t->info->value->from->owner != env->curr)
     ERR_O(exp_self(decl)->pos, _("can't use private type %s"), t->name)
   if(GET_FLAG(t, protect) && (!env->class_def || isa(t, env->class_def) < 0))
     ERR_O(exp_self(decl)->pos, _("can't use protected type %s"), t->name)
@@ -134,7 +134,7 @@ ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) {
   if(global) {
     if(env->context)
       env->context->global = 1;
-    if(!is_global(decl->type->info->owner, env->global_nspc))
+    if(!is_global(decl->type->info->value->from->owner, env->global_nspc))
       ERR_B(exp_self(decl)->pos, _("type '%s' is not global"), decl->type->name)
   }
   const m_uint scope = !global ? env->scope->depth : env_push_global(env);
@@ -332,7 +332,7 @@ ANN m_bool scan1_enum_def(const Env env, const Enum_Def edef) {
       set_vflag(v, vflag_builtin);
     SET_FLAG(v, const);
     set_vflag(v, vflag_valid);
-    nspc_add_value(edef->t->info->owner, list->xid, v);
+    nspc_add_value(edef->t->info->value->from->owner, list->xid, v);
     vector_add(&edef->values, (vtype)v);
   } while((list = list->next));
   return GW_OK;
@@ -643,8 +643,8 @@ ANN m_bool scan1_class_def(const Env env, const Class_Def cdef) {
   if(tflag(t, tflag_scan1))
     return GW_OK;
   set_tflag(t, tflag_scan1);
-  if(t->info->owner_class)
-    CHECK_BB(ensure_scan1(env, t->info->owner_class))
+  if(t->info->value->from->owner_class)
+    CHECK_BB(ensure_scan1(env, t->info->value->from->owner_class))
   if(cdef->base.ext)
     CHECK_BB(cdef_parent(env, cdef))
   if(cdef->body)
index 1cdc281af3dd2fc4e7310381eab7622d1b83b9b5..ef55a3ced173fcdfe0096154f6da89dd25960f60 100644 (file)
@@ -303,8 +303,6 @@ ANN static Type func_type(const Env env, const Func func) {
   const Type t = type_copy(env->gwion->mp, base);
   t->info->parent = base;
   t->name = func->name;
-  t->info->owner = env->curr;
-  t->info->owner_class = env->class_def;
   t->info->func = func;
   return t;
 }
@@ -312,7 +310,7 @@ ANN static Type func_type(const Env env, const Func func) {
 ANN2(1,2) static Value func_value(const Env env, const Func f,
     const Value overload) {
   const Type  t = func_type(env, f);
-  const Value v = new_value(env->gwion->mp, t, t->name);
+  const Value v = t->info->value = new_value(env->gwion->mp, t, t->name);
   valuefrom(env, v->from, f->def->base->pos);
   CHECK_OO(scan2_func_assign(env, f->def, f, v))
   if(!overload) {
@@ -511,7 +509,7 @@ static inline int is_cpy(const Func_Def fdef) {
 }
 
 ANN m_bool scan2_func_def(const Env env, const Func_Def fdef) {
-  if(GET_FLAG(fdef->base, global))
+  if(GET_FLAG(fdef->base, global) && !env->class_def)
     env->context->global = 1;
   const Func_Def f = !is_cpy(fdef) ?
     fdef : scan2_cpy_fdef(env, fdef);
@@ -562,8 +560,8 @@ ANN m_bool scan2_class_def(const Env env, const Class_Def cdef) {
   const Type t = cdef->base.type;
   if(tflag(t, tflag_scan2))
     return GW_OK;
-  if(t->info->owner_class)
-    CHECK_BB(ensure_scan2(env, t->info->owner_class))
+  if(t->info->value->from->owner_class)
+    CHECK_BB(ensure_scan2(env, t->info->value->from->owner_class))
   set_tflag(t, tflag_scan2);
   if(cdef->base.ext)
     CHECK_BB(cdef_parent(env, cdef))
index fe7876421553ee8ef7a522f946ae910e941fecc1..6d5610b4f19e0776cb5122dd43b9da64ce975ab1 100644 (file)
@@ -28,8 +28,8 @@ ANN static m_bool push_types(const Env env, const Tmpl *tmpl) {
 }
 
 ANN static m_bool _template_push(const Env env, const Type t) {
-  if(t->info->owner_class)
-    CHECK_BB(template_push(env, t->info->owner_class))
+  if(t->info->value->from->owner_class)
+    CHECK_BB(template_push(env, t->info->value->from->owner_class))
   if(tflag(t, tflag_tmpl))
     return push_types(env, t->info->cdef->base.tmpl); // incorrect
   return GW_OK;
@@ -55,16 +55,17 @@ ANN Tmpl* mk_tmpl(const Env env, const Tmpl *tm, const Type_List types) {
 
 static ANN Type scan_func(const Env env, const Type t, const Type_Decl* td) {
   DECL_OO(const m_str, tl_name, = tl2str(env->gwion, td->types, td->pos))
-  const Symbol sym = func_symbol(env, t->info->owner->name, t->info->func->name, tl_name, 0);
+  const Symbol sym = func_symbol(env, t->info->value->from->owner->name, t->info->func->name, tl_name, 0);
   free_mstr(env->gwion->mp, tl_name);
-  const Type base_type = nspc_lookup_type1(t->info->owner, sym);
+  const Type base_type = nspc_lookup_type1(t->info->value->from->owner, sym);
   if(base_type)
     return base_type;
   const Type ret = type_copy(env->gwion->mp, t);
   ret->info->parent = t;
+  ret->info->value = t->info->func->value_ref;
   ret->name = s_name(sym);
   set_tflag(ret, tflag_ftmpl);
-  nspc_add_type_front(t->info->owner, sym, ret);
+  nspc_add_type_front(t->info->value->from->owner, sym, ret);
   void* func_ptr = t->info->func->def->d.dl_func_ptr;
   if(vflag(t->info->func->value_ref, vflag_builtin))
     t->info->func->def->d.dl_func_ptr = NULL;
@@ -75,12 +76,12 @@ static ANN Type scan_func(const Env env, const Type t, const Type_Decl* td) {
   if(vflag(t->info->func->value_ref, vflag_member))
     set_vflag(value, vflag_member);
   value->d.func_ref = func;
-  value->from->owner = t->info->owner;
-  value->from->owner_class = t->info->owner_class;
+  value->from->owner = t->info->value->from->owner;
+//  value->from->owner_class = t->info->owner_class;
   func->value_ref = value;
   func->def->base->tmpl = mk_tmpl(env, t->info->func->def->base->tmpl, td->types);
   def->base->func = func;
-  nspc_add_value_front(t->info->owner, sym, value);
+  nspc_add_value_front(t->info->value->from->owner, sym, value);
   if(vflag(t->info->func->value_ref, vflag_builtin)) {
     builtin_func(env->gwion->mp, func, func_ptr);
     t->info->func->def->d.dl_func_ptr = func_ptr;
index 712ad571937d0da42ee65686ff758567eff74106..c9617e3e00d8008d6ff8c9330e784e8ac3945e2a 100644 (file)
@@ -34,7 +34,8 @@ ANN static Type resolve(const Env env, Type_Decl* td) {
     last = last->next;
   Array_Sub array = last->array;
   DECL_OO(const Type, base, = find_type(env, td))
-  if(base->info->ctx && base->info->ctx->error)
+  const Context ctx = base->info->value->from->ctx;
+  if(ctx && ctx->error)
     ERR_O(td->pos, _("type '%s' is invalid"), base->name)
   DECL_OO(const Type, type, = scan_type(env, base, td))
   const Type t = !td->ref ? type : ref(env, td);
index f30e1a1bffaa37bdd6b730e6017ab3766f611770..3581d1bd704ede3e45564f855543659df4bdb601 100644 (file)
@@ -32,7 +32,8 @@ ANN void free_vmcode(VM_Code a, Gwion gwion) {
       free_code_instr(a->instr, gwion);
     }
     free_vector(gwion->mp, a->instr);
-  }
+  } else if(a->tmpl_types.ptr)
+    vector_release(&a->tmpl_types);
   free_mstr(gwion->mp, a->name);
   mp_free(gwion->mp , VM_Code, a);
 }
index 5dbed0f8aa1deec0786282c4b60d4314f7a8f134..2b8ecd53ace55f2a23d3cf0831ab2d65dad45bc4 100644 (file)
@@ -3,6 +3,7 @@ class C:[A,B] {
   var B b;
   fun A test() {
     <<< "lol" >>>;
+    return a;
   }
   fun void test2:[C](C o) {
     <<< o >>>;