]> Nishi Git Mirror - gwion.git/commitdiff
:art: Few fixes
authorfennecdjay <astor.jeremie@wanadoo.fr>
Sun, 14 Jul 2019 15:45:59 +0000 (17:45 +0200)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Sun, 14 Jul 2019 15:45:59 +0000 (17:45 +0200)
24 files changed:
src/emit/emit.c
src/lib/instr.c
src/lib/object.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
src/vm/vm.c
tests/new/dottmpl.gw [new file with mode: 0644]
tests/new/dtor.gw [new file with mode: 0644]
tests/new/extend_template_union.gw [new file with mode: 0644]
tests/new/invalid_decl_exp.gw [new file with mode: 0644]
tests/new/ref.gw [new file with mode: 0644]
tests/new/static_tmpl.gw [new file with mode: 0644]
tests/new/static_tmpl2.gw [new file with mode: 0644]
tests/new/template_dyn.gw [new file with mode: 0644]
tests/new/test.gw [new file with mode: 0644]
tests/new/typedef_func_class.gw [new file with mode: 0644]
tests/new/typedef_func_class_variadic.gw [new file with mode: 0644]
tests/new/typedef_func_tmpl_class.gw [new file with mode: 0644]
tests/new/typedef_func_tmpl_class_static.gw [new file with mode: 0644]

index 22ee628a38911b487a2fc280278dda517c7bd93d..617933aa22bcf731f4ff34b7ce94cdabe03acc05 100644 (file)
@@ -762,21 +762,23 @@ ANN static Type_List tmpl_tl(const Env env, const m_str name) {
   return str2tl(env, c, &depth);
 }
 
+ANN static inline m_bool traverse_emit_func_def(const Emitter emit, const Func_Def fdef) {
+  CHECK_BB(traverse_func_def(emit->env, fdef))
+  return emit_func_def(emit, fdef);
+}
+
 ANN m_bool traverse_dot_tmpl(const Emitter emit, const struct dottmpl_ *dt) {
-  const m_uint scope = dt->owner_class ?
-      emit_push_type(emit, dt->owner_class) : emit_push(emit, NULL, dt->owner);
-  m_bool ret = GW_ERROR;
-  dt->def->base->tmpl->call = dt->tl;// in INSTR
-  if(!dt->def->base->func && traverse_func_def(emit->env, dt->def) > 0)
-    ret = emit_func_def(emit, dt->def);
+  const m_uint scope = emit_push(emit, dt->owner_class, dt->owner);
+  const m_bool ret = traverse_emit_func_def(emit, dt->def);
   emit_pop(emit, scope);
   return ret;
 }
 
 static inline m_bool push_func_code(const Emitter emit, const Func f) {
+  if(!vector_size(&emit->code->instr))
+    return GW_OK;
   const Instr instr = (Instr)vector_back(&emit->code->instr);
-  if(GET_FLAG(f, template) && f->value_ref->owner_class) {
-//    assert(instr->opcode == eDotTmplVal);
+  if(instr->opcode == eDotTmplVal) {
     size_t len = strlen(f->name);
     size_t sz = len - strlen(f->value_ref->owner_class->name);
     char c[sz + 1];
@@ -793,11 +795,8 @@ static inline m_bool push_func_code(const Emitter emit, const Func f) {
     instr->execute = DotTmpl;
     return GW_OK;
   }
-  if(vector_size(&emit->code->instr)) {
-    const Instr instr = (Instr)vector_back(&emit->code->instr);
-    instr->opcode = eRegPushImm;
-    instr->m_val = (m_uint)f->code;
-  }
+  instr->opcode = eRegPushImm;
+  instr->m_val = (m_uint)f->code;
   return GW_OK;
 }
 
@@ -806,9 +805,9 @@ ANN static m_bool emit_template_code(const Emitter emit, const Func f) {
     CHECK_BB(traverse_class_def(emit->env, f->value_ref->owner_class->e->def))
   const Value v = f->value_ref;
   size_t scope = emit_push(emit, v->owner_class, v->owner);
-  CHECK_BB(emit_func_def(emit, f->def))
+  const m_bool ret = emit_func_def(emit, f->def);
   emit_pop(emit, scope);
-  return push_func_code(emit, f);
+  return ret > 0 ? push_func_code(emit, f) : GW_ERROR;
 }
 
 ANN static Instr get_prelude(const Emitter emit, const Func f) {
@@ -1460,6 +1459,7 @@ ANN static m_bool emit_stmt_union(const Emitter emit, const Stmt_Union stmt) {
   emit_union_offset(stmt->l, stmt->o);
   if(stmt->xid || stmt->type_xid || global)
     emit_pop(emit, scope);
+  SET_FLAG(stmt->xid ? stmt->value->type : stmt->type, emit);
   return GW_OK;
 }
 
@@ -1599,8 +1599,7 @@ ANN static m_bool emit_member_func(const Emitter emit, const Exp_Dot* member, co
     func_i->m_val = (m_uint)(func->code ?: (VM_Code)func);
     return GW_OK;
   }
-//  if(func->def->base->tmpl)
-  if(GET_FLAG(func->def, template))
+  if(func->def->base->tmpl)
     emit_add_instr(emit, DotTmplVal);
   else {
     const Instr instr = emit_add_instr(emit, GET_FLAG(func, member) ? DotFunc : DotStaticFunc);
@@ -1780,9 +1779,8 @@ ANN static m_bool emit_parent(const Emitter emit, const Class_Def cdef) {
   const Type parent = cdef->base.type->e->parent;
   const Type base = parent->e->d.base_type;
   if(base && !GET_FLAG(base, emit))
-//  if(parent && (!GET_FLAG(parent, emit) || GET_FLAG(parent, template)))
-    CHECK_BB(scanx_parent(base, emit_parent_inner, emit))
-  return !GET_FLAG(parent, emit) ? GW_OK : scanx_parent(parent, emit_parent_inner, emit);
+    CHECK_BB(emit_parent_inner(emit, base->e->def))
+  return !GET_FLAG(parent, emit) ? emit_parent_inner(emit, parent->e->def) : GW_OK;
 }
 
 ANN static inline m_bool emit_cdef(const Emitter emit, const Class_Def cdef) {
index 9c0505916ee13e6daee5a601d105f804da299a48..bf97cd36b20ea9235591ac1cbb660516b1ea7f1f 100644 (file)
@@ -19,7 +19,7 @@
 INSTR(DTOR_EOC) {
   const M_Object o = *(M_Object*)MEM(0);
   o->type_ref = o->type_ref->e->parent;
-  __release(o, shred);
+  _release(o, shred);
   shred->info->me->ref = 1;
   vm_shred_exit(shred);
 }
@@ -51,15 +51,19 @@ INSTR(PopArrayClass) {
   free_object(shred->info->mp, tmp);
 }
 
-ANN static Func_Def from_base(const Env env, const struct dottmpl_ *dt, const Nspc nspc) {
+ANN static Func_Def from_base(const Env env, struct dottmpl_ *const dt, const Nspc nspc) {
   const Func_Def fdef = dt->def ?: dt->base;
   const Symbol sym = func_symbol(env, nspc->name, s_name(fdef->base->xid),
     "template", dt->vt_index);
-  DECL_OO(const Value, v, = nspc_lookup_value1(nspc, sym))
+  DECL_OO(const Value, v, = nspc_lookup_value0(nspc, sym))
   const Func_Def base = v->d.func_ref->def;
   const Func_Def def = new_func_def(env->gwion->mp, new_func_base(env->gwion->mp, fdef->base->td, insert_symbol(env->gwion->st, v->name),
-            fdef->base->args), fdef->d.code, fdef->flag, loc_cpy(env->gwion->mp, base->pos));
+            fdef->base->args), base->d.code, fdef->flag, loc_cpy(env->gwion->mp, base->pos));
   def->base->tmpl = new_tmpl(env->gwion->mp, base->base->tmpl->list, dt->vt_index);
+  def->base->tmpl->call = dt->tl;
+  dt->def = def;
+  dt->owner = v->owner;
+  dt->owner_class = v->owner_class;
   SET_FLAG(def, template);
   return def;
 }
@@ -78,8 +82,6 @@ INSTR(GTmpl) {
     if(base) {
       free_mstr(emit->gwion->mp, tmpl_name);
       assert(base->code);
-      if(GET_FLAG(base->def, static))
-        shred->reg -= SZ_INT;
       *(VM_Code*)(shred->reg -SZ_INT) = base->code;
       return;
     }
@@ -89,17 +91,9 @@ INSTR(GTmpl) {
   const Func_Def def = from_base(emit->env, dt, f->value_ref->owner);
   if(!def)
     Except(shred, "MissigTmplPtrException[internal]");
-  dt->def = def;
-  dt->owner = f->value_ref->owner;
-  dt->owner_class = f->value_ref->owner_class;
-  if(traverse_dot_tmpl(emit, dt) > 0) {
-    if(GET_FLAG(f, member)) // TODO: CHECK ME
-        shred->reg += SZ_INT; else
-    if(GET_FLAG(def, static))
-      shred->reg -= SZ_INT;
+  if(traverse_dot_tmpl(emit, dt) > 0)
     *(VM_Code*)(shred->reg -SZ_INT) = def->base->func->code;
-    return;
-  } else
+  else
     Except(shred, "TemplateException");
 }
 
@@ -116,14 +110,6 @@ INSTR(DotTmpl) {
     strcpy(str + instr->m_val2, t->name);
     const Func f = nspc_lookup_func1(t->nspc, insert_symbol(emit->env->gwion->st, str));
     if(f) {
-      if(!f->code) {
-        dt->def = f->def;//
-        dt->owner_class = t; //
-        if(traverse_dot_tmpl(emit, dt) < 0)
-          continue;
-      }
-      if(GET_FLAG(f->def, static))
-        shred->reg -= SZ_INT;
       *(VM_Code*)shred->reg = f->code;
       shred->reg += SZ_INT;
       return;
@@ -131,11 +117,7 @@ INSTR(DotTmpl) {
       const Func_Def def = from_base(emit->env, dt, t->nspc);
       if(!def)
         continue;
-      dt->def = def; //
-      dt->owner_class = t; //
       if(traverse_dot_tmpl(emit, dt) > 0) {
-        if(GET_FLAG(def, static))
-          shred->reg -= SZ_INT;
         *(VM_Code*)shred->reg = def->base->func->code;
         shred->reg += SZ_INT;
         return;
index 3d7c51d8c08bccd3752ad15d7f7fc846968b7cf7..8df093bbd5c8726d22ce95a091f6e3ef2b1e8114 100644 (file)
@@ -58,7 +58,7 @@ __attribute__((hot))
 ANN void __release(const M_Object o, const VM_Shred shred) {
   MemPool p = shred->info->mp;
   Type t = o->type_ref;
-  while(t->e->parent) {
+  do {
     struct scope_iter iter = { t->nspc->info->value, 0, 0 };\
     Value v;
     while(scope_iter(&iter, &v) > 0) {
@@ -66,16 +66,16 @@ ANN void __release(const M_Object o, const VM_Shred shred) {
           isa(v->type, t_object) > 0)
         release(*(M_Object*)(o->data + v->offset), shred);
     }
-    if(GET_FLAG(t, dtor)) {
+    if(GET_FLAG(t, dtor) && t->nspc->dtor) {
       if(GET_FLAG(t->nspc->dtor, builtin))
         ((f_xtor)t->nspc->dtor->native_func)(o, NULL, shred);
       else {
+        o->type_ref = t;
         handle_dtor(o, shred);
         return;
       }
     }
-    t = t->e->parent;
-  }
+  } while((t = t->e->parent));
   free_object(p, o);
 }
 
index 8600fc1500011d207cd298c12deb74c78d6c6f96..a4a76ec17e73e0916ab96aa8ef02de2f5d72291f 100644 (file)
@@ -103,11 +103,8 @@ ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) {
   }
   if(!decl->type) // TODO: remove when scan passes are complete
       ERR_O(td_pos(decl->td), _("can't infer type."));
-  if(GET_FLAG(decl->type , template)) {
-         /*if(!GET_FLAG(decl->type, checked))*/
-    if(!GET_FLAG(decl->type, scan2))
-      CHECK_BO(traverse_cdef(env, decl->type->e->def))
-  }
+  if(GET_FLAG(decl->type , template) && !GET_FLAG(decl->type, check))
+    CHECK_BO(traverse_cdef(env, decl->type->e->def))
   const m_bool global = GET_FLAG(decl->td, global);
   const m_uint scope = !global ? env->scope->depth : env_push_global(env);
   do {
@@ -369,10 +366,10 @@ ANN2(1,2) static Func find_func_match_actual(const Env env, Func func, const Exp
       }
       if(e1->type == t_undefined ||
             (func->def->base->tmpl && is_fptr(func->value_ref->type) > 0)) {
-        if(func->value_ref->owner_class)
+        if(SAFE_FLAG(func->value_ref->owner_class, template))
           CHECK_BO(template_push_types(env, func->value_ref->owner_class->e->def->base.tmpl))
         e1->type = known_type(env, e1->td);
-        if(func->value_ref->owner_class)
+        if(SAFE_FLAG(func->value_ref->owner_class, template))
           nspc_pop_type(env->gwion->mp, env->curr);
       }
       if(func_match_inner(env, e, e1->type, implicit, specific) < 0)
@@ -1019,8 +1016,6 @@ ANN static m_bool check_stmt_jump(const Env env, const Stmt_Jump stmt) {
 }
 
 ANN m_bool check_stmt_union(const Env env, const Stmt_Union stmt) {
-  if(stmt->tmpl)
-    return GW_OK;
   if(stmt->xid) {
     if(env->class_def)
       (!GET_FLAG(stmt, static) ? decl_member : decl_static)(env->curr, stmt->value);
@@ -1226,7 +1221,7 @@ ANN static m_bool check_class_parent(const Env env, const Class_Def cdef) {
   if(td->array)
     CHECK_BB(check_exp_array_subscripts(env, td->array->exp))
   if(parent->e->def && (!GET_FLAG(parent, check) || GET_FLAG(parent, template)))
-    CHECK_BB(scanx_parent(parent, traverse_class_def, env))
+    CHECK_BB(scanx_parent(parent, traverse_cdef, env))
   if(GET_FLAG(parent, typedef))
     SET_FLAG(cdef->base.type, typedef);
   return GW_OK;
index 6dd1bfdfd143530f6d1c46d1355a98d6df86bf60..8b88b6510746c1b4b56d71030ae884a932a9fdc1 100644 (file)
@@ -220,23 +220,20 @@ ANN static Nspc get_nspc(SymTable *st, const struct Op_Import* opi) {
 
 ANN m_bool op_emit(const Emitter emit, const struct Op_Import* opi) {
   Nspc nspc = get_nspc(emit->gwion->st, opi);
+  Type l = opi->lhs;
   do {
-    Type l = opi->lhs;
+    Type r = opi->rhs;
     do {
-      Type r = opi->rhs;
-      do {
-        if(!nspc->info->op_map.ptr)
-          continue;
-        const Vector v = (Vector)map_get(&nspc->info->op_map, (vtype)opi->op);
-        const M_Operator* mo = operator_find(v, l, r);
-        if(mo) {
-          if(mo->em)
-            return mo->em(emit, (void*)opi->data);
-          return handle_instr(emit, mo);
-        }
-      } while(r && (r = op_parent(emit->env, r)));
-    } while(l && (l = op_parent(emit->env, l)));
-  } while((nspc = nspc->parent));
-// probably deserves err_msg here
+      if(!nspc->info->op_map.ptr)
+        continue;
+      const Vector v = (Vector)map_get(&nspc->info->op_map, (vtype)opi->op);
+      const M_Operator* mo = operator_find(v, l, r);
+      if(mo) {
+        if(mo->em)
+          return mo->em(emit, (void*)opi->data);
+        return handle_instr(emit, mo);
+      }
+    } while(r && (r = op_parent(emit->env, r)));
+  } while(l && (l = op_parent(emit->env, l)));
   return GW_ERROR;
 }
index 7a5d61e357c1456d82be262d9d1a51c8b5c9913c..ea5fbbed81dfb37ad7e21332ade58b9f17af6cfb 100644 (file)
@@ -58,6 +58,8 @@ ANN m_bool scan0_stmt_fptr(const Env env, const Stmt_Fptr stmt) {
   stmt->value->owner = env->curr;
   stmt->value->owner_class = env->class_def;
   fptr_def(env, stmt);
+  if(env->class_def)
+    fptr_assign(env, stmt);
   SET_FLAG(stmt->value, func);
   add_type(env, t->e->owner, t);
   return GW_OK;
index 3a83cbdd4a4f92f505d41c7f0b7e184bbe6d0b05..7e8cc596c5f7ae2d1d2dce02b1aac4ba69ea3e47 100644 (file)
@@ -254,7 +254,7 @@ ANN m_bool scan1_stmt_fptr(const Env env, const Stmt_Fptr stmt) {
 ANN m_bool scan1_stmt_type(const Env env, const Stmt_Type stmt) {
   if(!stmt->type)
     CHECK_BB(scan0_stmt_type(env, stmt))
-  return stmt->type->e->def ? scan1_class_def(env, stmt->type->e->def) : GW_OK;
+  return stmt->type->e->def ? scan1_cdef(env, stmt->type->e->def) : GW_OK;
 }
 
 ANN m_bool scan1_stmt_union(const Env env, const Stmt_Union stmt) {
@@ -368,7 +368,7 @@ ANN static m_bool scan1_parent(const Env env, const Class_Def cdef) {
   if(isa(parent, t_object) < 0)
     ERR_B(pos, _("cannot extend primitive type '%s'"), parent->name)
   if(parent->e->def && (!GET_FLAG(parent, scan1) || GET_FLAG(parent, template)))
-    CHECK_BB(scanx_parent(parent, scan1_class_def, env))
+    CHECK_BB(scanx_parent(parent, scan1_cdef, env))
   if(type_ref(parent))
     ERR_B(pos, _("can't use ref type in class extend"))
   return GW_OK;
index ae676cb8badb2593cc157a7733434c13730d0174..9a8119c90377265fd56ec2ef25cbea3368454172 100644 (file)
@@ -82,28 +82,35 @@ ANN static Value scan2_func_assign(const Env env, const Func_Def d,
   return f->value_ref = v;
 }
 
+
+ANN void fptr_assign(const Env env, const Stmt_Fptr ptr) {
+  const Func_Def def = ptr->type->e->d.func->def;
+  if(GET_FLAG(ptr->base->td, global)) {
+    SET_FLAG(ptr->value, global);
+    SET_FLAG(ptr->base->func, global);
+    SET_FLAG(def, global);
+  } else if(!GET_FLAG(ptr->base->td, static)) {
+    SET_FLAG(ptr->value, member);
+    SET_FLAG(ptr->base->func, member);
+    SET_FLAG(def, member);
+    def->stack_depth += SZ_INT;
+  } else {
+    SET_FLAG(ptr->value, static);
+    SET_FLAG(ptr->base->func, static);
+    SET_FLAG(def, static);
+  }
+  if(GET_FLAG(def, variadic))
+    def->stack_depth += SZ_INT;
+  ptr->value->owner_class = env->class_def;
+}
+
 ANN m_bool scan2_stmt_fptr(const Env env, const Stmt_Fptr ptr) {
   const Func_Def def = ptr->type->e->d.func->def;
   if(!ptr->base->tmpl) {
     def->base->ret_type = ptr->base->ret_type;
     if(ptr->base->args)
       CHECK_BB(scan2_args(env, def))
-  }
-  if(env->class_def) {
-    if(GET_FLAG(ptr->base->td, global)) {
-      SET_FLAG(ptr->value, global);
-      SET_FLAG(ptr->base->func, global);
-    } else if(!GET_FLAG(ptr->base->td, static)) {
-      SET_FLAG(ptr->value, member);
-      SET_FLAG(ptr->base->func, member);
-      def->stack_depth += SZ_INT;
-    } else {
-      SET_FLAG(ptr->value, static);
-      SET_FLAG(ptr->base->func, static);
-    }
-    ptr->value->owner_class = env->class_def;
-  }
-  if(ptr->base->tmpl)
+  } else
     SET_FLAG(ptr->type, func);
 //  nspc_add_value(env->curr, ptr->base->xid, ptr->value);
   nspc_add_func(ptr->type->e->owner, ptr->base->xid, ptr->base->func);
index 568f30a58f22102259e9f6d7ebcc658f4e85f555..2f9bd2fac6b4bd2872e4160ebef1a5c2cad58626 100644 (file)
@@ -66,8 +66,6 @@ static inline Class_Def get_type_def(const Type t) {
 
 ANN m_bool
 scanx_parent(const Type t, const _exp_func f, void* d) {
-  if(t->e->parent == t_union)
-    return GW_OK;
   const Class_Def def = get_type_def(t);
   return def ? f(d, def) : GW_OK;
 }
index c9f66576a430830a2046401b6986f4d3edb94bb4..0e02fb1d2a29cd34bd3e49fba79bd100d5e7e261 100644 (file)
@@ -170,7 +170,7 @@ ANN Type scan_type(const Env env, const Type t, const Type_Decl* type) {
     if(a->base.type)
       return a->base.type;
     a->base.tmpl = mk_tmpl(env, t, t->e->def->base.tmpl, type->types);
-    if(isa(t, t_union) < 0) {
+    if(t->e->parent !=  t_union) {
       CHECK_BO(scan0_class_def(env, a))
       map_set(&t->e->owner->info->type->map, (vtype)a->base.xid, (vtype)a->base.type);
       map_set((Map)vector_front((Vector)&t->e->owner->info->type->ptr), (vtype)a->base.xid, (vtype)a->base.type);
@@ -208,9 +208,10 @@ ANN Type scan_type(const Env env, const Type t, const Type_Decl* type) {
       nspc_add_type(env->curr, sym, ret);
       const Func_Def def = new_func_def(env->gwion->mp,
         new_func_base(env->gwion->mp, t->e->d.func->def->base->td, sym, t->e->d.func->def->base->args),
-        NULL, type->flag, loc_cpy(env->gwion->mp, td_pos(type)));
+        NULL, t->e->d.func->def->flag, loc_cpy(env->gwion->mp, td_pos(type)));
       const Func func = ret->e->d.func = new_func(env->gwion->mp, s_name(sym), def);
       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;
index ff2fcfc6674513bb348b7f3b87ff0a8f51c74ffd..a3a8df93450f960b591508b00fe59d0119eb2b05 100644 (file)
@@ -103,10 +103,9 @@ ANN static inline void vm_ugen_init(const VM* vm) {
 
 #ifdef DEBUG_STACK
 #define VM_INFO                                                              \
-  if(s->curr)                                                                \
-    gw_err("shred[%" UINT_F "] mem[%" INT_F"] reg[%" INT_F"]\n", \
-    shred->tick->xid, \
-    mem - ((m_bit*)shred + sizeof(struct VM_Shred_) + SIZEOF_REG), reg - ((m_bit*)shred + sizeof(struct VM_Shred_)));
+  gw_err("shred[%" UINT_F "] mem[%" INT_F"] reg[%" INT_F"]\n", \
+  shred->tick->xid, \
+  mem - ((m_bit*)shred + sizeof(struct VM_Shred_) + SIZEOF_REG), reg - ((m_bit*)shred + sizeof(struct VM_Shred_)));
 #else
 #define VM_INFO
 #endif
diff --git a/tests/new/dottmpl.gw b/tests/new/dottmpl.gw
new file mode 100644 (file)
index 0000000..0576efe
--- /dev/null
@@ -0,0 +1,10 @@
+class C {
+  fun void test<~A~>(A a) { <<< a >>>; }
+}
+
+class D extends C {
+}
+
+D d;
+d.test(1);
+d.test(2.3);
diff --git a/tests/new/dtor.gw b/tests/new/dtor.gw
new file mode 100644 (file)
index 0000000..c6ca2f1
--- /dev/null
@@ -0,0 +1,11 @@
+class <~A~>C {
+  dtor { <<< __func__ >>>; }
+}
+class <~A~>D extends <~A~>C {
+  dtor { <<< __func__ >>>; }
+}
+class E extends <~int~>D {
+  dtor { <<< __func__ >>>; }
+}
+
+E e;
diff --git a/tests/new/extend_template_union.gw b/tests/new/extend_template_union.gw
new file mode 100644 (file)
index 0000000..f9e9de1
--- /dev/null
@@ -0,0 +1,26 @@
+union <~A~>U {
+  A a;
+  int i;
+};
+
+#!<~float~>U u;
+#!<<< u.i >>>;
+class <~A~>C extends <~A~>U {
+  fun void test() { <<< this >>>; }
+  dtor { <<< __func__ >>>; }
+}
+
+<~float~>C c;
+<<< c >>>;
+<<< c.test() >>>;
+<<< c.i >>>;
+
+class <~A,B~>D extends <~float~>C {
+
+}
+
+<~int,int~>D d;
+class <~A,B~>E extends <~float,B~>D {
+
+}
+<~int,int~>E e;
diff --git a/tests/new/invalid_decl_exp.gw b/tests/new/invalid_decl_exp.gw
new file mode 100644 (file)
index 0000000..7f9438d
--- /dev/null
@@ -0,0 +1,2 @@
+`1` i;
+<<< i >>>;
diff --git a/tests/new/ref.gw b/tests/new/ref.gw
new file mode 100644 (file)
index 0000000..34c9985
--- /dev/null
@@ -0,0 +1 @@
+new Object @=> Object ! @ o;
diff --git a/tests/new/static_tmpl.gw b/tests/new/static_tmpl.gw
new file mode 100644 (file)
index 0000000..b024fdd
--- /dev/null
@@ -0,0 +1,14 @@
+class global C {
+  fun static void t<~A~>() { <<< __func__ >>>; }
+}
+class D extends C {
+
+}
+
+fun void test(C c) {
+  C.t<~int~>();
+}
+
+#!D d;
+#!d.t<~int~>();
+#!d => test;
diff --git a/tests/new/static_tmpl2.gw b/tests/new/static_tmpl2.gw
new file mode 100644 (file)
index 0000000..3d2d2f6
--- /dev/null
@@ -0,0 +1,11 @@
+#!C.t<~float~>();
+#!C.t<~Object~>();
+class D extends C {
+
+}
+#!<<< "here" >>>;
+D d;
+<<< d >>>;
+#!<<< d.t() >>>;
+<<< d.t<~int~>() >>>;
+#!d.t<~Object~>();
diff --git a/tests/new/template_dyn.gw b/tests/new/template_dyn.gw
new file mode 100644 (file)
index 0000000..64d5749
--- /dev/null
@@ -0,0 +1,16 @@
+class C {
+  fun int test<~A~>(A a) { <<< " A ", a >>>; }
+  fun int test<~A~>(A a, int i) { <<< " A ", a, " ", __func__  >>>; }
+  fun int test<~A~>(A a, int i, int j) { <<< a >>>; }
+}
+class D extends C {
+  fun int test<~A~>(A a, int i) { <<< this, " extent ", a, __func__ >>>; }
+}
+class E extends D {
+  fun int test<~A~>(A a, int i) { <<< this, " Extent ", a, __func__ >>>; }
+}
+
+
+<<< E e >>>;
+
+e.test(123,3);
diff --git a/tests/new/test.gw b/tests/new/test.gw
new file mode 100644 (file)
index 0000000..e2f0cce
--- /dev/null
@@ -0,0 +1,8 @@
+class C {
+  typedef static void func_t<~A~>(A a);
+  fun static void myfunc<~A~>(A a) { <<< a >>>; }
+  myfunc @=> static func_t ptr;
+  ptr(1);
+}
+
+C c;
diff --git a/tests/new/typedef_func_class.gw b/tests/new/typedef_func_class.gw
new file mode 100644 (file)
index 0000000..d52f288
--- /dev/null
@@ -0,0 +1,17 @@
+class C {
+  typedef void t_ptr();
+
+  t_ptr iptr;
+
+  fun void test() {
+    <<< this, " ", __func__ >>>;
+  }
+
+  test @=> iptr;
+  <<< iptr() >>>;
+  <<< iptr() >>>;
+}
+<<<C c>>>;
+  <<< c.iptr >>>;
+  <<< c.iptr() >>>;
+  <<< c.iptr() >>>;
diff --git a/tests/new/typedef_func_class_variadic.gw b/tests/new/typedef_func_class_variadic.gw
new file mode 100644 (file)
index 0000000..914c46d
--- /dev/null
@@ -0,0 +1,20 @@
+class C {
+  typedef void t_ptr(...);
+
+  t_ptr iptr;
+
+  fun void test(...) {
+    <<< this, " ", __func__ >>>;
+    vararg.start;
+    <<< vararg.i >>>;
+    vararg.end;
+  }
+
+  test @=> iptr;
+  <<< iptr() >>>;
+  <<< iptr() >>>;
+}
+<<<C c>>>;
+  <<< c.iptr >>>;
+  <<< c.iptr(1) >>>;
+  <<< c.iptr(1,2) >>>;
diff --git a/tests/new/typedef_func_tmpl_class.gw b/tests/new/typedef_func_tmpl_class.gw
new file mode 100644 (file)
index 0000000..bdb9244
--- /dev/null
@@ -0,0 +1,17 @@
+class C {
+  typedef void t_ptr<~A~>();
+
+  <~int~>t_ptr iptr;
+
+  fun void test<~A~>() {
+    <<< this, " ", __func__ >>>;
+  }
+
+  test @=> iptr;
+  <<< iptr() >>>;
+  <<< iptr() >>>;
+}
+<<<C c>>>;
+  <<< c.iptr >>>;
+  <<< c.iptr() >>>;
+  <<< c.iptr() >>>;
diff --git a/tests/new/typedef_func_tmpl_class_static.gw b/tests/new/typedef_func_tmpl_class_static.gw
new file mode 100644 (file)
index 0000000..df6015c
--- /dev/null
@@ -0,0 +1,18 @@
+class C {
+  typedef static void t_ptr<~A~>();
+
+  <~int~>t_ptr iptr;
+
+  fun static void test<~A~>() {
+    <<< __func__ >>>;
+  }
+
+  test @=> iptr;
+#!  test<~int~>();
+  <<< iptr() >>>;
+ <<< iptr() >>>;
+}
+<<<C c>>>;
+#!  <<< c.iptr >>>;
+#!  <<< c.iptr() >>>;
+#!  <<< c.iptr() >>>;