From 1d34b8e91da13fb9316f12e85b4975f3f529353f Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Tue, 23 Jul 2019 18:14:43 +0200 Subject: [PATCH] :art: Copy def for templates :smile: --- ast | 2 +- include/cpy_ast.h | 6 + src/emit/emit.c | 44 +-- src/lib/func.c | 4 +- src/lib/import.c | 2 +- src/lib/instr.c | 7 +- src/lib/object.c | 5 +- src/parse/check.c | 104 +++--- src/parse/cpy_ast.c | 484 +++++++++++++++++++++++++++ src/parse/func.c | 9 +- src/parse/scan0.c | 5 +- src/parse/scan1.c | 6 +- src/parse/scan2.c | 5 +- src/parse/template.c | 18 +- src/parse/type_decl.c | 3 +- tests/error/variadic_miss_end.gw | 3 + tests/new/class_fptr_returns_fptr.gw | 24 ++ tests/new/implicit_fptr.gw | 8 + tests/new/int_float_minus.gw | 14 + tests/new/lambda_return.gw | 4 + tests/new/recursive_template.gw | 9 + tests/new/recursive_template0.gw | 9 + tests/new/recursive_template1.gw | 9 + tests/new/recursive_template2.gw | 9 + tests/new/recursive_template3.gw | 14 + tests/new/recursive_template_test.gw | 6 + tests/new/spork_fptr.gw | 15 + tests/new/spork_fptr2.gw | 12 + 28 files changed, 711 insertions(+), 129 deletions(-) create mode 100644 include/cpy_ast.h create mode 100644 src/parse/cpy_ast.c create mode 100644 tests/error/variadic_miss_end.gw create mode 100644 tests/new/class_fptr_returns_fptr.gw create mode 100644 tests/new/implicit_fptr.gw create mode 100644 tests/new/int_float_minus.gw create mode 100644 tests/new/lambda_return.gw create mode 100644 tests/new/recursive_template.gw create mode 100644 tests/new/recursive_template0.gw create mode 100644 tests/new/recursive_template1.gw create mode 100644 tests/new/recursive_template2.gw create mode 100644 tests/new/recursive_template3.gw create mode 100644 tests/new/recursive_template_test.gw create mode 100644 tests/new/spork_fptr.gw create mode 100644 tests/new/spork_fptr2.gw diff --git a/ast b/ast index bd7f714f..5d8450be 160000 --- 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 index 00000000..54344060 --- /dev/null +++ b/include/cpy_ast.h @@ -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 diff --git a/src/emit/emit.c b/src/emit/emit.c index 3a0228fa..76a30554 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -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) { diff --git a/src/lib/func.c b/src/lib/func.c index f544ebd9..68778e62 100644 --- a/src/lib/func.c +++ b/src/lib/func.c @@ -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) diff --git a/src/lib/import.c b/src/lib/import.c index 56ecdfd9..ef280069 100644 --- a/src/lib/import.c +++ b/src/lib/import.c @@ -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); } diff --git a/src/lib/instr.c b/src/lib/instr.c index bf97cd36..13ffed02 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -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; diff --git a/src/lib/object.c b/src/lib/object.c index 4d2e1f17..d3e09a93 100644 --- a/src/lib/object.c +++ b/src/lib/object.c @@ -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) { diff --git a/src/parse/check.c b/src/parse/check.c index 75d7a033..de70be55 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -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: ''")) + " 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 index 00000000..2f9f3c57 --- /dev/null +++ b/src/parse/cpy_ast.c @@ -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; +} + diff --git a/src/parse/func.c b/src/parse/func.c index 7aebd43d..2d3ce42c 100644 --- a/src/parse/func.c +++ b/src/parse/func.c @@ -11,13 +11,8 @@ #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); diff --git a/src/parse/scan0.c b/src/parse/scan0.c index a1cc966b..59cd50f6 100644 --- a/src/parse/scan0.c +++ b/src/parse/scan0.c @@ -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); diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 1c219586..56cd35d6 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -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)) diff --git a/src/parse/scan2.c b/src/parse/scan2.c index 1739e38b..f0ec7dd6 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -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; diff --git a/src/parse/template.c b/src/parse/template.c index 5cfbeba0..afd0bad4 100644 --- a/src/parse/template.c +++ b/src/parse/template.c @@ -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; diff --git a/src/parse/type_decl.c b/src/parse/type_decl.c index cd75753d..aeeb4d11 100644 --- a/src/parse/type_decl.c +++ b/src/parse/type_decl.c @@ -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 index 00000000..7ff8ee1d --- /dev/null +++ b/tests/error/variadic_miss_end.gw @@ -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 index 00000000..6756a1c7 --- /dev/null +++ b/tests/new/class_fptr_returns_fptr.gw @@ -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; +<<>>; + 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 index 00000000..01c93148 --- /dev/null +++ b/tests/new/implicit_fptr.gw @@ -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 index 00000000..9d1e9fad --- /dev/null +++ b/tests/new/int_float_minus.gw @@ -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 index 00000000..dca32f80 --- /dev/null +++ b/tests/new/lambda_return.gw @@ -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 index 00000000..dab026b9 --- /dev/null +++ b/tests/new/recursive_template.gw @@ -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 index 00000000..89ba5643 --- /dev/null +++ b/tests/new/recursive_template0.gw @@ -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 index 00000000..ddfbf064 --- /dev/null +++ b/tests/new/recursive_template1.gw @@ -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 index 00000000..4755a580 --- /dev/null +++ b/tests/new/recursive_template2.gw @@ -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 index 00000000..4d753ba5 --- /dev/null +++ b/tests/new/recursive_template3.gw @@ -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 index 00000000..5416ba74 --- /dev/null +++ b/tests/new/recursive_template_test.gw @@ -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 index 00000000..e1bef54b --- /dev/null +++ b/tests/new/spork_fptr.gw @@ -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.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 index 00000000..a286dbfb --- /dev/null +++ b/tests/new/spork_fptr2.gw @@ -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; +} +<<>>; -- 2.43.0