From b06a02263d5762d1b60183d80fe03f3394ffb4c7 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Sat, 30 Jul 2022 07:34:07 +0200 Subject: [PATCH] :art: Allow no types in variadic --- src/import/import_checker.c | 13 ++++++++++ src/parse/func_resolve_tmpl.c | 6 +++-- src/parse/template.c | 48 +++++++++++++++++++++++------------ 3 files changed, 49 insertions(+), 18 deletions(-) diff --git a/src/import/import_checker.c b/src/import/import_checker.c index b21721ae..0dea184f 100644 --- a/src/import/import_checker.c +++ b/src/import/import_checker.c @@ -84,6 +84,15 @@ ANN m_bool str2var(const Gwion gwion, Var_Decl *vd, const m_str path, const loc_ #define SPEC_ERROR (Specialized_List) GW_ERROR ANN static bool _tmpl_list(const Gwion gwion, struct td_checker *tdc, Specialized_List *sl) { + if(unlikely(!strncmp(tdc->str, "...", 3))) { + tdc->str += 3; + Specialized spec = { + .xid = insert_symbol(gwion->st, "..."), + .pos = tdc->pos + }; + mp_vector_add(gwion->mp, sl, Specialized, spec); + return true; + } DECL_OO(const Symbol, sym, = __str2sym(gwion, tdc)); // TODO: handle traits? Specialized spec = { @@ -286,6 +295,10 @@ ANN static void td_fullname(const Env env, GwText *text, const Type t) { ANN static m_bool td_info_run(const Env env, struct td_info *info) { Type_List tl = info->tl; + if(unlikely(!tl->len)) { + text_add(&info->text, ""); + return GW_OK; + } for(uint32_t i = 0; i < tl->len; i++) { if (i) text_add(&info->text, ","); DECL_OB(Type_Decl *, td, = *mp_vector_at(tl, Type_Decl*, i)); diff --git a/src/parse/func_resolve_tmpl.c b/src/parse/func_resolve_tmpl.c index 23dccba0..1cbeff5e 100644 --- a/src/parse/func_resolve_tmpl.c +++ b/src/parse/func_resolve_tmpl.c @@ -147,12 +147,14 @@ ANN static Func find_tmpl(const Env env, const Value v, Exp_Call *const exp, .v = v, .e = exp, .tmpl_name = tmpl_name, .types = types}; CHECK_BO(envset_pushv(&es, v)); (void)env_push(env, v->from->owner_class, v->from->owner); - if (v->from->owner_class && v->from->owner_class->info->cdef->base.tmpl) + const bool in_tmpl = v->from->owner_class && v->from->owner_class->info->cdef && + v->from->owner_class->info->cdef->base.tmpl; + if(in_tmpl) (void)template_push_types(env, v->from->owner_class->info->cdef->base.tmpl); const bool is_clos = isa(exp->func->type, env->gwion->type[et_closure]) > 0; const Func m_func = !is_clos ? func_match(env, &ra) : fptr_match(env, &ra); - if (v->from->owner_class && v->from->owner_class->info->cdef->base.tmpl) + if(in_tmpl) nspc_pop_type(env->gwion->mp, env->curr); env_pop(env, scope); if (es.run) envset_pop(&es, v->from->owner_class); diff --git a/src/parse/template.c b/src/parse/template.c index 30262609..d6b273b3 100644 --- a/src/parse/template.c +++ b/src/parse/template.c @@ -134,16 +134,44 @@ static ANN Type maybe_func(const Env env, const Type t, const Type_Decl *td) { t->name) } +static ANN bool is_single_variadic(const MP_Vector *v) { + if(v->len != 1) return false; + const Specialized *spec = mp_vector_at(v, Specialized, 0); + return !strcmp(s_name(spec->xid), "..."); +} + +ANN2(1,2) static m_bool check_tmpl(const Env env, const Type_List tl, const Specialized_List sl, const loc_t pos, const bool is_spread) { + if (!sl || sl->len > tl->len || (tl->len != sl->len && !is_spread)) + ERR_B(pos, "invalid template type number"); + for (uint32_t i = 0; i < sl->len; i++) { + Type_Decl *tmp = *mp_vector_at(tl, Type_Decl*, i); + DECL_OB(const Type, t, = known_type(env, tmp)); + Specialized *spec = mp_vector_at(sl, Specialized, i); + if(spec->traits) { + Symbol missing = miss_traits(t, spec); + if (missing) { + ERR_B(pos, "does not implement requested trait '{/}%s{0}'", + s_name(missing)); + } + } + } + return GW_OK; +} + ANN static Type _scan_type(const Env env, const Type t, Type_Decl *td) { if (tflag(t, tflag_tmpl) && !is_func(env->gwion, t)) { // is_callable if (tflag(t, tflag_ntmpl) && !td->types) return t; + const bool single_variadic = is_single_variadic(t->info->cdef->base.tmpl->list); if(!td->types) { const Type new_type = nspc_lookup_type1(env->curr, td->xid); Type_Decl *new_td = type2td(env->gwion, new_type, td->pos); Type_Decl *d = new_td; while(d->next) d = d->next; - if(!d->types) - ERR_N(td->pos, _("you must provide template types for type '%s' !!!"), t->name); + if(!d->types) { + if(!single_variadic) + ERR_N(td->pos, _("you must provide template types for type '%s' !!!"), t->name); + d->types = new_mp_vector(env->gwion->mp, Type_Decl*, 0); + } const Type ret = _scan_type(env, t, d); free_type_decl(env->gwion->mp, new_td); return ret; @@ -152,20 +180,8 @@ ANN static Type _scan_type(const Env env, const Type t, Type_Decl *td) { Type_List tl = td->types; Specialized_List sl = t->info->cdef->base.tmpl ? t->info->cdef->base.tmpl->list : NULL; - if (!sl || sl->len > tl->len || (tl->len != sl->len && !is_spread_tmpl(t->info->cdef->base.tmpl))) - ERR_O(td->pos, "invalid template type number"); - for (uint32_t i = 0; i < sl->len; i++) { - Type_Decl *tmp = *mp_vector_at(tl, Type_Decl*, i); - DECL_OO(const Type, t, = known_type(env, tmp)); - Specialized *spec = mp_vector_at(sl, Specialized, i); - if(spec->traits) { - Symbol missing = miss_traits(t, spec); - if (missing) { - ERR_O(td->pos, "does not implement requested trait '{/}%s{0}'", - s_name(missing)); - } - } - } + const bool is_spread = is_spread_tmpl(t->info->cdef->base.tmpl); + if(!single_variadic) CHECK_BO(check_tmpl(env, tl, sl, td->pos, is_spread)); struct Op_Import opi = {.op = insert_symbol("@scan"), .lhs = t, .data = (uintptr_t)&ts, -- 2.43.0