]> Nishi Git Mirror - gwion.git/commitdiff
:art: Copy def for templates :smile:
authorfennecdjay <astor.jeremie@wanadoo.fr>
Tue, 23 Jul 2019 16:14:43 +0000 (18:14 +0200)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Tue, 23 Jul 2019 16:14:43 +0000 (18:14 +0200)
28 files changed:
ast
include/cpy_ast.h [new file with mode: 0644]
src/emit/emit.c
src/lib/func.c
src/lib/import.c
src/lib/instr.c
src/lib/object.c
src/parse/check.c
src/parse/cpy_ast.c [new file with mode: 0644]
src/parse/func.c
src/parse/scan0.c
src/parse/scan1.c
src/parse/scan2.c
src/parse/template.c
src/parse/type_decl.c
tests/error/variadic_miss_end.gw [new file with mode: 0644]
tests/new/class_fptr_returns_fptr.gw [new file with mode: 0644]
tests/new/implicit_fptr.gw [new file with mode: 0644]
tests/new/int_float_minus.gw [new file with mode: 0644]
tests/new/lambda_return.gw [new file with mode: 0644]
tests/new/recursive_template.gw [new file with mode: 0644]
tests/new/recursive_template0.gw [new file with mode: 0644]
tests/new/recursive_template1.gw [new file with mode: 0644]
tests/new/recursive_template2.gw [new file with mode: 0644]
tests/new/recursive_template3.gw [new file with mode: 0644]
tests/new/recursive_template_test.gw [new file with mode: 0644]
tests/new/spork_fptr.gw [new file with mode: 0644]
tests/new/spork_fptr2.gw [new file with mode: 0644]

diff --git a/ast b/ast
index bd7f714f19c2c2e237cbe4cd6a74aa2cb2dd7206..5d8450be617d21ac1aca168dd9c5cf267bebd8f1 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit bd7f714f19c2c2e237cbe4cd6a74aa2cb2dd7206
+Subproject commit 5d8450be617d21ac1aca168dd9c5cf267bebd8f1
diff --git a/include/cpy_ast.h b/include/cpy_ast.h
new file mode 100644 (file)
index 0000000..5434406
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef __CPY_AST
+#define __CPY_AST
+ANN Func_Def cpy_func_def(MemPool, Func_Def);
+ANN struct Func_Base_* cpy_func_base(MemPool, struct Func_Base_*);
+ANN Class_Def cpy_class_def(MemPool, Class_Def);
+#endif
index 3a0228fa1cc58b193c47760ff7e9d5f475744a75..76a30554a579e85189d4a33218e15da6dd1620c0 100644 (file)
@@ -607,14 +607,9 @@ ANN static m_bool emit_exp_decl_global(const Emitter emit, const Var_Decl var_de
 ANN static m_bool emit_class_def(const Emitter, const Class_Def);
 ANN static m_bool emit_cdef(const Emitter, const Class_Def);
 
-ANN static m_bool emit_parent_inner(const Emitter emit, const Class_Def cdef) {
-  CHECK_BB(traverse_cdef(emit->env, cdef))
-  return emit_cdef(emit, cdef);
-}
-
 ANN static inline m_bool emit_exp_decl_template(const Emitter emit, const Exp_Decl* decl) {
   const Type t = decl->type;
-  return !GET_FLAG(t, emit) ? emit_parent_inner(emit, t->e->def) : GW_OK;
+  return !GET_FLAG(t, emit) ? emit_cdef(emit, t->e->def) : GW_OK;
 }
 
 ANN static m_bool emit_exp_decl(const Emitter emit, const Exp_Decl* decl) {
@@ -682,32 +677,8 @@ ANN static m_bool prepare_call(const Emitter emit, const Exp_Call* exp_call) {
   return emit_exp(emit, exp_call->func, 0);
 }
 
-ANN static inline m_int push_tmpl_func(const Emitter emit, const Func f) {
-  const Value v = f->value_ref;
-  if(isa(v->type, t_class) > 0 && is_fptr(v->type))
-    return emit->env->scope->depth;
-  const m_uint scope = emit_push(emit, v->owner_class, v->owner);
-  CHECK_BB(traverse_func_def(emit->env, f->def))
-  return (m_int)scope;
-}
-
-ANN static m_bool emit_exp_call_template(const Emitter emit, const Exp_Call* exp_call) {
-  if(emit->env->func && emit->env->func == exp_call->m_func)
-    return prepare_call(emit, exp_call);
-  exp_call->m_func->def->base->tmpl->call = exp_call->tmpl->call;
-  DECL_BB(const m_int,scope, = push_tmpl_func(emit, exp_call->m_func))
-  CHECK_BB(prepare_call(emit, exp_call))
-  if(!is_fptr(exp_call->m_func->value_ref->type))
-    emit_pop(emit, (m_uint)scope);
-  UNSET_FLAG(exp_call->m_func, checked);
-  return GW_OK;
-}
-
 ANN static m_bool emit_exp_call(const Emitter emit, const Exp_Call* exp_call) {
-  if(!exp_call->tmpl)
-    CHECK_BB(prepare_call(emit, exp_call))
-  else
-    CHECK_BB(emit_exp_call_template(emit, exp_call))
+  CHECK_BB(prepare_call(emit, exp_call))
   return emit_exp_call1(emit, exp_call->m_func);
 }
 
@@ -752,7 +723,8 @@ ANN static Type_List tmpl_tl(const Env env, const m_str name) {
 }
 
 ANN static inline m_bool traverse_emit_func_def(const Emitter emit, const Func_Def fdef) {
-  CHECK_BB(traverse_func_def(emit->env, fdef))
+  if(!fdef->base->ret_type)
+    CHECK_BB(traverse_func_def(emit->env, fdef))
   return emit_func_def(emit, fdef);
 }
 
@@ -790,8 +762,6 @@ 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) {
-  if(GET_FLAG(f, ref))
-    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);
   const m_bool ret = emit_func_def(emit, f->def);
@@ -1707,7 +1677,7 @@ ANN static m_bool emit_func_def_body(const Emitter emit, const Func_Def fdef) {
 
 ANN static m_bool tmpl_rettype(const Emitter emit, const Func_Def fdef) {
   CHECK_BB(template_push_types(emit->env, fdef->base->tmpl))
-  const m_bool ret = emit_parent_inner(emit, fdef->base->ret_type->e->def);
+  const m_bool ret = emit_cdef(emit, fdef->base->ret_type->e->def);
   emit_pop_type(emit);
   return ret;
 }
@@ -1766,8 +1736,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))
-    CHECK_BB(emit_parent_inner(emit, base->e->def))
-  return !GET_FLAG(parent, emit) ? emit_parent_inner(emit, parent->e->def) : GW_OK;
+    CHECK_BB(emit_cdef(emit, base->e->def))
+  return !GET_FLAG(parent, emit) ? emit_cdef(emit, parent->e->def) : GW_OK;
 }
 
 ANN static inline m_bool emit_cdef(const Emitter emit, const Class_Def cdef) {
index f544ebd94e7f8cfa509ca5ef1e10ac4917de11db..68778e622462121d85561340ca99a991c2c4695a 100644 (file)
@@ -90,7 +90,7 @@ static m_bool td_match(const Env env, const Type_Decl *id[2]) {
   return isa(t0, t1);
 }
 
-ANN static m_bool fptr_args(const Env env, struct Func_Base_ *base[2]) {
+ANN static m_bool fptr_args(const Env env, Func_Base *base[2]) {
   Arg_List arg0 = base[0]->args, arg1 = base[1]->args;
   while(arg0) {
     CHECK_OB(arg1)
@@ -141,7 +141,7 @@ ANN static Type fptr_type(const Env env, struct FptrInfo *info) {
     const Symbol sym = (!info->lhs->def->base->tmpl || i != 0) ?
         func_symbol(env, nspc->name, c, stmpl, i) : info->lhs->def->base->xid;
     CHECK_OO((info->lhs = nspc_lookup_func1(nspc, sym)))
-    struct Func_Base_ *base[2] =  { info->lhs->def->base, info->rhs->def->base };
+    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)
index 56ecdfd965cf903e98b09451e43444bb11a01067..ef280069b99ee93495fb196765b7552e8e5e672d 100644 (file)
@@ -528,7 +528,7 @@ ANN static Stmt import_fptr(const Gwi gwi, DL_Func* dl_fun, ae_flag flag) {
   if(!(type_path = str2list(env, dl_fun->type, &array_depth)) ||
       !(type_decl = new_type_decl(env->gwion->mp, type_path)))
     GWI_ERR_O(_("  ...  during fptr import '%s' (type)."), dl_fun->name);
-  struct Func_Base_ *base = new_func_base(env->gwion->mp, type_decl, insert_symbol(env->gwion->st, dl_fun->name), args);
+  Func_Base *base = new_func_base(env->gwion->mp, type_decl, insert_symbol(env->gwion->st, dl_fun->name), args);
   return new_stmt_fptr(env->gwion->mp, base, flag);
 }
 
index bf97cd36b20ea9235591ac1cbb660516b1ea7f1f..13ffed020eabf6884fc3d05c29597ededc79195d 100644 (file)
@@ -15,6 +15,7 @@
 #include "gwion.h"
 #include "operator.h"
 #include "import.h"
+#include "cpy_ast.h"
 
 INSTR(DTOR_EOC) {
   const M_Object o = *(M_Object*)MEM(0);
@@ -56,11 +57,9 @@ ANN static Func_Def from_base(const Env env, struct dottmpl_ *const dt, const Ns
   const Symbol sym = func_symbol(env, nspc->name, s_name(fdef->base->xid),
     "template", dt->vt_index);
   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), 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);
+  const Func_Def def = cpy_func_def(env->gwion->mp, v->d.func_ref->def);
   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;
index 4d2e1f17e6cd32d1de9cfb8f325b50bb9832aa46..d3e09a93f0cacb9d9a79d460bf7cda3f83cf0d6e 100644 (file)
@@ -148,9 +148,7 @@ static inline Type new_force_type(MemPool p, const Type t, const Symbol sym) {
   const Type ret = type_copy(p, t);
   ret->name = s_name(sym);
   ret->flag = t->flag | ae_flag_force;
-//  nspc_add_type(t->e->owner, sym, ret);
-//  map_set(&t->e->owner->info->type->map, sym, ret);
-  map_set(vector_front(&t->e->owner->info->type->ptr), sym, ret);
+  map_set(&t->e->owner->info->type->map, (vtype)sym, (vtype)ret);
   return ret;
  }
 
@@ -161,7 +159,6 @@ static Type get_force_type(const Env env, const Type t) {
   strcpy(name + len, STR_FORCE);
   const Symbol sym = insert_symbol(env->gwion->st, name);
   return nspc_lookup_type1(t->e->owner, sym) ?: new_force_type(env->gwion->mp, t, sym);
-//  return nspc_lookup_type0(t->e->owner, sym) ?: new_force_type(env, t, sym);
 }
 
 static OP_CHECK(opck_object_cast) {
index 75d7a03364890751750a7cc85bc1627582a55ebb..de70be5554f053950e13adf44ac6c921679ad399 100644 (file)
@@ -18,6 +18,7 @@
 #include "parse.h"
 #include "nspc.h"
 #include "switch.h"
+#include "cpy_ast.h"
 
 ANN static Type   check_exp(const Env env, Exp exp);
 ANN static m_bool check_stmt_list(const Env env, Stmt_List list);
@@ -101,7 +102,7 @@ ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) {
     if(decl->type == t_auto)
       ERR_O(td_pos(decl->td), _("can't infer type."));
   }
-  if(!decl->type) // TODO: remove when scan passes are complete
+  if(!decl->type)
       ERR_O(td_pos(decl->td), _("can't infer type."));
   if(GET_FLAG(decl->type , template) && !GET_FLAG(decl->type, check))
     CHECK_BO(traverse_cdef(env, decl->type->e->def))
@@ -488,8 +489,9 @@ CHECK_BO(check_call(env, exp))
   const Symbol sym = func_symbol(env, v->owner->name, v->name, tmpl_name, 0);
   const Value value = nspc_lookup_value1(v->owner, sym);
   Func_Def base = v->d.func_ref ? v->d.func_ref->def : exp->func->type->e->d.func->def;
-  struct Func_Base_ *fbase = new_func_base(env->gwion->mp, base->base->td, sym, base->base->args);
-  fbase->tmpl = new_tmpl(env->gwion->mp, base->base->tmpl->list, 0);
+  Func_Base *fbase = cpy_func_base(env->gwion->mp, base->base);
+  fbase->xid = sym;
+  fbase->tmpl->base = 0;
   fbase->tmpl->call = types;
   if(template_push_types(env, fbase->tmpl) > 0) {
     const Stmt stmt = new_stmt_fptr(env->gwion->mp, fbase, base->flag);
@@ -503,8 +505,6 @@ 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) {
-        if(!m_func->def->base->ret_type)
-          CHECK_BO(traverse_func_def(env, m_func->def))
         map_set(&v->owner->info->type->map, (vtype)sym, (vtype)actual_type(m_func->value_ref->type));
       }
     }
@@ -512,35 +512,27 @@ CHECK_BO(check_call(env, exp))
   }
   } else {
     for(m_uint i = 0; i < v->offset + 1; ++i) {
-      Func_Def fdef = NULL;
-      Func_Def base = NULL;
-      Value value = template_get_ready(env, v, tmpl_name, i);
-      if(value) {
-        if(env->func == value->d.func_ref) {
+      const Value exists = template_get_ready(env, v, tmpl_name, i);
+      if(exists) {
+        if(env->func == exists->d.func_ref) {
           if(check_call(env, exp) < 0)
             continue;
           m_func = env->func;
           break;
         }
-        fdef = value->d.func_ref->def;
-        if(!fdef->base->tmpl) {
-          if(!(value = template_get_ready(env, v, "template", i)))
-            continue;
-          base = value->d.func_ref->def;
-          fdef->base->tmpl = new_tmpl(env->gwion->mp, base->base->tmpl->list, (m_int)i);
-        }
+        if((m_func = ensure_tmpl(env, exists->d.func_ref->def, exp)))
+          break;
       } else {
-        if(!(value = template_get_ready(env, v, "template", i)))
+        const Value value = template_get_ready(env, v, "template", i);
+        if(!value)
           continue;
-        base = value->d.func_ref->def;
-        fdef = new_func_def(env->gwion->mp, new_func_base(env->gwion->mp, base->base->td, insert_symbol(v->name),
-                base->base->args), base->d.code, base->flag, loc_cpy(env->gwion->mp, base->pos));
-        fdef->base->tmpl = new_tmpl(env->gwion->mp, base->base->tmpl->list, (m_int)i);
+        const Func_Def fdef = (Func_Def)cpy_func_def(env->gwion->mp, value->d.func_ref->def);
         SET_FLAG(fdef, template);
+        fdef->base->tmpl->call = types;
+        fdef->base->tmpl->base = i;
+        if((m_func = ensure_tmpl(env, fdef, exp)))
+          break;
       }
-      fdef->base->tmpl->call = types;
-      if((m_func = ensure_tmpl(env, fdef, exp)))
-        break;
     }
   }
   free_mstr(env->gwion->mp, tmpl_name);
@@ -613,37 +605,36 @@ ANN static Func get_template_func(const Env env, const Exp_Call* func, const Val
   assert(exp_self(func));
   ERR_O(exp_self(func)->pos,
         _("function is template. automatic type guess not fully implemented yet.\n"
-        "  please provide template types. eg: '<type1, type2, ...>'"))
+        "  please provide template types. eg: '<~type1, type2, ...~>'"))
+}
+
+ANN static Func predefined_func(const Env env, const Value v,
+    Exp_Call *exp, const Tmpl *tm) {
+  Tmpl tmpl = { .call=tm->call };
+  ((Exp_Call*)exp)->tmpl = &tmpl;
+  DECL_OO(const Func, func, = get_template_func(env, exp, v))
+  return v->d.func_ref = func;
 }
 
 ANN static Type check_exp_call_template(const Env env, const Exp_Call *exp) {
   const Exp call = exp->func;
   const Exp args = exp->args;
-  m_uint args_number = 0;
   DECL_OO(const Value, value, = nspc_lookup_value1(call->type->e->owner, insert_symbol(call->type->name)))
   Tmpl *tm = value->d.func_ref ? value->d.func_ref->def->base->tmpl : call->type->e->d.func->def->base->tmpl;
-  const m_uint type_number = get_type_number(tm->list);
-  Type_List tl[type_number];
-  ID_List list = tm->list;
   if(tm->call) {
-    if(!value->d.func_ref) {
-      Tmpl tmpl = { .call=tm->call };
-      ((Exp_Call*)exp)->tmpl = &tmpl;
-      DECL_OO(const Func,func, = get_template_func(env, exp, value))
-      assert(func->def->base->ret_type);
-      value->d.func_ref = func;
-      return func->def->base->ret_type;
-    } else {
-      const Func func = value->d.func_ref;
-      if(!func->def->base->ret_type) { // template fptr
-        const m_uint scope = env_push(env, value->owner_class, value->owner);
-        CHECK_BO(traverse_func_def(env, func->def))
-        env_pop(env, scope);
-      }
-      ((Exp_Call*)exp)->m_func = func;
-      return func->def->base->ret_type;
+    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);
+      CHECK_BO(traverse_func_def(env, func->def))
+      env_pop(env, scope);
     }
+    ((Exp_Call*)exp)->m_func = func;
+    return func->def->base->ret_type;
   }
+  m_uint args_number = 0;
+  const m_uint type_number = get_type_number(tm->list);
+  Type_List tl[type_number];
+  ID_List list = tm->list;
   while(list) {
     Arg_List arg = value->d.func_ref->def->base->args;
     Exp template_arg = args;
@@ -667,15 +658,11 @@ ANN static Type check_exp_call_template(const Env env, const Exp_Call *exp) {
   Tmpl tmpl = { .call=tl[0] };
   ((Exp_Call*)exp)->tmpl = &tmpl;
   DECL_OO(const Func,func, = get_template_func(env, exp, value))
-  if(!func->def->base->ret_type) // template fptr
-    CHECK_BO(traverse_func_def(env, func->def))
   return func->def->base->ret_type;
 }
 
 ANN static m_bool check_exp_call1_check(const Env env, const Exp exp) {
   CHECK_OB(check_exp(env, exp))
-//  if(!check_exp(env, exp))
-//    ERR_B(exp->pos, _("function call using a non-existing function"))
   if(isa(exp->type, t_function) < 0)
     ERR_B(exp->pos, _("function call using a non-function value"))
   return GW_OK;
@@ -773,8 +760,14 @@ ANN static Type check_exp_call(const Env env, Exp_Call* exp) {
       ERR_O(exp_self(exp)->pos, _("template call of non-function value."))
     if(!v->d.func_ref->def->base->tmpl)
       ERR_O(exp_self(exp)->pos, _("template call of non-template function."))
-    if(t->e->d.func->def->base->tmpl->call)
+    if(t->e->d.func->def->base->tmpl->call) {
+      if(env->func == t->e->d.func) {
+        CHECK_OO(check_exp(env, exp->args))
+        exp->m_func = env->func;
+        return env->func->def->base->ret_type;
+      }  else
       CHECK_BO(predefined_call(env, t, exp_self(exp)->pos))
+    }
     const Func ret = find_template_match(env, v, exp);
     CHECK_OO((exp->m_func = ret))
     return ret->def->base->ret_type;
@@ -1005,7 +998,7 @@ ANN static m_bool check_stmt_return(const Env env, const Stmt_Exp stmt) {
   struct Op_Import opi = { .op=insert_symbol("@implicit"), .lhs=ret_type, .rhs=env->func->def->base->ret_type,
                       .data=(m_uint)&imp, .pos=stmt_self(stmt)->pos };
   const Type ret = op_check(env, &opi);
-  if(!ret)
+  if(!ret && isa(ret_type, env->func->def->base->ret_type) < 0)
     ERR_B(stmt_self(stmt)->pos, _("invalid return type '%s' -- expecting '%s'"),
           ret_type->name, env->func->def->base->ret_type->name)
   return GW_OK;
@@ -1053,6 +1046,8 @@ 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 && stmt->tmpl->base == -1) // there's a func for this
+    return GW_OK;
   if(stmt->xid) {
     if(env->class_def)
       (!GET_FLAG(stmt, static) ? decl_member : decl_static)(env->curr, stmt->value);
@@ -1214,10 +1209,9 @@ ANN m_bool check_func_def(const Env env, const Func_Def fdef) {
     return traverse_func_def(env, fdef);
   }
   CHECK_BB(check_func_def_override(env, fdef))
+  DECL_BB(const m_int, scope, = GET_FLAG(fdef, global) ? env_push_global(env) : env->scope->depth)
   if(env->class_def) // tmpl ?
     CHECK_BB(check_parent_match(env, fdef))
-  else if(GET_FLAG(fdef, global))
-    env_push_global(env);
   const Func former = env->func;
   env->func = func;
   ++env->scope->depth;
@@ -1246,7 +1240,7 @@ ANN m_bool check_func_def(const Env env, const Func_Def fdef) {
   --env->scope->depth;
   env->func = former;
   if(GET_FLAG(fdef, global))
-    env_push_global(env);
+    env_pop(env,scope);
   return ret;
 }
 
diff --git a/src/parse/cpy_ast.c b/src/parse/cpy_ast.c
new file mode 100644 (file)
index 0000000..2f9f3c5
--- /dev/null
@@ -0,0 +1,484 @@
+#include "gwion_util.h"
+#include "gwion_ast.h"
+
+ANN static Stmt cpy_stmt(MemPool p, const Stmt src);
+ANN static Exp cpy_exp(MemPool p, const Exp src);
+ANN static ID_List cpy_id_list(MemPool p, const ID_List src);
+ANN static Type_List cpy_type_list(MemPool p, const Type_List src);
+ANN static Arg_List cpy_arg_list(MemPool p, const Arg_List src);
+ANN Class_Def cpy_class_def(MemPool p, const Class_Def src);
+ANN static Stmt_List cpy_stmt_list(MemPool p, const Stmt_List src);
+
+ANN static void cpy_exp_dot(MemPool p, Exp_Dot *a, const Exp_Dot *src) {
+  a->base = cpy_exp(p, src->base);
+  a->xid = src->xid;
+}
+
+ANN static void cpy_exp_lambda(MemPool p, Exp_Lambda *a, const Exp_Lambda *src) {
+  if(src->args)
+    a->args = cpy_arg_list(p, src->args);
+  a->code = cpy_stmt(p, src->code);
+  a->name = src->name;
+}
+
+ANN static Array_Sub cpy_array_sub(MemPool p, const Array_Sub src) {
+  Array_Sub a = mp_calloc(p, Array_Sub);
+  if(src->exp)
+    a->exp = cpy_exp(p, src->exp);
+  a->depth = src->depth;
+  return a;
+}
+
+ANN static void cpy_exp_array(MemPool p, Exp_Array *a, const Exp_Array *src) {
+  a->base = cpy_exp(p, src->base);
+  a->array = cpy_array_sub(p, src->array);
+}
+
+ANN static Var_Decl cpy_var_decl(MemPool p, const Var_Decl src) {
+  Var_Decl a = mp_calloc(p, Var_Decl);
+  a->xid = src->xid; // 1 
+  if(src->array)
+    a->array = cpy_array_sub(p, src->array); // 1 
+  a->pos = loc_cpy(p, src->pos); // 1 
+  return a;
+}
+
+ANN static Var_Decl_List cpy_var_decl_list(MemPool p, const Var_Decl_List src) {
+  Var_Decl_List a = mp_calloc(p, Var_Decl_List);
+  a->self = cpy_var_decl(p, src->self); // 1 
+  if(src->next)
+    a->next = cpy_var_decl_list(p, src->next); // 1 
+  return a;
+}
+
+ANN static Type_Decl* cpy_type_decl(MemPool p, const Type_Decl* src) {
+  Type_Decl* a = mp_calloc(p, Type_Decl);
+  if(src->xid)
+    a->xid = cpy_id_list(p, src->xid); // 1 
+  if(src->exp)
+    a->exp = cpy_exp(p, src->exp); // 1 
+  if(src->array)
+    a->array = cpy_array_sub(p, src->array); // 1 
+  if(src->types)
+    a->types = cpy_type_list(p, src->types); // 1 
+  a->flag = src->flag; // 1 
+  return a;
+}
+
+ANN static ID_List cpy_id_list(MemPool p, const ID_List src) {
+  ID_List a = mp_calloc(p, ID_List);
+  a->xid = src->xid; // 1 
+  if(src->next)
+    a->next = cpy_id_list(p, src->next); // 1 
+  a->pos = loc_cpy(p, src->pos); // 1 
+  return a;
+}
+
+ANN static Type_List cpy_type_list(MemPool p, const Type_List src) {
+  Type_List a = mp_calloc(p, Type_List);
+  if(src->td)
+    a->td = cpy_type_decl(p, src->td); // 1 
+  if(src->next)
+    a->next = cpy_type_list(p, src->next); // 1 
+  return a;
+}
+
+ANN static void cpy_vec(MemPool p, Vec* a, const Vec* src) {
+  a->exp = cpy_exp(p, src->exp);
+  a->dim = src->dim;
+}
+
+ANN static Arg_List cpy_arg_list(MemPool p, const Arg_List src) {
+  Arg_List a = mp_calloc(p, Arg_List);
+  if(src->td)
+    a->td = cpy_type_decl(p, src->td); // 1 
+  if(src->var_decl)
+    a->var_decl = cpy_var_decl(p, src->var_decl); // 1 
+  if(src->next)
+    a->next = cpy_arg_list(p, src->next); // 1 
+  return a;
+}
+
+ANN static void cpy_exp_decl(MemPool p, Exp_Decl *a, const Exp_Decl *src) {
+  a->td = cpy_type_decl(p, src->td);
+  a->list = cpy_var_decl_list(p, src->list);
+}
+
+ANN static void cpy_exp_primary(MemPool p, Exp_Primary *a, const Exp_Primary *src) {
+  switch(src->primary_type) {
+    case ae_primary_id:
+      a->d.var = src->d.var;
+      break;
+    case ae_primary_num:
+      a->d.num = src->d.num;
+      break;
+    case ae_primary_float:
+      a->d.fnum = src->d.fnum;
+      break;
+    case ae_primary_char:
+      a->d.chr = src->d.chr;
+      break;
+    case ae_primary_str:
+      a->d.str = src->d.str;
+      break;
+    case ae_primary_array:
+      a->d.array = cpy_array_sub(p, src->d.array);
+      break;
+    case ae_primary_vec:
+      cpy_vec(p, &a->d.vec, &src->d.vec);
+      break;
+    default:
+      a->d.exp = cpy_exp(p, src->d.exp);
+      break;
+  }
+  a->primary_type = src->primary_type;
+}
+
+ANN static Tmpl* cpy_tmpl(MemPool p, const Tmpl *src) {
+  Tmpl *a = mp_calloc(p, Tmpl);
+  if(src->list)
+    a->list = cpy_id_list(p, src->list);
+  if(src->call)
+    a->call = cpy_type_list(p, src->call);
+  a->base = src->base;
+  return a;
+}
+
+ANN static void cpy_exp_call(MemPool p, Exp_Call *a, const Exp_Call *src) {
+  a->func = cpy_exp(p, src->func);
+  if(src->args)
+    a->args = cpy_exp(p, src->args);
+  if(src->tmpl)
+    a->tmpl = cpy_tmpl(p, src->tmpl);
+}
+
+ANN static void cpy_exp_cast(MemPool p, Exp_Cast *a, const Exp_Cast *src) {
+  a->td = cpy_type_decl(p, src->td);
+  a->exp = cpy_exp(p, src->exp);
+}
+
+ANN static void cpy_exp_binary(MemPool p, Exp_Binary *a, const Exp_Binary *src) {
+  a->lhs = cpy_exp(p, src->lhs);
+  a->rhs = cpy_exp(p, src->rhs);
+  a->op = src->op;
+}
+
+ANN static void cpy_exp_postfix(MemPool p, Exp_Postfix *a, const Exp_Postfix *src) {
+  a->op = src->op;
+  a->exp = cpy_exp(p, src->exp);
+}
+
+ANN static void cpy_exp_if(MemPool p, Exp_If *a, const Exp_If *src) {
+  a->cond = cpy_exp(p, src->cond);
+  a->if_exp = cpy_exp(p, src->if_exp);
+  if(src->else_exp)
+    a->else_exp = cpy_exp(p, src->else_exp);
+}
+
+
+// TODO check me
+ANN static void cpy_exp_unary(MemPool p, Exp_Unary *a, const Exp_Unary *src) {
+  a->op = src->op;
+  if(src->exp)
+    a->exp = cpy_exp(p, src->exp);
+  if(src->td)
+    a->td = cpy_type_decl(p, src->td);
+  if(src->code)
+    a->code = cpy_stmt(p, src->code);
+}
+
+ANN static void cpy_exp_typeof(MemPool p, Exp_Typeof *a, const Exp_Typeof *src) {
+  a->exp = cpy_exp(p, src->exp);
+}
+
+ANN static Exp cpy_exp(MemPool p, const Exp src) {
+  Exp a = mp_calloc(p, Exp);
+  if(src->next)
+    a->next = cpy_exp(p, src->next);
+  switch(src->exp_type) {
+    case ae_exp_post:  // !! naming
+      cpy_exp_postfix(p, &a->d.exp_post, &src->d.exp_post);
+      break;
+    case ae_exp_primary:
+      cpy_exp_primary(p, &a->d.exp_primary, &src->d.exp_primary);
+      break;
+    case ae_exp_decl:
+      cpy_exp_decl(p, &a->d.exp_decl, &src->d.exp_decl);
+      break;
+    case ae_exp_unary:
+      cpy_exp_unary(p, &a->d.exp_unary, &src->d.exp_unary);
+      break;
+    case ae_exp_binary:
+      cpy_exp_binary(p, &a->d.exp_binary, &src->d.exp_binary);
+      break;
+    case ae_exp_cast:
+      cpy_exp_cast(p, &a->d.exp_cast, &src->d.exp_cast);
+      break;
+    case ae_exp_call:
+      cpy_exp_call(p, &a->d.exp_call, &src->d.exp_call);
+      break;
+    case ae_exp_if:
+      cpy_exp_if(p, &a->d.exp_if, &src->d.exp_if);
+      break;
+    case ae_exp_dot:
+      cpy_exp_dot(p, &a->d.exp_dot, &src->d.exp_dot);
+      break;
+    case ae_exp_array:
+      cpy_exp_array(p, &a->d.exp_array, &src->d.exp_array);
+      break;
+    case ae_exp_lambda:
+      cpy_exp_lambda(p, &a->d.exp_lambda, &src->d.exp_lambda);
+      break;
+    case ae_exp_typeof:
+      cpy_exp_typeof(p, &a->d.exp_typeof, &src->d.exp_typeof);
+      break;
+  }
+  a->exp_type = src->exp_type;
+  a->meta = src->meta;// maybe meta shoyuld be set as in constructors
+  a->pos = loc_cpy(p, src->pos);
+  return a;
+}
+
+ANN static Decl_List cpy_decl_list(MemPool p, const Decl_List src) {
+  Decl_List a = mp_calloc(p, Decl_List);
+  a->self = cpy_exp(p, src->self);
+  if(src->next)
+    a->next = cpy_decl_list(p, src->next);
+  return a;
+}
+
+ANN static void cpy_stmt_exp(MemPool p, const Stmt_Exp a, const Stmt_Exp src) {
+  if(src->val)
+    a->val = cpy_exp(p, src->val);
+}
+
+ANN static void cpy_stmt_flow(MemPool p, Stmt_Flow a,const Stmt_Flow src) {
+  if(src->cond)
+    a->cond = cpy_exp(p, src->cond); 
+  if(src->body)
+    a->body = cpy_stmt(p, src->body); 
+  a->is_do = src->is_do; 
+}
+
+ANN static void cpy_stmt_code(MemPool p, Stmt_Code a, const Stmt_Code src) {
+  if(src->stmt_list)
+    a->stmt_list = cpy_stmt_list(p, src->stmt_list);
+}
+
+ANN static void cpy_stmt_for(MemPool p, Stmt_For a, const Stmt_For src) {
+  if(src->c1)
+    a->c1 = cpy_stmt(p, src->c1); 
+  if(src->c2)
+    a->c2 = cpy_stmt(p, src->c2); 
+  if(src->c3)
+    a->c3 = cpy_exp(p, src->c3);
+  if(src->body)
+    a->body = cpy_stmt(p, src->body); 
+}
+
+ANN static void cpy_stmt_auto(MemPool p, Stmt_Auto a, const Stmt_Auto src) {
+  if(src->sym)
+    a->sym = src->sym;
+  if(src->exp)
+    a->exp = cpy_exp(p, src->exp);
+  if(src->body)
+    a->body = cpy_stmt(p, src->body);
+  if(src->is_ptr)
+    a->is_ptr = src->is_ptr; 
+}
+
+ANN static void cpy_stmt_loop(MemPool p, Stmt_Loop a, const Stmt_Loop src) {
+  if(src->cond)
+    a->cond = cpy_exp(p, src->cond); 
+  if(src->body)
+    a->body = cpy_stmt(p, src->body); 
+}
+
+ANN static void cpy_stmt_if(MemPool p, Stmt_If a, const Stmt_If src) {
+  if(src->cond)
+    a->cond = cpy_exp(p, src->cond);
+  if(src->if_body)
+    a->if_body = cpy_stmt(p, src->if_body);
+  if(src->else_body)
+    a->else_body = cpy_stmt(p, src->else_body);
+}
+
+ANN static void cpy_stmt_jump(MemPool p, const Stmt_Jump a,const Stmt_Jump src) {
+  a->name = src->name;
+}
+
+ANN static void cpy_stmt_switch(MemPool p, Stmt_Switch a, const Stmt_Switch src) {
+  a->val = cpy_exp(p, src->val);
+  a->stmt = cpy_stmt(p, src->stmt);
+}
+
+ANN static void cpy_stmt_enum(MemPool p, Stmt_Enum a, const Stmt_Enum src) {
+  a->list = cpy_id_list(p, src->list);
+  a->xid = src->xid;
+  a->flag = src->flag;
+}
+
+ANN Func_Base* cpy_func_base(MemPool p, const Func_Base* src) {
+  Func_Base *a = mp_calloc(p, Func_Base);
+  if(src->td)
+    a->td = cpy_type_decl(p, src->td); // 1 
+  if(src->xid)
+    a->xid = src->xid; // 1 
+  if(src->args)
+    a->args = cpy_arg_list(p, src->args); // 1 
+  if(src->tmpl)
+    a->tmpl = cpy_tmpl(p, src->tmpl); // 1 
+  return a;
+}
+
+ANN static void cpy_stmt_fptr(MemPool p, Stmt_Fptr a, const Stmt_Fptr src) {
+  a->base = cpy_func_base(p, src->base);
+}
+
+ANN static void cpy_stmt_type(MemPool p, Stmt_Type a, const Stmt_Type src) {
+  if(src->ext)
+    a->ext = cpy_type_decl(p, src->ext);
+  a->xid = src->xid;
+  if(src->tmpl)
+    a->tmpl = cpy_tmpl(p, src->tmpl);
+}
+
+ANN static void cpy_stmt_union(MemPool p, Stmt_Union a,const Stmt_Union src) {
+  a->l = cpy_decl_list(p, src->l); // 1 
+  if(src->xid)
+    a->xid = src->xid; // 1 
+  if(src->type_xid)
+    a->type_xid = src->type_xid; // 1 
+  if(src->tmpl)
+    a->tmpl = cpy_tmpl(p, src->tmpl); // 1 
+  a->flag = src->flag; // 1 
+}
+
+ANN static Stmt cpy_stmt(MemPool p, const Stmt src) {
+  Stmt a = mp_calloc(p, Stmt);
+  switch(src->stmt_type) {
+    case ae_stmt_case:
+    case ae_stmt_exp:
+  if(src->d.stmt_exp.val)
+    a->d.stmt_exp.val = cpy_exp(p, src->d.stmt_exp.val);
+
+//      cpy_stmt_exp(p, &a->d.stmt_exp, &src->d.stmt_exp);
+      break;
+    case ae_stmt_return:
+      if(&src->d.stmt_exp)
+        cpy_stmt_exp(p, &a->d.stmt_exp, &src->d.stmt_exp);
+      break;
+    case ae_stmt_code:
+      cpy_stmt_code(p, &a->d.stmt_code, &src->d.stmt_code);
+      break;
+    case ae_stmt_while:
+    case ae_stmt_until:
+      cpy_stmt_flow(p, &a->d.stmt_flow, &src->d.stmt_flow);
+      break;
+    case ae_stmt_loop:
+      cpy_stmt_loop(p, &a->d.stmt_loop, &src->d.stmt_loop);
+      break;
+    case ae_stmt_for:
+      cpy_stmt_for(p, &a->d.stmt_for, &src->d.stmt_for);
+      break;
+    case ae_stmt_auto:
+      cpy_stmt_auto(p, &a->d.stmt_auto, &src->d.stmt_auto);
+      break;
+    case ae_stmt_if:
+      cpy_stmt_if(p, &a->d.stmt_if, &src->d.stmt_if);
+      break;
+    case ae_stmt_jump:
+      cpy_stmt_jump(p, &a->d.stmt_jump, &src->d.stmt_jump);
+      break;
+    case ae_stmt_switch:
+      cpy_stmt_switch(p, &a->d.stmt_switch, &src->d.stmt_switch);
+      break;
+    case ae_stmt_enum:
+      cpy_stmt_enum(p, &a->d.stmt_enum, &src->d.stmt_enum);
+      break;
+    case ae_stmt_fptr:
+      cpy_stmt_fptr(p, &a->d.stmt_fptr, &src->d.stmt_fptr);
+      break;
+    case ae_stmt_type:
+      cpy_stmt_type(p, &a->d.stmt_type, &src->d.stmt_type);
+      break;
+    case ae_stmt_union:
+      cpy_stmt_union(p, &a->d.stmt_union, &src->d.stmt_union);
+      break;
+      case ae_stmt_break:
+      case ae_stmt_continue:
+        break;
+    }
+  a->stmt_type = src->stmt_type;
+  a->pos = loc_cpy(p, src->pos);
+  return a;
+}
+
+ANN Func_Def cpy_func_def(MemPool p, const Func_Def src) {
+  Func_Def a = mp_calloc(p, Func_Def);
+  a->base = cpy_func_base(p, src->base);
+  if(!GET_FLAG(a, builtin)) {
+    if(src->d.code)
+      a->d.code = cpy_stmt(p, src->d.code);
+  } else
+    a->d.dl_func_ptr = src->d.dl_func_ptr;
+  a->pos = loc_cpy(p, src->pos);
+  a->flag = src->flag;
+  return a;
+}
+
+ANN static Stmt_List cpy_stmt_list(MemPool p, const Stmt_List src) {
+  Stmt_List a = mp_calloc(p, Stmt_List);
+  if(src->next)
+    a->next = cpy_stmt_list(p, src->next);
+  a->stmt = cpy_stmt(p, src->stmt);
+  return a;
+}
+
+ANN static Section* cpy_section(MemPool p, const Section *src) {
+  Section* a = mp_calloc(p, Section);
+  switch(src->section_type) {
+    case ae_section_stmt:
+      a->d.stmt_list = cpy_stmt_list(p, src->d.stmt_list);
+      break;
+    case ae_section_class:
+      a->d.class_def = cpy_class_def(p, src->d.class_def);
+      break;
+    case ae_section_func:
+      a->d.func_def = cpy_func_def(p, src->d.func_def);
+      break;
+  }
+  a->section_type = src->section_type;
+  return a;
+}
+
+ANN static Class_Body cpy_class_body(MemPool p, const Class_Body src) {
+  Class_Body a = mp_calloc(p, Class_Body);
+  a->section = cpy_section(p, src->section);
+  if(src->next)
+    a->next = cpy_class_body(p, src->next);
+  return a;
+}
+
+ANN Class_Def cpy_class_def(MemPool p, const Class_Def src) {
+  Class_Def a = mp_calloc(p, Class_Def);
+  cpy_stmt_type(p, &a->base, &src->base);
+  if(src->body) {
+    if(!GET_FLAG(src, union))
+      a->body = cpy_class_body(p, src->body);
+    else
+      a->list = cpy_decl_list(p, src->list);
+  }
+  a->flag = src->flag;
+  a->pos = loc_cpy(p, src->pos);
+  return a;
+}
+
+ANN static Ast cpy_ast(MemPool p, const Ast src) {
+  Ast a = mp_calloc(p, Ast);
+  a->section = cpy_section(p, src->section);
+  if(src->next)
+    a->next = cpy_ast(p, src->next);
+  return a;
+}
+
index 7aebd43d56f443b61a3e2823d594f37f651181b5..2d3ce42c17e425b2e9146aec1ae1e5de7fd195a3 100644 (file)
 #include "value.h"
 
 ANN static void free_func(Func a, Gwion gwion) {
-//  if(GET_FLAG(a, template) && !is_fptr(a->value_ref->type)) {
-  if(GET_FLAG(a, template) && !GET_FLAG(a, builtin) && a->def->d.code) {
-    free_tmpl(gwion->mp, a->def->base->tmpl);
-    free_func_base(gwion->mp, a->def->base);
-    free_loc(gwion->mp, a->def->pos);
-    mp_free(gwion->mp, Func_Def, a->def);
-  }
+  if(GET_FLAG(a, template) && !GET_FLAG(a, builtin)/* && a->def->d.code*/)
+    free_func_def(gwion->mp, a->def);
   if(a->code)
     REM_REF(a->code, gwion);
   mp_free(gwion->mp, Func, a);
index a1cc966bb8332cd73e503784656c3da5fa8ad955..59cd50f680c4308da92189f211ff0ff96fee48e2 100644 (file)
@@ -14,7 +14,7 @@
 
 static inline void add_type(const Env env, const Nspc nspc, const Type t) {
   map_set(&nspc->info->type->map, (m_uint)insert_symbol(t->name), (m_uint)t);
-  map_set(vector_front(&nspc->info->type->ptr), (m_uint)insert_symbol(t->name), (m_uint)t);
+//  map_set((Map)vector_front((Vector)&nspc->info->type->ptr), (m_uint)insert_symbol(t->name), (m_uint)t);
 }
 
 ANN static Value mk_class(const Env env, const Type base) {
@@ -197,11 +197,12 @@ ANN m_bool scan0_stmt_union(const Env env, const Stmt_Union stmt) {
   if(stmt->tmpl) {
     if(tmpl_base(stmt->tmpl)) {
       const Class_Def cdef = new_class_def(env->gwion->mp, stmt->flag, stmt->type_xid,
-          NULL, (Class_Body)stmt->l, stmt_self(stmt)->pos);
+          NULL, (Class_Body)stmt->l, loc_cpy(env->gwion->mp, stmt_self(stmt)->pos));
       stmt->type->e->def = cdef;
       cdef->base.tmpl = stmt->tmpl;
       cdef->base.type = stmt->type;
       cdef->list = stmt->l;
+      SET_FLAG(cdef, union);
       SET_FLAG(stmt->type, pure);
       SET_FLAG(stmt, template);
       SET_FLAG(stmt->type, template);
index 1c2195863f0d080bc32fd96c446782c203da9f02..56cd35d6c2089c3b9ab05085c760df073d9dbb77 100644 (file)
@@ -245,8 +245,8 @@ ANN static m_bool scan1_args(const Env env, Arg_List list) {
 ANN m_bool scan1_stmt_fptr(const Env env, const Stmt_Fptr stmt) {
   if(!stmt->type)
     CHECK_BB(scan0_stmt_fptr(env, stmt))
-  if(stmt->base->tmpl)//
-    return GW_OK;//
+  if(tmpl_base(stmt->base->tmpl))
+    return GW_OK;
   CHECK_OB((stmt->base->ret_type = known_type(env, stmt->base->td)))
   return stmt->base->args ? scan1_args(env, stmt->base->args) : GW_OK;
 }
@@ -258,7 +258,7 @@ ANN m_bool scan1_stmt_type(const Env env, const Stmt_Type stmt) {
 }
 
 ANN m_bool scan1_stmt_union(const Env env, const Stmt_Union stmt) {
-  if(stmt->tmpl)
+  if(tmpl_base(stmt->tmpl))
     return GW_OK;
   if(!stmt->value)
     CHECK_BB(scan0_stmt_union(env, stmt))
index 1739e38b1d9846d801de6174803d6db66fb7f6a8..f0ec7dd693a8339ff3dc3cd4ba288298685e38f6 100644 (file)
@@ -106,13 +106,12 @@ ANN void fptr_assign(const Env env, const Stmt_Fptr ptr) {
 
 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) {
+  if(!tmpl_base(ptr->base->tmpl)) {
     def->base->ret_type = ptr->base->ret_type;
     if(ptr->base->args)
       CHECK_BB(scan2_args(env, def))
   } 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);
   return GW_OK;
 }
@@ -272,7 +271,7 @@ ANN static m_bool scan2_stmt_jump(const Env env, const Stmt_Jump stmt) {
 }
 
 ANN m_bool scan2_stmt_union(const Env env, const Stmt_Union stmt) {
-  if(stmt->tmpl)
+  if(tmpl_base(stmt->tmpl))
     return GW_OK;
   const m_uint scope = union_push(env, stmt);
   Decl_List l = stmt->l;
index 5cfbeba017635ca0270c60b50baa1921dab0caa0..afd0bad4a1d6f8f3c3184fe8678b1dd6ea03ef76 100644 (file)
@@ -13,6 +13,7 @@
 #include "vm.h"
 #include "parse.h"
 #include "gwion.h"
+#include "cpy_ast.h"
 
 ANN static inline Type owner_type(const Env env, const Type t) {
   const Nspc nspc = t->nspc ? t->nspc->parent : NULL;
@@ -123,8 +124,12 @@ ANN static Class_Def template_class(const Env env, const Class_Def def, const Ty
   if(env->class_def && name == insert_symbol(env->class_def->name))
      return env->class_def->e->def;
   const Type t = nspc_lookup_type1(env->curr, name);
-  return t ? t->e->def : new_class_def(env->gwion->mp, def->flag, name, def->base.ext, def->body,
-    loc_cpy(env->gwion->mp, def->pos));
+  if(t)
+    return t->e->def;
+  const Class_Def c = cpy_class_def(env->gwion->mp, def);
+  c->base.xid = name;
+  return c;
+
 }
 
 ANN m_bool template_push_types(const Env env, const Tmpl *tmpl) {
@@ -175,12 +180,12 @@ ANN Type scan_type(const Env env, const Type t, const Type_Decl* type) {
       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);
     } else {
-      a->stmt = new_stmt_union(env->gwion->mp, (Decl_List)a->body, t->e->def->pos);
+      a->stmt = new_stmt_union(env->gwion->mp, a->list, t->e->def->pos);
       a->stmt->d.stmt_union.type_xid = a->base.xid;
       CHECK_BO(scan0_stmt_union(env, &a->stmt->d.stmt_union))
       a->base.type = a->stmt->d.stmt_union.type;
       a->base.type->e->def = a;
-      SET_FLAG(a, union);
+      assert(GET_FLAG(a, union));
     }
     SET_FLAG(a->base.type, template | ae_flag_ref);
     a->base.type->e->owner = t->e->owner;
@@ -191,7 +196,6 @@ ANN Type scan_type(const Env env, const Type t, const Type_Decl* type) {
   } else if(type->types) { // TODO: clean me
     if(isa(t, t_function) > 0 && t->e->d.func->def->base->tmpl) {
       DECL_OO(const m_str, tl_name, = tl2str(env, type->types))
-// err_msg here ?
       const Symbol sym = func_symbol(env, t->e->owner->name, t->e->d.func->name, tl_name, 0);
       free_mstr(env->gwion->mp, tl_name);
       const Type base_type = nspc_lookup_type1(t->e->owner, sym);
@@ -202,9 +206,7 @@ ANN Type scan_type(const Env env, const Type t, const Type_Decl* type) {
       ret->name = s_name(sym);
       SET_FLAG(ret, func);
       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, t->e->d.func->def->flag, loc_cpy(env->gwion->mp, td_pos(type)));
+      const Func_Def def = cpy_func_def(env->gwion->mp, t->e->d.func->def);
       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;
index cd75753ddb571d37adeb68ec16072254c1cb9f69..aeeb4d11da607e6071f33e0c169abb8ae4277725 100644 (file)
@@ -25,12 +25,11 @@ ANN Type type_decl_resolve(const Env env, const Type_Decl* td) {
     if(exist)
       return exist;
     const Type t = type_copy(env->gwion->mp, ret);
-assert(t->size == SZ_INT);
     t->name = s_name(sym);
     t->e->parent = ret;
     SET_FLAG(t, nonnull);
     ADD_REF(ret);
-    map_set(vector_front(&t->e->owner->info->type->ptr), sym, t);
+    map_set(&t->e->owner->info->type->map, (vtype)sym, (vtype)t);
     return t;
   }
   return ret;
diff --git a/tests/error/variadic_miss_end.gw b/tests/error/variadic_miss_end.gw
new file mode 100644 (file)
index 0000000..7ff8ee1
--- /dev/null
@@ -0,0 +1,3 @@
+fun void test(...) {
+  vararg.start;
+}
diff --git a/tests/new/class_fptr_returns_fptr.gw b/tests/new/class_fptr_returns_fptr.gw
new file mode 100644 (file)
index 0000000..6756a1c
--- /dev/null
@@ -0,0 +1,24 @@
+class C {
+int i;
+  typedef void t_fptr0();
+  typedef void t_fptr1(int i);
+  fun void test() { <<< this , " ", __func__ >>>;}
+  fun void test(int i) { <<< __func__, " ", i >>>;}
+#!  fun t_fptr call() {
+#!    <<< this >>>;
+#!    return test $ t_fptr;
+#!  }
+#!  spork call();
+#!  me.yield();
+#!<<< this >>>;
+#!  test @=>
+test @=> t_fptr0 ptr0;
+test @=> t_fptr1 ptr1;
+<<<ptr0>>>;
+  spork ptr0();
+#!  spork ptr1(2);
+  me.yield();
+}
+<<< C c >>>;
+#!<<< c.test >>>;
+#!<<< c.call() >>>;
diff --git a/tests/new/implicit_fptr.gw b/tests/new/implicit_fptr.gw
new file mode 100644 (file)
index 0000000..01c9314
--- /dev/null
@@ -0,0 +1,8 @@
+class C {
+  typedef void T();
+  fun int f(T t) { <<< t >>>;  t();}
+  fun void test() { <<< __func__ >>>; }
+  test => f;
+  f(test);
+}
+C c;
diff --git a/tests/new/int_float_minus.gw b/tests/new/int_float_minus.gw
new file mode 100644 (file)
index 0000000..9d1e9fa
--- /dev/null
@@ -0,0 +1,14 @@
+fun float test(float f) {
+   return f;
+}
+
+<<< 1 - 2.0 => test >>>;
+
+
+<<< 1.9 > 1 >>>;
+
+int i;
+
+<<< .1 -=> i >>>;
+
+<<< 1 -.1 >>>;
diff --git a/tests/new/lambda_return.gw b/tests/new/lambda_return.gw
new file mode 100644 (file)
index 0000000..dca32f8
--- /dev/null
@@ -0,0 +1,4 @@
+#! <<< \ { <<< __func__ >>>; }() >>>;
+
+
+ <<< \ { if(maybe)return .2; return 1; }() >>>;
diff --git a/tests/new/recursive_template.gw b/tests/new/recursive_template.gw
new file mode 100644 (file)
index 0000000..dab026b
--- /dev/null
@@ -0,0 +1,9 @@
+fun void test<~A~>(int i, A a) {
+  A b;
+  <<< __func__, " ", a >>>;
+  <<< i, " ", a >>>;
+  if(i)
+    test<~int~>((i-2, b));
+#!    test((i-2.0));
+}
+test<~float~>(2, 2);
diff --git a/tests/new/recursive_template0.gw b/tests/new/recursive_template0.gw
new file mode 100644 (file)
index 0000000..89ba564
--- /dev/null
@@ -0,0 +1,9 @@
+fun void test<~A~>(int i) {
+  A a;
+  <<< a >>>;
+  <<< __func__, " ", i, " ", a >>>;
+  if(i)
+#!me.exit();
+  test<~float~>((i-2));
+}
+test<~float~>(2);
diff --git a/tests/new/recursive_template1.gw b/tests/new/recursive_template1.gw
new file mode 100644 (file)
index 0000000..ddfbf06
--- /dev/null
@@ -0,0 +1,9 @@
+fun void test<~A~>(int i) {
+  A a;
+  <<< a >>>;
+#!  <<< __func__, " ", i, " ", a >>>;
+  if(i)
+#!me.exit();
+    test<~float~>((i-2));
+}
+test<~Object~>(2);
diff --git a/tests/new/recursive_template2.gw b/tests/new/recursive_template2.gw
new file mode 100644 (file)
index 0000000..4755a58
--- /dev/null
@@ -0,0 +1,9 @@
+fun void test<~A~>(A i) {
+  A a;
+  <<< a , " ", __func__>>>;
+  <<< i, " ", a >>>;
+  if(i > 0)
+#!me.exit();
+    test(i-2.0);
+}
+test<~int~>(2);
diff --git a/tests/new/recursive_template3.gw b/tests/new/recursive_template3.gw
new file mode 100644 (file)
index 0000000..4d753ba
--- /dev/null
@@ -0,0 +1,14 @@
+fun void test<~A~>(A i) {
+  A a;
+  <<< a >>>;
+  <<< i, " ", a, " ", i > 1 >>>;
+  if(i > 1) {
+#!    2 -=> i;
+#!    i => A a;
+#!    test(a);
+    .1 -=> i;
+    test(i);
+#!    test(i);
+  }
+}
+test(2.0);
diff --git a/tests/new/recursive_template_test.gw b/tests/new/recursive_template_test.gw
new file mode 100644 (file)
index 0000000..5416ba7
--- /dev/null
@@ -0,0 +1,6 @@
+fun void test<~A~>(int i) {
+  <<< __func__ >>>;
+
+  <<< 1 >>>;
+}
+test<~int~>(1);
diff --git a/tests/new/spork_fptr.gw b/tests/new/spork_fptr.gw
new file mode 100644 (file)
index 0000000..e1bef54
--- /dev/null
@@ -0,0 +1,15 @@
+class C {
+typedef void t_fptr(int i);
+fun void test(int i) { <<< this , " ", __func__, " ", i >>>;}
+test @=> t_fptr ptr;
+}
+typedef void t_fptr(int i);
+fun void test(int i) { <<< __func__, " ", i >>>;}
+test @=> t_fptr ptr;
+<<< ptr >>>;
+spork ptr(2);
+me.yield();
+<<<C c>>>;
+<<< c.ptr >>>;
+spork c.ptr(3);
+me.yield();
diff --git a/tests/new/spork_fptr2.gw b/tests/new/spork_fptr2.gw
new file mode 100644 (file)
index 0000000..a286dbf
--- /dev/null
@@ -0,0 +1,12 @@
+class C {
+  typedef void t_fptr(int i, int);
+  fun void test(int i, int j) { <<< this ,
+       " ", __func__, " ", i, " " , j >>>;}
+  test @=> t_fptr ptr;
+<<< this, ptr >>>;
+#!  ptr(2);
+  spork ptr(1,2);
+#!  me.yield();
+  second => now;
+}
+<<<C c>>>;