From c7997051829e1ed557eaf24c1af758515993d4eb Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Wed, 17 Mar 2021 17:04:54 +0100 Subject: [PATCH] :art: Templates/Array and return fixes --- include/env/func.h | 11 +++++----- src/env/type.c | 4 ++-- src/gwion.c | 6 +++--- src/parse/check.c | 35 +++++++++++++------------------ src/parse/template.c | 4 +++- src/parse/type_decl.c | 3 --- tests/UsrUgen/UsrUGen_no_float.gw | 1 + tests/error/late_return.gw | 6 ++++++ tests/error/mandatory_return.gw | 5 +++++ tests/error/template_dyn2.gw | 10 ++++----- tests/tree/tmpl_array.gw | 14 +++++++++++++ 11 files changed, 59 insertions(+), 40 deletions(-) create mode 100644 tests/error/late_return.gw create mode 100644 tests/error/mandatory_return.gw create mode 100644 tests/tree/tmpl_array.gw diff --git a/include/env/func.h b/include/env/func.h index 6f0e416a..879bed56 100644 --- a/include/env/func.h +++ b/include/env/func.h @@ -2,11 +2,12 @@ #define __FUNC enum fflag { - fflag_none = 1 << 0, - fflag_pure = 1 << 1, - fflag_ftmpl = 1 << 2, - fflag_tmpl = 1 << 3, - fflag_valid = 1 << 4, + fflag_none = 1 << 0, + fflag_pure = 1 << 1, + fflag_ftmpl = 1 << 2, + fflag_tmpl = 1 << 3, + fflag_valid = 1 << 4, + fflag_return = 1 << 5, } __attribute__((packed)); struct Func_ { diff --git a/src/env/type.c b/src/env/type.c index db2e5137..972937f9 100644 --- a/src/env/type.c +++ b/src/env/type.c @@ -78,11 +78,12 @@ ANN Type typedef_base(Type t) { ANN Type array_base(Type type) { const Type t = typedef_base(type); -// return t->array_depth ? t->info->base_type : t; return t->array_depth ? array_base(t->info->base_type) : t; } ANN /*static */Symbol array_sym(const Env env, const Type src, const m_uint depth) { + if(src->array_depth == depth) + return insert_symbol(src->name); const Type t = array_base(src); size_t len = strlen(t->name); char name[len + 2* depth + 1]; @@ -99,7 +100,6 @@ ANN /*static */Symbol array_sym(const Env env, const Type src, const m_uint dept #include "operator.h" #include "import.h" ANN Type array_type(const Env env, const Type src, const m_uint depth) { -if(src == env->gwion->type[et_auto])return src; const Symbol sym = array_sym(env, src, depth); const Type type = nspc_lookup_type1(src->info->owner, sym); if(type) diff --git a/src/gwion.c b/src/gwion.c index 4111b1fa..c7c5d086 100644 --- a/src/gwion.c +++ b/src/gwion.c @@ -147,9 +147,9 @@ ANN void gwion_end(const Gwion gwion) { ANN static void env_header(const Env env) { if(env->class_def) - gwerr_secondary("in class:", env->name, env->class_def->info->cdef->pos); + gwerr_secondary("in class", env->name, env->class_def->info->cdef->pos); if(env->func && env->func != (Func)1 && env->func->def) - gwerr_secondary("in function:", env->name, env->func->def->base->pos); + gwerr_secondary("in function", env->name, env->func->def->base->pos); } ANN static void env_xxx(const Env env, const loc_t pos, const m_str fmt, va_list arg) { @@ -161,7 +161,7 @@ ANN static void env_xxx(const Env env, const loc_t pos, const m_str fmt, va_list char c[size + 1]; vsprintf(c, fmt, arg); gwerr_basic(c, NULL, NULL, env->name, pos, 0); -// env_header(env); + env_header(env); #endif } diff --git a/src/parse/check.c b/src/parse/check.c index 81e00bd4..5b7a28ef 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -376,25 +376,10 @@ static ANN Type check_exp_slice(const Env env, const Exp_Slice* range) { return op_check(env, &opi); } -ANN2(1,2) static Type_Decl* prepend_type_decl(MemPool mp, const Symbol xid, Type_Decl* td, const struct loc_t_ pos) { - Type_Decl *a = new_type_decl(mp, xid, pos); - a->next = td; - return a; -} - -ANN static Type_List mk_type_list(const Env env, const Type type, const loc_t pos) { - struct Vector_ v; - vector_init(&v); - vector_add(&v, (vtype)insert_symbol(type->name)); - Type owner = type->info->owner_class; - while(owner) { - vector_add(&v, (vtype)insert_symbol(owner->name)); - owner = owner->info->owner_class; - } - Type_Decl *td = NULL; - for(m_uint i = 0 ; i < vector_size(&v); ++i) - td = prepend_type_decl(env->gwion->mp, (Symbol)vector_at(&v, i), td, pos); - vector_release(&v); +ANN static Type_List mk_type_list(const Env env, const Arg_List arg, const Type type, const loc_t pos) { + const Type t = !arg->td->array ? + type : array_type(env, type, arg->td->array->depth); + Type_Decl *td = type2td(env->gwion, t, pos); return new_type_list(env->gwion->mp, td, NULL); } @@ -622,7 +607,7 @@ ANN static Type_List check_template_args(const Env env, Exp_Call *exp, const Tmp Exp template_arg = exp->args; while(arg && template_arg) { if(list->xid == arg->td->xid) { - tl[args_number] = mk_type_list(env, template_arg->type, fdef->base->pos); + tl[args_number] = mk_type_list(env, arg, template_arg->type, fdef->base->pos); if(args_number) tl[args_number - 1]->next = tl[args_number]; ++args_number; @@ -1052,6 +1037,8 @@ stmt_func_xxx(each, Stmt_Each,, do_stmt_each(env, stmt)) ANN static m_bool check_stmt_return(const Env env, const Stmt_Exp stmt) { if(!env->func) ERR_B(stmt_self(stmt)->pos, _("'return' statement found outside function definition")) + if(env->scope->depth == 1) // so ops no dot set scope->depth ? + set_fflag(env->func, fflag_return); DECL_OB(const Type, ret_type, = stmt->val ? check_exp(env, stmt->val) : env->gwion->type[et_void]) if(!env->func->def->base->ret_type) { assert(isa(env->func->value_ref->type, env->gwion->type[et_lambda]) > 0); @@ -1303,8 +1290,14 @@ ANN static m_bool check_func_def_override(const Env env, const Func_Def fdef) { ANN m_bool check_fdef(const Env env, const Func_Def fdef) { if(fdef->base->args) CHECK_BB(check_func_args(env, fdef->base->args)) - if(fdef->d.code) + if(fdef->d.code) { + env->scope->depth--; CHECK_BB(check_stmt_code(env, &fdef->d.code->d.stmt_code)) + env->scope->depth++; + } + if(fdef->base->ret_type && fdef->base->ret_type != env->gwion->type[et_void] && + fdef->d.code && !fflag(fdef->base->func, fflag_return)) + ERR_B(fdef->base->td->pos, _("missing return statement in a non void function")); return GW_OK; } diff --git a/src/parse/template.c b/src/parse/template.c index 9f0a8d21..111c20c2 100644 --- a/src/parse/template.c +++ b/src/parse/template.c @@ -99,6 +99,8 @@ ANN Type _scan_type(const Env env, const Type t, Type_Decl* td) { if(tflag(t, tflag_tmpl) && isa(t, env->gwion->type[et_function]) < 0) { if(tflag(t, tflag_ntmpl) && !td->types) return t; +// if(t->array_depth && tflag(t, tflag_scan1)) +// return t; struct TemplateScan ts = { .t=t, .td=td }; struct Op_Import opi = { .op=insert_symbol("@scan"), .lhs=t, .data=(uintptr_t)&ts, .pos=td->pos }; return op_check(env, &opi); @@ -126,5 +128,5 @@ ANN Type scan_type(const Env env, const Type t, Type_Decl* td) { envset_pop(&es, owner); return ret; } - return _scan_type(env, t, td); + return !t->array_depth ? _scan_type(env, t, td) : t; } diff --git a/src/parse/type_decl.c b/src/parse/type_decl.c index b574f368..935875e9 100644 --- a/src/parse/type_decl.c +++ b/src/parse/type_decl.c @@ -35,9 +35,6 @@ ANN static Type resolve(const Env env, Type_Decl* td) { DECL_OO(const Type, type, = scan_type(env, base, td)) const Type t = !td->ref ? type : ref(env, td); const Type ret = !td->option ? t : option(env, td); -// if(!td->array || ret == env->gwion->type[et_auto]) -// return ret; -// return array_type(env, ret, td->array->depth); return !td->array ? ret: array_type(env, ret, td->array->depth); } diff --git a/tests/UsrUgen/UsrUGen_no_float.gw b/tests/UsrUgen/UsrUGen_no_float.gw index 0c102469..69d71a26 100644 --- a/tests/UsrUgen/UsrUGen_no_float.gw +++ b/tests/UsrUgen/UsrUGen_no_float.gw @@ -1,5 +1,6 @@ #! [contains] must be of type float fun float t(int i) { + return 0; } class C extends UsrUGen { diff --git a/tests/error/late_return.gw b/tests/error/late_return.gw new file mode 100644 index 00000000..8a615955 --- /dev/null +++ b/tests/error/late_return.gw @@ -0,0 +1,6 @@ +#! [contains] NullPtrException +fun Object test() { + late Object o; + return o; +} +test(); diff --git a/tests/error/mandatory_return.gw b/tests/error/mandatory_return.gw new file mode 100644 index 00000000..0d7c83bb --- /dev/null +++ b/tests/error/mandatory_return.gw @@ -0,0 +1,5 @@ +fun int test() { + { + return 2; + } +} diff --git a/tests/error/template_dyn2.gw b/tests/error/template_dyn2.gw index d13f2fc8..c8bb5a3d 100644 --- a/tests/error/template_dyn2.gw +++ b/tests/error/template_dyn2.gw @@ -5,15 +5,15 @@ fun void test(C cc, int i) { <<< 1 >>>; <<< cc.test(i, i) >>>; } class C { - fun int test:[A](A a) { <<< " A ", a >>>; } - fun int test:[A](A a, int i) { <<< " ", a >>>; } - fun int test:[A](A a, int i, int j) { <<< a >>>; } + fun void test:[A](A a) { <<< " A ", a >>>; } + fun void test:[A](A a, int i) { <<< " ", a >>>; } + fun void test:[A](A a, int i, int j) { <<< a >>>; } } class D extends C { - fun int test:[A](A a, int i) { <<< this, " extent ", a, __func__ >>>; } + fun void test:[A](A a, int i) { <<< this, " extent ", a, __func__ >>>; } } class E extends D { - fun int test:[A](A a, int i) { <<< this, " Extent ", a, _func__ >>>; } + fun void test:[A](A a, int i) { <<< this, " Extent ", a, _func__ >>>; } } diff --git a/tests/tree/tmpl_array.gw b/tests/tree/tmpl_array.gw new file mode 100644 index 00000000..fbc63921 --- /dev/null +++ b/tests/tree/tmpl_array.gw @@ -0,0 +1,14 @@ +#! [contains] 1 +fun void test:[A](A t) { + <<< t[0] >>>; +} + +test:[ int[] ]([1]); +test([1]); + +fun void test2:[A](A t[]) { + <<< t[0] >>>; +} + +test2:[ int ]([1]); +test2([1]); -- 2.43.0