]> Nishi Git Mirror - gwion.git/commitdiff
:bug: Fix problems with global
authorfennecdjay <astor.jeremie@wanadoo.fr>
Wed, 25 Sep 2019 22:27:24 +0000 (00:27 +0200)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Wed, 25 Sep 2019 22:27:24 +0000 (00:27 +0200)
20 files changed:
include/context.h
include/type.h
include/value.h
src/emit/emit.c
src/lib/func.c
src/lib/import.c
src/lib/instr.c
src/lib/object.c
src/lib/tuple.c
src/oo/env.c
src/oo/nspc.c
src/oo/value.c
src/parse/check.c
src/parse/operator.c
src/parse/scan0.c
src/parse/scan1.c
src/parse/scan2.c
src/parse/template.c
src/parse/type_decl.c
util

index 3abafca35fde807728f87a18ba7143a0d2414775..61c3fa61bfb7331121974a263107fb40d0e6afd2 100644 (file)
@@ -8,6 +8,7 @@ struct Context_ {
   struct Map_ lbls;
   HAS_OBJ
   m_bool error;
+  m_bool global;
 };
 
 ANN2(2) ANEW Context new_context(MemPool p, const Ast, const m_str);
index 0b67d08ab961c7a4b41ee67fabd07d9f39812f29..c84b17a193860f2642c45dada24cda3c37385dac 100644 (file)
@@ -12,6 +12,7 @@ struct TypeInfo_ {
   struct Vector_ contains;
   struct TupleForm_* tuple;
   struct VM_Code_ *gack;
+  struct Context_ *ctx;
 };
 
 struct Type_ {
index 8f76ed910f3a9fad0c9d7186e8db8cd659ce7ece..14cf3d9d1cf13dd158b2681ae1bbd92f969240dc 100644 (file)
@@ -1,15 +1,20 @@
 #ifndef __VALUE
 #define __VALUE
+struct ValueFrom_ {
+  Nspc owner;
+  Type owner_class;
+  struct Context_ *ctx;
+  size_t offset;
+};
+
 struct Value_ {
   Type type;
   m_str name;
-  Nspc owner;
-  Type owner_class;
+  struct ValueFrom_ *from;
   union value_data{
     m_uint* ptr;
     Func func_ref;
   } d;
-  size_t offset;
   HAS_OBJ
   ae_flag flag;
 };
index f1940cd438d0c6c4173e4382eecabf5585ec75d7..d2e5cdc16285be97ccb1a0ea93d917b2d111381f 100644 (file)
@@ -309,7 +309,7 @@ ANN static inline Exp dot_static_exp(const Emitter emit, const Exp_Primary* prim
 
 ANN static m_bool emit_symbol_owned(const Emitter emit, const Exp_Primary* prim) {
   const Value v = prim->value;
-  const Exp dot = (!GET_FLAG(v, static) ? dot_this_exp : dot_static_exp)(emit, prim, v->owner_class);
+  const Exp dot = (!GET_FLAG(v, static) ? dot_this_exp : dot_static_exp)(emit, prim, v->from->owner_class);
   dot->type = exp_self(prim)->type;
   dot->emit_var = exp_self(prim)->emit_var;
   const m_bool ret = emit_exp_dot(emit, &dot->d.exp_dot);
@@ -347,7 +347,7 @@ ANN static m_bool emit_symbol_builtin(const Emitter emit, const Exp_Primary* pri
 
 ANN static m_bool emit_symbol(const Emitter emit, const Exp_Primary* prim) {
   const Value v = prim->value;
-  if(v->owner_class)
+  if(v->from->owner_class)
     return emit_symbol_owned(emit, prim);
   if(isa(v->type, emit->gwion->type[et_class]) > 0) {
     regpushi(emit, (m_uint)actual_type(emit->gwion, v->type));
@@ -357,9 +357,9 @@ ANN static m_bool emit_symbol(const Emitter emit, const Exp_Primary* prim) {
     return emit_symbol_builtin(emit, prim);
   const m_uint size = v->type->size;
   const Instr instr = emit_kind(emit, size, exp_self(prim)->emit_var, !GET_FLAG(v, global) ? regpushmem : regpushbase);
-  instr->m_val  = v->offset;
+  instr->m_val  = v->from->offset;
   if(isa(v->type, emit->gwion->type[et_function]) > 0 && !is_fptr(emit->gwion, v->type))
-    instr->m_val = exp_self(prim)->type->e->d.func->value_ref->offset;
+    instr->m_val = exp_self(prim)->type->e->d.func->value_ref->from->offset;
   return GW_OK;
 }
 
@@ -594,7 +594,7 @@ ANN static m_bool emit_dot_static_data(const Emitter emit, const Value v, const
   const m_uint size = v->type->size;
   if(isa(v->type, emit->gwion->type[et_class]) < 0) {
     const Instr instr = emit_kind(emit, size, emit_var, dotstatic);
-    instr->m_val = (m_uint)(v->owner->info->class_data + v->offset);
+    instr->m_val = (m_uint)(v->from->owner->info->class_data + v->from->offset);
     instr->m_val2 = size;
   } else
     regpushi(emit, (m_uint)v->type);
@@ -634,15 +634,15 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Var_Decl va
     CHECK_BB(emit_instantiate_object(emit, type, array, is_ref))
   f_instr *exec = (f_instr*)allocmember;
   if(!GET_FLAG(v, member)) {
-    v->offset = emit_local(emit, v->type->size, is_obj);
+    v->from->offset = emit_local(emit, v->type->size, is_obj);
     exec = (f_instr*)(allocword);
     if(GET_FLAG(var_decl->value, ref)) {
       const Instr clean = emit_add_instr(emit, MemSetImm);
-      clean->m_val = v->offset;
+      clean->m_val = v->from->offset;
     }
   }
   const Instr instr = emit_kind(emit, v->type->size, emit_addr, exec);
-  instr->m_val = v->offset;
+  instr->m_val = v->from->offset;
   instr->m_val2 = v->type->size;
   if(is_obj && (is_array || !is_ref)) {
     emit_add_instr(emit, Assign);
@@ -861,7 +861,7 @@ static inline m_bool push_func_code(const Emitter emit, const Func f) {
   const Instr instr = (Instr)vector_back(&emit->code->instr);
   if(instr->opcode == eDotTmplVal) {
     size_t len = strlen(f->name);
-    size_t sz = len - strlen(f->value_ref->owner_class->name);
+    size_t sz = len - strlen(f->value_ref->from->owner_class->name);
     char c[sz + 1];
     memcpy(c, f->name, sz);
     c[sz] = '\0';
@@ -883,7 +883,7 @@ static inline m_bool push_func_code(const Emitter emit, const Func f) {
 
 ANN static m_bool emit_template_code(const Emitter emit, const Func f) {
   const Value v = f->value_ref;
-  size_t scope = emit_push(emit, v->owner_class, v->owner);
+  size_t scope = emit_push(emit, v->from->owner_class, v->from->owner);
   const m_bool ret = emit_func_def(emit, f->def);
   emit_pop(emit, scope);
   return ret > 0 ? push_func_code(emit, f) : GW_ERROR;
@@ -899,7 +899,7 @@ ANN static Instr get_prelude(const Emitter emit, const Func f) {
     if(f->def->base->tmpl) { // TODO: put in func
       struct dottmpl_ *dt = (struct dottmpl_*)mp_calloc(emit->gwion->mp, dottmpl);
       size_t len = strlen(f->name);
-      size_t slen = strlen(f->value_ref->owner->name);
+      size_t slen = strlen(f->value_ref->from->owner->name);
       assert(len > slen);
       size_t sz = len - slen;
       char c[sz + 1];
@@ -909,8 +909,8 @@ ANN static Instr get_prelude(const Emitter emit, const Func f) {
       dt->name = s_name(insert_symbol(c));
       dt->vt_index = f->def->base->tmpl->base;
       dt->base = f->def;
-      dt->owner = f->value_ref->owner;
-      dt->owner_class = f->value_ref->owner_class;
+      dt->owner = f->value_ref->from->owner;
+      dt->owner_class = f->value_ref->from->owner_class;
       const Instr gtmpl = emit_add_instr(emit, GTmpl);
       gtmpl->m_val = (m_uint)dt;
       gtmpl->m_val2 = strlen(c);
@@ -962,12 +962,12 @@ ANN Instr emit_exp_call1(const Emitter emit, const Func f) {
         back->opcode = ePushStaticCode;
         back->m_val = 0;
       }
-    } else if(emit->env->func != f && !f->value_ref->owner_class && !f->code && !is_fptr(emit->gwion, f->value_ref->type)) {
+    } else if(emit->env->func != f && !f->value_ref->from->owner_class && !f->code && !is_fptr(emit->gwion, f->value_ref->type)) {
       const Instr back = !GET_FLAG(f->def, op) ? emit_add_instr(emit, PushStaticCode) : (Instr)vector_back(&emit->code->instr);
       back->m_val = (m_uint)f;
     }
-  } else if((f->value_ref->owner_class && is_special(emit, f->value_ref->owner_class) > 0) ||
-        !f->value_ref->owner_class || (GET_FLAG(f, template) &&
+  } else if((f->value_ref->from->owner_class && is_special(emit, f->value_ref->from->owner_class) > 0) ||
+        !f->value_ref->from->owner_class || (GET_FLAG(f, template) &&
         !is_fptr(emit->gwion, f->value_ref->type)))
     push_func_code(emit, f);
   else if(vector_size(&emit->code->instr)) {
@@ -1283,12 +1283,12 @@ ANN static m_bool emit_stmt_auto(const Emitter emit, const Stmt_Auto stmt) {
   const Instr loop = emit_add_instr(emit, stmt->is_ptr ? AutoLoopPtr : AutoLoop);
   const Instr end = emit_add_instr(emit, BranchEqInt);
   const m_uint offset = emit_local(emit, SZ_INT + stmt->v->type->size, 0);
-  stmt->v->offset = offset + SZ_INT;
+  stmt->v->from->offset = offset + SZ_INT;
   CHECK_BB(emit_stmt(emit, stmt->body, 1))
   const m_uint end_pc = emit_code_size(emit);
   if(stmt->is_ptr) {
     loop->m_val2 = (m_uint)stmt->v->type;
-    cpy->m_val = stmt->v->offset;
+    cpy->m_val = stmt->v->from->offset;
   }
   const Instr tgt = emit_add_instr(emit, Goto);
   end->m_val = emit_code_size(emit);
@@ -1346,10 +1346,10 @@ ANN static m_bool emit_enum_def(const Emitter emit, const Enum_Def edef) {
     const Value v = (Value)vector_at(&edef->values, i);
     if(!emit->env->class_def) {
       ALLOC_PTR(emit->gwion->mp, addr, m_uint, i);
-      v->offset = emit_local(emit, SZ_INT, 0);
+      v->from->offset = emit_local(emit, SZ_INT, 0);
       v->d.ptr = addr;
     } else
-      *(m_bit*)(emit->env->class_def->nspc->info->class_data + v->offset) = i;
+      *(m_bit*)(emit->env->class_def->nspc->info->class_data + v->from->offset) = i;
   }
   return GW_OK;
 }
@@ -1357,7 +1357,7 @@ ANN static m_bool emit_enum_def(const Emitter emit, const Enum_Def edef) {
 ANN void emit_union_offset(Decl_List l, const m_uint o) {
   do {
     Var_Decl_List v = l->self->d.exp_decl.list;
-    do v->self->value->offset = o;
+    do v->self->value->from->offset = o;
     while((v = v->next));
   } while((l = l->next));
 }
@@ -1448,11 +1448,11 @@ ANN static m_bool emit_case_body(const Emitter emit, const struct Stmt_Match_* s
 
 ANN static m_bool case_value(const Emitter emit, const Exp base, const Exp e) {
   const Value v = e->d.exp_primary.value;
-  v->offset = emit_local(emit, base->type->size, isa(base->type, emit->gwion->type[et_object]) > 0);
+  v->from->offset = emit_local(emit, base->type->size, isa(base->type, emit->gwion->type[et_object]) > 0);
   CHECK_BB(emit_exp(emit, base, 1))
   regpop(emit, base->type->size);
   const Instr instr = emit_add_instr(emit, Reg2Mem4);
-  instr->m_val = v->offset;
+  instr->m_val = v->from->offset;
   instr->m_val2 = base->type->size;
   return GW_OK;
 }
@@ -1585,10 +1585,10 @@ ANN static m_bool emit_VecMember(const Emitter emit, const Exp_Dot* member) {
     regpushi(emit, (m_uint)v->d.func_ref->code);
     return GW_OK;
   }
-  if(!v->offset && exp_self(member)->emit_var)
+  if(!v->from->offset && exp_self(member)->emit_var)
     return GW_OK;
   const Instr instr = emit_add_instr(emit, VecMember);
-  instr->m_val2 = v->offset;
+  instr->m_val2 = v->from->offset;
   instr->m_val = exp_self(member)->emit_var;
   return GW_OK;
 }
@@ -1672,7 +1672,7 @@ ANN static m_bool emit_member_func(const Emitter emit, const Exp_Dot* member) {
 ANN static inline m_bool emit_member(const Emitter emit, const Value v, const uint emit_addr) {
   const m_uint size = v->type->size;
   const Instr instr = emit_kind(emit, size, emit_addr, dotmember);
-  instr->m_val = v->offset;
+  instr->m_val = v->from->offset;
   instr->m_val2 = size;
   return GW_OK;
 }
@@ -1699,7 +1699,7 @@ ANN static m_bool emit_exp_dot(const Emitter emit, const Exp_Dot* member) {
 
 ANN static inline void emit_func_def_global(const Emitter emit, const Value value) {
   const Instr set_mem = emit_add_instr(emit, MemSetImm);
-  set_mem->m_val = value->offset;
+  set_mem->m_val = value->from->offset;
   set_mem->m_val2 = (m_uint)value->d.func_ref->code;
 }
 
@@ -1716,7 +1716,7 @@ ANN static void emit_func_def_args(const Emitter emit, Arg_List a) {
     const m_uint size = value->type->size;
     const m_bool obj = isa(value->type, emit->gwion->type[et_object]) > 0;
     emit->code->stack_depth += size;
-    value->offset = emit_local(emit, size, obj);
+    value->from->offset = emit_local(emit, size, obj);
   } while((a = a->next));
 }
 
@@ -1795,7 +1795,7 @@ ANN static m_bool emit_func_def(const Emitter emit, const Func_Def fdef) {
   if(SAFE_FLAG(emit->env->class_def, builtin) && GET_FLAG(emit->env->class_def, template))
     return GW_OK;
   if(!emit->env->class_def && !GET_FLAG(fdef, global) && !fdef->base->tmpl && !emit->env->scope->depth)
-    func->value_ref->offset = emit_local(emit, SZ_INT, 0);
+    func->value_ref->from->offset = emit_local(emit, SZ_INT, 0);
   emit_func_def_init(emit, func);
   if(GET_FLAG(func, member))
     stack_alloc_this(emit);
index f29b49667ea41d04737eff3753dd085aa71742e8..e5badaf04f412f27415474dd297bf39b8b5bc5f2 100644 (file)
@@ -95,8 +95,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) {
-  const Type l_type = info->lhs->value_ref->owner_class;
-  const Type r_type = info->rhs->value_ref->owner_class;
+  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)
     ERR_B(info->pos, _("can't assign member function to non member function pointer"))
   else if(!l_type && r_type) {
@@ -125,11 +125,11 @@ ANN static inline m_bool fptr_arity(struct FptrInfo *info) {
 
 ANN static Type fptr_type(const Env env, struct FptrInfo *info) {
   const Value v = info->lhs->value_ref;
-  const Nspc nspc = v->owner;
+  const Nspc nspc = v->from->owner;
   const m_str c = s_name(info->lhs->def->base->xid),
     stmpl = !info->rhs->def->base->tmpl ? NULL : "template";
   Type type = NULL;
-  for(m_uint i = 0; i <= v->offset && !type; ++i) {
+  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(isa(info->lhs->value_ref->type, env->gwion->type[et_class]) < 0)
@@ -178,7 +178,7 @@ ANN2(1,3,4) m_bool check_lambda(const Env env, const Type owner,
 
 ANN static m_bool fptr_lambda(const Env env, struct FptrInfo *info) {
   Exp_Lambda *l = &info->exp->d.exp_lambda;
-  const Type owner = info->rhs->value_ref->owner_class;
+  const Type owner = info->rhs->value_ref->from->owner_class;
   return check_lambda(env, owner, l, info->rhs->def);
 }
 
index 37601216f79b27f0ca6facebb0529168d81b2a84..661219550009c8488c28df1aaf35deabf59d1a8b 100644 (file)
@@ -357,7 +357,7 @@ ANN2(1) m_int gwi_item_end(const Gwi gwi, const ae_flag flag, const m_uint* addr
 if(v->var.value->type->array_depth)
 ADD_REF(v->var.value->type);
   dl_var_release(gwi->gwion->mp, v);
-  return (m_int)v->var.value->offset;
+  return (m_int)v->var.value->from->offset;
 }
 
 static Array_Sub make_dll_arg_list_array(MemPool p, Array_Sub array_sub,
index 7c922cab3af27f044737c8abe61e3421c21c3f13..6a49ec0c787f771265c491c1fba9215922492691 100644 (file)
@@ -47,8 +47,8 @@ ANN static Func_Def from_base(const Env env, struct dottmpl_ *const dt, const Ns
   def->base->tmpl->call = dt->tl;
   def->base->tmpl->base = dt->vt_index;
   dt->def = def;
-  dt->owner = v->owner;
-  dt->owner_class = v->owner_class;
+  dt->owner = v->from->owner;
+  dt->owner_class = v->from->owner_class;
   SET_FLAG(def, template);
   return def;
 }
@@ -66,10 +66,10 @@ INSTR(GTmpl) {
   const Emitter emit = shred->info->vm->gwion->emit;
   emit->env->name = "runtime";
   m_str tmpl_name = tl2str(emit->env, dt->tl);
-  for(m_uint i = 0 ; i <= f->value_ref->offset; ++i) {
-    const Symbol sym = func_symbol(emit->env, f->value_ref->owner->name,
+  for(m_uint i = 0 ; i <= f->value_ref->from->offset; ++i) {
+    const Symbol sym = func_symbol(emit->env, f->value_ref->from->owner->name,
       name, tmpl_name, i);
-    const Func base = nspc_lookup_func0(f->value_ref->owner, sym);
+    const Func base = nspc_lookup_func0(f->value_ref->from->owner, sym);
     if(base) {
       free_mstr(emit->gwion->mp, tmpl_name);
       assert(base->code);
@@ -79,7 +79,7 @@ INSTR(GTmpl) {
   }
   free_mstr(emit->gwion->mp, tmpl_name);
   dt->def = f->def;
-  const Func_Def def = traverse_tmpl(emit, dt, f->value_ref->owner);
+  const Func_Def def = traverse_tmpl(emit, dt, f->value_ref->from->owner);
   if(!def)
     Except(shred, "MissigTmplPtrException[internal]");
   *(VM_Code*)(shred->reg -SZ_INT) = def->base->func->code;
index daf0aad030306be5d11f7701668cf7d1995df65b..14da66cc521ceae19ab5344d50754fce89e2e998 100644 (file)
@@ -73,7 +73,7 @@ ANN void __release(const M_Object o, const VM_Shred shred) {
     while(scope_iter(&iter, &v) > 0) {
       if(!GET_FLAG(v, static) && !GET_FLAG(v, pure) &&
           isa(v->type, shred->info->vm->gwion->type[et_object]) > 0)
-        release(*(M_Object*)(o->data + v->offset), shred);
+        release(*(M_Object*)(o->data + v->from->offset), shred);
     }
     if(GET_FLAG(t, dtor) && t->nspc->dtor) {
       if(GET_FLAG(t->nspc->dtor, builtin))
index c1df7b3e02ec0beb7946bdbc97deb89259d7391b..a2c11fb98f310fd9f6ae5b0be9e37159516d098b 100644 (file)
@@ -93,8 +93,7 @@ ANN static void unpack_instr_decl(const Emitter emit, struct TupleEmit *te) {
       const Value value = te->e->d.exp_decl.list->self->value;
       te->sz += value->type->size;
       sz += value->type->size;
-      value->offset = emit_local(emit, value->type->size, 0);
-printf("value->offset %lu\n", value->offset);
+      value->from->offset = emit_local(emit, value->type->size, 0);
     } else {
       sz += ((Type)vector_at(te->v, te->idx))->size;
       break;
index aece42e0ae49b45575a879c847f9b7fca9e4d113..fb5e8bc481cd3f02f32f0ee4935093a330516bd0 100644 (file)
@@ -90,8 +90,8 @@ ANN void env_add_type(const Env env, const Type type) {
   const Value v = new_value(env->gwion->mp, v_type, s_name(sym));
   SET_FLAG(v, checked | ae_flag_const | ae_flag_global | ae_flag_builtin);
   nspc_add_value(env->curr, insert_symbol(type->name), v);
-  v->owner = type->e->owner = env->curr;
-  v->owner_class = env->class_def;
+  v->from->owner = type->e->owner = env->curr;
+  v->from->owner_class = env->class_def;
   type->xid = ++env->scope->type_xid;
 }
 
@@ -100,10 +100,11 @@ ANN m_bool type_engine_check_prog(const Env env, const Ast ast) {
   env_reset(env);
   load_context(ctx, env);
   const m_bool ret = traverse_ast(env, ast);
-  if(ret > 0) {
+  if(ret > 0) //{
     nspc_commit(env->curr);
+  if(ret || env->context->global)
     vector_add(&env->scope->known_ctx, (vtype)ctx);
-  else //nspc_rollback(env->global_nspc);
+  else //nspc_rollback(env->global_nspc);
     REM_REF(ctx, env->gwion);
   unload_context(ctx, env);
   return ret;
index 7490e778f8f09247496cffb56bbf5164d0c90c32..5075deca40b8d4c1068a7469ae9d9ff14790ce41 100644 (file)
@@ -22,7 +22,7 @@ ANN static inline void nspc_release_object(const Nspc a, Value value, Gwion gwio
   if((GET_FLAG(value, static) && a->info->class_data) ||
     (value->d.ptr && GET_FLAG(value, builtin))) {
     const M_Object obj = value->d.ptr ? (M_Object)value->d.ptr :
-        *(M_Object*)(a->info->class_data + value->offset);
+        *(M_Object*)(a->info->class_data + value->from->offset);
        release(obj, gwion->vm->cleaner_shred);
   }
 }
index f0398620dd2c209a23b4e379b572ba449837c9ae..b728e45616edc5d6d07f97ab1c6fec8824c4225d 100644 (file)
 ANN static void free_value(Value a, Gwion gwion) {
   const Type t = a->type;
   if(!GET_FLAG(a, func) && a->d.ptr && !GET_FLAG(a, union) &&
-      !(GET_FLAG(a, enum) && GET_FLAG(a, builtin) && a->owner_class)
+      !(GET_FLAG(a, enum) && GET_FLAG(a, builtin) && a->from->owner_class)
       && isa(t, gwion->type[et_object]) < 0)
    _mp_free(gwion->mp, t->size, a->d.ptr);
   if(isa(t, gwion->type[et_class]) > 0/* || isa(a->type, t_function) > 0*/)
     REM_REF(t, gwion)
+  mp_free(gwion->mp, ValueFrom, a->from);
   mp_free(gwion->mp, Value, a);
 }
 
 ANN Value new_value(MemPool p, const Type type, const m_str name) {
   const Value a = mp_calloc(p, Value);
+  a->from = mp_calloc(p, ValueFrom);
   a->type       = type;
   a->name       = name;
   a->ref = new_refcount(p, free_value);
index 1905510c350494e8bb7232cab14c1ea49784b33d..4435bec7b31032925a4d9e2a25538c7fa2536d25 100644 (file)
@@ -22,6 +22,7 @@
 #include "tuple.h"
 #include "emit.h"
 #include "specialid.h"
+#include "context.h"
 
 ANN static Type   check_exp(const Env env, Exp exp);
 ANN static m_bool check_stmt_list(const Env env, Stmt_List list);
@@ -41,15 +42,15 @@ ANN static inline m_bool check_exp_decl_parent(const Env env, const Var_Decl var
     ERR_B(var->pos,
           _("in class '%s': '%s' has already been defined in parent class '%s' ..."),
           env->class_def->name, s_name(var->xid),
-          value->owner_class ? value->owner_class->name : "?")
+          value->from->owner_class ? value->from->owner_class->name : "?")
   return GW_OK;
 }
 
 #define describe_check_decl(a, b)                                 \
-ANN static inline void decl_##a(const Env env, const Value v) { \
+ANN static inline void decl_##a(const Env env, const Value v) {   \
   const Nspc nspc = env->curr;\
   SET_FLAG(v, a);                                                 \
-  v->offset = nspc->info->b;                                      \
+  v->from->offset = nspc->info->b;                                \
   nspc->info->b += v->type->size;                                 \
 }
 describe_check_decl(member, offset)
@@ -58,7 +59,7 @@ describe_check_decl(static, class_data_size)
 ANN static m_bool check_fptr_decl(const Env env, const Var_Decl var) {
   const Value v    = var->value;
   const Func  func = v->type->e->d.func;
-  const Type type = func->value_ref->owner_class;
+  const Type type = func->value_ref->from->owner_class;
   if(!env->class_def) {
     if(!type || GET_FLAG(func, global))
       return GW_OK;
@@ -191,10 +192,10 @@ ANN static Type prim_array(const Env env, const Exp_Primary* primary) {
 
 ANN static inline m_bool not_from_owner_class(const Env env, const Type t,
       const Value v, const loc_t pos) {
-  if(!v->owner_class || isa(t, v->owner_class) < 0) {
+  if(!v->from->owner_class || isa(t, v->from->owner_class) < 0) {
     ERR_B(pos,
         _("'%s' from owner namespace '%s' used in '%s'."),
-            v->name, v->owner ? v->owner->name : "?", t->name)
+            v->name, v->from->owner ? v->from->owner->name : "?", t->name)
   }
   return GW_OK;
 }
@@ -204,7 +205,7 @@ ANN static Value check_non_res_value(const Env env, const Exp_Primary* primary)
   if(env->class_def) {
     const Value v = value ? value : find_value(env->class_def, primary->d.var);
     if(v) {
-      if(v->owner_class)
+      if(v->from->owner_class)
         CHECK_BO(not_from_owner_class(env, env->class_def, v, exp_self(primary)->pos))
       if(env->func && GET_FLAG(env->func->def, static) && GET_FLAG(v, member))
         ERR_O(exp_self(primary)->pos,
@@ -221,16 +222,16 @@ ANN static Value check_non_res_value(const Env env, const Exp_Primary* primary)
 
 ANN static Type prim_id_non_res(const Env env, const Exp_Primary* primary) {
   const Value v = check_non_res_value(env, primary);
-  if(!v || !GET_FLAG(v, checked)) {
+  if(!v || !GET_FLAG(v, checked) || (v->from->ctx && v->from->ctx->error)) {
     env_err(env, exp_self(primary)->pos,
           _("variable %s not legit at this point."), s_name(primary->d.var));
-    if(v && v->owner_class)
-      did_you_mean_type(v->owner_class, s_name(primary->d.var));
+    if(v && v->from->owner_class)
+      did_you_mean_type(v->from->owner_class, s_name(primary->d.var));
     else
-      did_you_mean_nspc(v ? v->owner : env->curr, s_name(primary->d.var));
+      did_you_mean_nspc(v ? v->from->owner : env->curr, s_name(primary->d.var));
     return NULL;
   }
-  if(env->func && !GET_FLAG(v, const) && v->owner)
+  if(env->func && !GET_FLAG(v, const) && v->from->owner)
     UNSET_FLAG(env->func, pure);
   SET_FLAG(v, used);
   ((Exp_Primary*)primary)->value = v;
@@ -471,10 +472,10 @@ ANN2(1,2) static Func find_func_match_actual(const Env env, Func func, const Exp
       }
       if(e1->type == env->gwion->type[et_undefined] ||
             (func->def->base->tmpl && is_fptr(env->gwion, func->value_ref->type) > 0)) {
-        if(SAFE_FLAG(func->value_ref->owner_class, template))
-          CHECK_BO(template_push_types(env, func->value_ref->owner_class->e->def->base.tmpl))
+        if(SAFE_FLAG(func->value_ref->from->owner_class, template))
+          CHECK_BO(template_push_types(env, func->value_ref->from->owner_class->e->def->base.tmpl))
           e1->type = known_type(env, e1->td);
-        if(SAFE_FLAG(func->value_ref->owner_class, template))
+        if(SAFE_FLAG(func->value_ref->from->owner_class, template))
           nspc_pop_type(env->gwion->mp, env->curr);
         CHECK_OO(e1->type)
       }
@@ -511,9 +512,9 @@ ANN static m_bool check_call(const Env env, const Exp_Call* exp) {
 }
 
 ANN static inline Value template_get_ready(const Env env, const Value v, const m_str tmpl, const m_uint i) {
-  const Symbol sym = func_symbol(env, v->owner->name, v->name, tmpl, i);
-  return v->owner_class ? find_value(v->owner_class, sym) :
-      nspc_lookup_value1(v->owner, sym);
+  const Symbol sym = func_symbol(env, v->from->owner->name, v->name, tmpl, i);
+  return v->from->owner_class ? find_value(v->from->owner_class, sym) :
+      nspc_lookup_value1(v->from->owner, sym);
 }
 
 static Func ensure_tmpl(const Env env, const Func_Def fdef, const Exp_Call *exp) {
@@ -552,10 +553,10 @@ CHECK_BO(check_call(env, exp))
   const Type_List types = exp->tmpl->call;
   Func m_func = NULL, former = env->func;
   DECL_OO(const m_str, tmpl_name, = tl2str(env, types))
-  const m_uint scope = env_push(env, v->owner_class, v->owner);
+  const m_uint scope = env_push(env, v->from->owner_class, v->from->owner);
   if(is_fptr(env->gwion, v->type)) {
-    const Symbol sym = func_symbol(env, v->owner->name, v->name, tmpl_name, 0);
-    const Value value = nspc_lookup_value1(v->owner, sym);
+    const Symbol sym = func_symbol(env, v->from->owner->name, v->name, tmpl_name, 0);
+    const Value value = nspc_lookup_value1(v->from->owner, sym);
     Func_Def base = v->d.func_ref ? v->d.func_ref->def : exp->func->type->e->d.func->def;
     Func_Base *fbase = cpy_func_base(env->gwion->mp, base->base);
     fbase->xid = sym;
@@ -573,12 +574,12 @@ CHECK_BO(check_call(env, exp))
         m_func = find_func_match(env, fbase->func, exp->args);
         nspc_pop_type(env->gwion->mp, env->curr);
         if(!value && m_func)
-          nspc_add_type_front(v->owner, sym, actual_type(env->gwion, m_func->value_ref->type));
+          nspc_add_type_front(v->from->owner, sym, actual_type(env->gwion, m_func->value_ref->type));
       }
       free_fptr_def(env->gwion->mp, fptr); // ???? related
     }
   } else {
-    for(m_uint i = 0; i < v->offset + 1; ++i) {
+    for(m_uint i = 0; i < v->from->offset + 1; ++i) {
       const Value exists = template_get_ready(env, v, tmpl_name, i);
       if(exists) {
         if(env->func == exists->d.func_ref) {
@@ -613,7 +614,7 @@ ANN Func find_template_match(const Env env, const Value value, const Exp_Call* e
   const Func f = _find_template_match(env, value, exp);
   if(f)
     return f;
-  Type t = value->owner_class;
+  Type t = value->from->owner_class;
   while(t) {
     const Value v = nspc_lookup_value0(t->nspc, value->d.func_ref->def->base->xid);
     if(!v)
@@ -706,7 +707,7 @@ ANN static Type check_exp_call_template(const Env env, Exp_Call *exp) {
   if(tm->call) {
     DECL_OO(const Func, func, = value->d.func_ref ?: predefined_func(env, value, exp, tm))
     if(!func->def->base->ret_type) { // template fptr
-      const m_uint scope = env_push(env, value->owner_class, value->owner);
+      const m_uint scope = env_push(env, value->from->owner_class, value->from->owner);
       CHECK_BO(traverse_func_def(env, func->def))
       env_pop(env, scope);
     }
@@ -778,8 +779,8 @@ ANN Type check_exp_call1(const Env env, const Exp_Call *exp) {
     return check_lambda_call(env, exp);
   if(GET_FLAG(exp->func->type->e->d.func, ref)) {
     const Value value = exp->func->type->e->d.func->value_ref;
-    if(value->owner_class)
-      CHECK_BO(traverse_class_def(env, value->owner_class->e->def))
+    if(value->from->owner_class)
+      CHECK_BO(traverse_class_def(env, value->from->owner_class->e->def))
   }
   if(exp->args)
     CHECK_OO(check_exp(env, exp->args))
@@ -910,7 +911,7 @@ ANN static Type check_exp_dot(const Env env, Exp_Dot* member) {
     return NULL;
   }
   CHECK_BO(not_from_owner_class(env, the_base, value, exp_self(member)->pos))
-  if(!env->class_def || isa(env->class_def, value->owner_class) < 0) {
+  if(!env->class_def || isa(env->class_def, value->from->owner_class) < 0) {
     if(GET_FLAG(value, private))
       ERR_O(exp_self(member)->pos,
           _("can't access private '%s' outside of class..."), value->name)
@@ -1256,8 +1257,8 @@ ANN static m_bool check_stmt_list(const Env env, Stmt_List l) {
 
 ANN static m_bool check_signature_match(const Env env, const Func_Def fdef, const Func parent) {
   if(GET_FLAG(parent->def, static) != GET_FLAG(fdef, static)) {
-    const m_str c_name  = fdef->base->func->value_ref->owner_class->name;
-    const m_str p_name = parent->value_ref->owner_class->name;
+    const m_str c_name  = fdef->base->func->value_ref->from->owner_class->name;
+    const m_str p_name = parent->value_ref->from->owner_class->name;
     const m_str f_name = s_name(fdef->base->xid);
     ERR_B(td_pos(fdef->base->td),
           _("function '%s.%s' ressembles '%s.%s' but cannot override...\n"
@@ -1309,9 +1310,9 @@ ANN static inline Func get_overload(const Env env, const Func_Def fdef, const m_
 
 ANN static m_bool check_func_overload(const Env env, const Func_Def fdef) {
   const Value v = fdef->base->func->value_ref;
-  for(m_uint i = 0; i <= v->offset; ++i) {
+  for(m_uint i = 0; i <= v->from->offset; ++i) {
     const Func f1 = get_overload(env, fdef, i);
-    for(m_uint j = i + 1; f1 && j <= v->offset; ++j) {
+    for(m_uint j = i + 1; f1 && j <= v->from->offset; ++j) {
       const Func f2 = get_overload(env, fdef, j);
       if(f2 && compat_func(f1->def, f2->def) > 0)
         ERR_B(td_pos(f2->def->base->td), _("global function '%s' already defined"
@@ -1325,13 +1326,13 @@ ANN static m_bool check_func_def_override(const Env env, const Func_Def fdef) {
   const Func func = fdef->base->func;
   if(env->class_def && env->class_def->e->parent) {
     const Value override = find_value(env->class_def->e->parent, fdef->base->xid);
-    if(override && override->owner_class && isa(override->type, env->gwion->type[et_function]) < 0)
+    if(override && override->from->owner_class && isa(override->type, env->gwion->type[et_function]) < 0)
       ERR_B(fdef->pos,
             _("function name '%s' conflicts with previously defined value...\n"
             "  from super class '%s'..."),
-            s_name(fdef->base->xid), override->owner_class->name)
+            s_name(fdef->base->xid), override->from->owner_class->name)
   }
-  if(func->value_ref->offset && (!fdef->base->tmpl || !fdef->base->tmpl->base))
+  if(func->value_ref->from->offset && (!fdef->base->tmpl || !fdef->base->tmpl->base))
     CHECK_BB(check_func_overload(env, fdef))
   return GW_OK;
 }
index 78ca400b0fb70b0743cb028ee1dbe4dbef8890da..a5d35166f7b58a74ac96c7460710e156ae725c9a 100644 (file)
@@ -186,7 +186,7 @@ ANN Type op_check(const Env env, struct Op_Import* opi) {
 }
 
 ANN m_bool operator_set_func(const struct Op_Import* opi) {
-  const Nspc nspc = ((Func)opi->data)->value_ref->owner;
+  const Nspc nspc = ((Func)opi->data)->value_ref->from->owner;
   const Vector v = (Vector)map_get(&nspc->info->op_map, (vtype)opi->op);
   DECL_OB(M_Operator*, mo, = operator_find(v, opi->lhs, opi->rhs))
   mo->func = (Func)opi->data;
index eba8f72a35de8cb7df66584402c7c3623743ae88..43d8ba52328b03990bc8bf9e1dc661e738c2b165 100644 (file)
 #include "operator.h"
 #include "import.h"
 
+#include "context.h"
+
 static inline void add_type(const Env env, const Nspc nspc, const Type t) {
   nspc_add_type_front(nspc, insert_symbol(t->name), t);
 }
 
+static inline Type scan0_type(const Env env, const m_uint xid,
+    const m_str name, const Type t) {
+  const Type type = new_type(env->gwion->mp, xid, name, t);
+  type->e->ctx = env->context;
+  return type;
+}
+
 ANN static Value mk_class(const Env env, const Type base) {
   const Symbol sym = insert_symbol(base->name);
   const Type t = type_copy(env->gwion->mp, env->gwion->type[et_class]);
+t->e->ctx = env->context;
   const Value v = new_value(env->gwion->mp, t, s_name(sym));
   t->e->d.base_type = base;
-  v->owner = base->e->owner;
+// set from
+  v->from->owner = base->e->owner;
   SET_FLAG(v, const | ae_flag_checked);
   nspc_add_value_front(base->e->owner, sym, v);
   return v;
@@ -42,6 +53,7 @@ ANN static inline m_bool scan0_defined(const Env env, const Symbol s, const loc_
 ANN static void fptr_assign(const Env env, const Fptr_Def fptr) {
   const Func_Def def = fptr->type->e->d.func->def;
   if(GET_FLAG(fptr->base->td, global)) {
+    env->context->global = 1;
     SET_FLAG(fptr->value, global);
     SET_FLAG(fptr->base->func, global);
     SET_FLAG(def, global);
@@ -57,7 +69,7 @@ ANN static void fptr_assign(const Env env, const Fptr_Def fptr) {
   }
   if(GET_FLAG(def, variadic))
     def->stack_depth += SZ_INT;
-  fptr->value->owner_class = env->class_def;
+  fptr->value->from->owner_class = env->class_def;
 }
 
 static void fptr_def(const Env env, const Fptr_Def fptr) {
@@ -76,15 +88,18 @@ ANN m_bool scan0_fptr_def(const Env env, const Fptr_Def fptr) {
   CHECK_OB(known_type(env, fptr->base->td))
   CHECK_BB(scan0_defined(env, fptr->base->xid, td_pos(fptr->base->td)));
   const m_str name = s_name(fptr->base->xid);
-  const Type t = new_type(env->gwion->mp, env->gwion->type[et_fptr]->xid, name, env->gwion->type[et_fptr]);
+  const Type t = scan0_type(env, env->gwion->type[et_fptr]->xid, name, env->gwion->type[et_fptr]);
   t->e->owner = !(!env->class_def && GET_FLAG(fptr->base->td, global)) ?
     env->curr : env->global_nspc;
+  if(GET_FLAG(fptr->base->td, global))
+    env->context->global = 1;
   t->nspc = new_nspc(env->gwion->mp, name);
   t->flag = fptr->base->td->flag;
   fptr->type = t;
   fptr->value = mk_class(env, t);
-  fptr->value->owner = env->curr;
-  fptr->value->owner_class = env->class_def;
+// set owner ?
+  fptr->value->from->owner = env->curr;
+  fptr->value->from->owner_class = env->class_def;
   fptr_def(env, fptr);
   if(env->class_def)
     fptr_assign(env, fptr);
@@ -106,10 +121,12 @@ ANN static void scan0_implicit_similar(const Env env, const Type lhs, const Type
 }
 
 ANN static void typedef_simple(const Env env, const Type_Def tdef, const Type base) {
-  const Type t = new_type(env->gwion->mp, ++env->scope->type_xid, s_name(tdef->xid), base);
+  const Type t = scan0_type(env, ++env->scope->type_xid, s_name(tdef->xid), base);
   t->size = base->size;
   const Nspc nspc = (!env->class_def && GET_FLAG(tdef->ext, global)) ?
   env->global_nspc : env->curr;
+  if(GET_FLAG(tdef->ext, global))
+    env->context->global = 1;
   add_type(env, nspc, t);
   t->e->owner = nspc;
   tdef->type = t;
@@ -172,6 +189,8 @@ ANN m_bool scan0_enum_def(const Env env, const Enum_Def edef) {
   t->e->parent = env->gwion->type[et_int];
   const Nspc nspc = GET_FLAG(edef, global) ? env->global_nspc : env->curr;
   t->e->owner = nspc;
+  if(GET_FLAG(edef, global))
+    env->context->global = 1;
   edef->t = t;
   if(edef->xid) {
     add_type(env, nspc, t);
@@ -202,6 +221,8 @@ ANN m_bool scan0_union_def(const Env env, const Union_Def udef) {
   CHECK_BB(env_storage(env, udef->flag, udef->pos))
   const m_uint scope = !GET_FLAG(udef, global) ? env->scope->depth :
       env_push_global(env);
+  if(GET_FLAG(udef, global))
+    env->context->global = 1;
   if(udef->xid) {
     CHECK_BB(scan0_defined(env, udef->xid, udef->pos))
     const Nspc nspc = !GET_FLAG(udef, global) ?
@@ -209,8 +230,10 @@ ANN m_bool scan0_union_def(const Env env, const Union_Def udef) {
     const Type t = union_type(env, nspc, udef->type_xid ?: udef->xid,
        !!udef->type_xid);
     udef->value = new_value(env->gwion->mp, t, s_name(udef->xid));
-    udef->value->owner_class = env->class_def;
-    udef->value->owner = nspc;
+// set owner ?
+    udef->value->from->owner_class = env->class_def;
+    udef->value->from->owner = nspc;
+    udef->value->from->ctx = env->context;
     nspc_add_value(nspc, udef->xid, udef->value);
     add_type(env, nspc, t);
     SET_FLAG(t, scan1 | ae_flag_union);
@@ -236,8 +259,9 @@ ANN m_bool scan0_union_def(const Env env, const Union_Def udef) {
     const Symbol sym = insert_symbol(name);
     const Type t = union_type(env, nspc, sym, 1);
     udef->value = new_value(env->gwion->mp, t, s_name(sym));
-    udef->value->owner_class = env->class_def;
-    udef->value->owner = nspc;
+    udef->value->from->owner_class = env->class_def;
+    udef->value->from->owner = nspc;
+    udef->value->from->ctx = env->context;
     nspc_add_value(nspc, udef->xid, udef->value);
     add_type(env, nspc, t);
     SET_FLAG(udef->value, checked | udef->flag);
@@ -269,6 +293,7 @@ ANN static m_bool scan0_class_def_pre(const Env env, const Class_Def cdef) {
   if(GET_FLAG(cdef, global)) {
     vector_add(&env->scope->nspc_stack, (vtype)env->curr);
     env->curr = env->global_nspc;
+    env->context->global = 1;
   }
   CHECK_BB(scan0_defined(env, cdef->base.xid, cdef->pos))
   CHECK_BB(isres(env, cdef->base.xid, cdef->pos))
@@ -276,7 +301,7 @@ ANN static m_bool scan0_class_def_pre(const Env env, const Class_Def cdef) {
 }
 
 ANN static Type scan0_class_def_init(const Env env, const Class_Def cdef) {
-  const Type t = new_type(env->gwion->mp, ++env->scope->type_xid, s_name(cdef->base.xid), env->gwion->type[et_object]);
+  const Type t = scan0_type(env, ++env->scope->type_xid, s_name(cdef->base.xid), env->gwion->type[et_object]);
   t->e->owner = env->curr;
   t->nspc = new_nspc(env->gwion->mp, t->name);
 //  t->nspc->parent = GET_FLAG(cdef, global) ? env_nspc(env) : env->curr;
index 3c11b15295e53a025dd949e705ce506a6655b417..7c3672fa85e6156e4e6f2a783411bd1fd436532b 100644 (file)
@@ -10,6 +10,7 @@
 #include "traverse.h"
 #include "template.h"
 #include "parse.h"
+#include "context.h"
 
 ANN static m_bool scan1_stmt_list(const Env env, Stmt_List list);
 ANN static m_bool scan1_stmt(const Env env, Stmt stmt);
@@ -71,6 +72,8 @@ ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) {
   ((Exp_Decl*)decl)->type = scan1_exp_decl_type(env, (Exp_Decl*)decl);
   CHECK_OB(decl->type)
   const m_bool global = GET_FLAG(decl->td, global);
+  if(env->context)
+    env->context->global = 1;
   const m_uint scope = !global ? env->scope->depth : env_push_global(env);
   const Nspc nspc = !global ? env->curr : env->global_nspc;
   do {
@@ -102,8 +105,10 @@ ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) {
     if(!env->scope->depth && !env->class_def)
       SET_FLAG(v, global);
     v->d.ptr = var->addr;
-    v->owner = !env->func ? env->curr : NULL;
-    v->owner_class = env->scope->depth ? NULL : env->class_def;
+// set from ?
+    v->from->owner = !env->func ? env->curr : NULL;
+    v->from->owner_class = env->scope->depth ? NULL : env->class_def;
+    v->from->ctx = env->context;
   } while((list = list->next));
   ((Exp_Decl*)decl)->type = decl->list->self->value->type;
   if(global)
@@ -235,11 +240,13 @@ ANN m_bool scan1_enum_def(const Env env, const Enum_Def edef) {
     CHECK_BB(already_defined(env, list->xid, edef->pos))
     const Value v = new_value(env->gwion->mp, edef->t, s_name(list->xid));
     if(env->class_def) {
-      v->owner_class = env->class_def;
+      v->from->owner_class = env->class_def;
       SET_FLAG(v, static);
       SET_ACCESS(edef, v)
     }
-    v->owner = env->curr;
+// set from ?
+    v->from->owner = env->curr;
+    v->from->ctx = env->context;
     SET_FLAG(v, const | ae_flag_enum | ae_flag_checked);
     nspc_add_value(edef->t->e->owner, list->xid, v);
     vector_add(&edef->values, (vtype)v);
index f239b9cdccbf7e14d0e90237c16c5459da04d728..b3f4f81e41edf27355e50809207216a9901c97ac 100644 (file)
@@ -62,7 +62,7 @@ ANN static m_bool scan2_args(const Env env, const Func_Def f) {
     if(var->array)
       list->type = array_type(env, list->type, var->array->depth);
     var->value = arg_value(env->gwion->mp, list);
-    var->value->offset = f->stack_depth;
+    var->value->from->offset = f->stack_depth;
     f->stack_depth += list->type->size;
   } while((list = list->next));
   return GW_OK;
@@ -70,9 +70,11 @@ ANN static m_bool scan2_args(const Env env, const Func_Def f) {
 
 ANN static Value scan2_func_assign(const Env env, const Func_Def d,
     const Func f, const Value v) {
-  v->owner = env->curr;
+// set from ?
+  v->from->owner = env->curr;
+  v->from->ctx = env->context;
   SET_FLAG(v, func | ae_flag_const);
-  if(!(v->owner_class = env->class_def))
+  if(!(v->from->owner_class = env->class_def))
     SET_FLAG(v, global);
   else {
     if(GET_FLAG(f, member))
@@ -394,7 +396,7 @@ ANN2(1, 2) static m_bool scan2_func_def_template(const Env env, const Func_Def f
     nspc_add_value(env->curr, f->base->xid, value);
     nspc_add_func(env->curr, f->base->xid, func);
   } else
-    func->vt_index = ++overload->offset;
+    func->vt_index = ++overload->from->offset;
   return GW_OK;
 }
 
@@ -493,7 +495,7 @@ ANN static m_str template_helper(const Env env, const Func_Def f) {
 
 ANN2(1,2) static m_str func_name(const Env env, const Func_Def f, const Value v) {
   if(!f->base->tmpl) {
-    const Symbol sym  = func_symbol(env, env->curr->name, s_name(f->base->xid), NULL, v ? ++v->offset : 0);
+    const Symbol sym  = func_symbol(env, env->curr->name, s_name(f->base->xid), NULL, v ? ++v->from->offset : 0);
     return s_name(sym);
   }
   return template_helper(env, f);
index 618e2d9f798109314bbb99c61fd60bcc7a0e8766..01b57af4dc0ecda411c562b93c311a7ed969f908 100644 (file)
@@ -238,8 +238,8 @@ ANN Type scan_type(const Env env, const Type t, const Type_Decl* type) {
       const Value value = new_value(env->gwion->mp, ret, s_name(sym));
       func->flag = def->flag;
       value->d.func_ref = func;
-      value->owner = t->e->owner;
-      value->owner_class = t->e->d.func->value_ref->owner_class;
+      value->from->owner = t->e->owner;
+      value->from->owner_class = t->e->d.func->value_ref->from->owner_class;
       func->value_ref = value;
       func->def->base->tmpl = mk_tmpl(env, t, t->e->d.func->def->base->tmpl, type->types);
       def->base->func = func;
index f3bd8df514ec3be846c7ac1827fcf3195e1f7fc8..a778ab95e8805585fab0904e044a4bc4c43e0dae 100644 (file)
@@ -10,6 +10,8 @@
 #include "traverse.h"
 #include "parse.h"
 
+#include "context.h"
+
 #define STR_NONNULL ":nonnull"
 #define STRLEN_NONNULL strlen(STR_NONNULL)
 
@@ -35,6 +37,8 @@ ANN Type type_nonnull(const Env env, const Type base) {
 
 ANN Type type_decl_resolve(const Env env, const Type_Decl* td) {
   DECL_OO(const Type, base, = find_type(env, td->xid))
+  if(base->e->ctx && base->e->ctx->error)
+    ERR_O(td_pos(td), _("type '%s' is invalid"), base->name)
   DECL_OO(const Type, t, = scan_type(env, base, td))
   const Type ret = !td->array ? t : array_type(env, t, td->array->depth);
   if(GET_FLAG(td, nonnull)) {
diff --git a/util b/util
index 3d2be8fdf552bdded221ddb266d55043c288da4a..dee77e5c3be6b2bcecd77929a21b5057ac5af5ce 160000 (submodule)
--- a/util
+++ b/util
@@ -1 +1 @@
-Subproject commit 3d2be8fdf552bdded221ddb266d55043c288da4a
+Subproject commit dee77e5c3be6b2bcecd77929a21b5057ac5af5ce