From f46a9ba6d3d8fabc5841ccbc4c26d00d938a018c Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Mon, 15 Mar 2021 17:24:49 +0100 Subject: [PATCH] :art: Few improvements --- src/clean.c | 2 +- src/gwion.c | 2 +- src/lib/object_op.c | 7 ++++--- src/lib/opfunc.c | 20 ++++++++++++++++++++ src/lib/ref.c | 2 ++ src/lib/tmpl_info.c | 7 +++++-- src/parse/check.c | 34 ++++++++++++++++++++++++++++------ 7 files changed, 61 insertions(+), 13 deletions(-) diff --git a/src/clean.c b/src/clean.c index 72ddac6f..51b7ef63 100644 --- a/src/clean.c +++ b/src/clean.c @@ -23,7 +23,7 @@ ANN static void clean_type_list(Clean *a, Type_List b) { } ANN static void clean_tmpl(Clean *a, Tmpl *b) { - if(b->list) + if(b->base < 0 && b->list) clean_id_list(a, b->list); if(b->call) clean_type_list(a, b->call); diff --git a/src/gwion.c b/src/gwion.c index 2ae6f687..4111b1fa 100644 --- a/src/gwion.c +++ b/src/gwion.c @@ -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/lib/object_op.c b/src/lib/object_op.c index 3cbc35b4..31a4382c 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -269,16 +269,17 @@ ANN static Type _scan_class(const Env env, struct tmpl_info *info) { ANN Type tmpl_exists(const Env env, struct tmpl_info *const info); ANN Type scan_class(const Env env, const Type t, const Type_Decl *td) { - struct tmpl_info info = { .base=t, .td=td, .list=t->info->cdef->base.tmpl->list }; + struct tmpl_info info = { .base=t, .td=td, .list=t->info->cdef->base.tmpl->list }; const Type exists = tmpl_exists(env, &info); if(exists) return exists != env->gwion->type[et_error] ? exists : NULL; struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan0_cdef, .scope=env->scope->depth, .flag=tflag_scan0 }; - CHECK_BO(envset_push(&es, t->info->owner_class, t->info->ctx ? t->info->ctx->nspc : env->curr)) + const Type _t = known_type(env, td->types->td); + CHECK_BO(envset_push(&es, _t->info->owner_class, _t->info->owner)) const Type ret = _scan_class(env, &info); if(es.run) - envset_pop(&es, t->info->owner_class); + envset_pop(&es, _t->info->owner_class); return ret; } diff --git a/src/lib/opfunc.c b/src/lib/opfunc.c index 1e08e911..221ffbac 100644 --- a/src/lib/opfunc.c +++ b/src/lib/opfunc.c @@ -19,6 +19,26 @@ OP_CHECK(opck_basic_cast) { OP_CHECK(opck_usr_implicit) { struct Implicit* imp = (struct Implicit*)data; +/* +// in use for refinement types + const Value v = nspc_lookup_value1(imp->t->info->owner, insert_symbol("@implicit")); + if(v) { + Func f = v->d.func_ref; + while(f) { + if(f->def->base->ret_type == imp->t) + break; + f = f->next; + } + if(f) { + // TODO: add call exp + struct Exp_ call = { .exp_type=ae_exp_call, .d={.exp_call={.args=imp->e}}, .pos=imp->e->pos, + .type=f->value_ref->type }; + struct Op_Import opi = { .op=insert_symbol("@func_check"), + .rhs=f->value_ref->type, .pos=imp->e->pos, .data=(uintptr_t)&call }; + CHECK_NN(op_check(env, &opi)) + } + } +*/ return imp->t; } diff --git a/src/lib/ref.c b/src/lib/ref.c index 237266de..71c15c7c 100644 --- a/src/lib/ref.c +++ b/src/lib/ref.c @@ -63,8 +63,10 @@ OP_CHECK(opck_foreach_scan) { const Type t = new_type(env->gwion->mp, s_name(info.name), base); SET_FLAG(t, abstract | ae_flag_final); set_tflag(t, tflag_infer); + const m_uint scope = env_push(env, base->info->owner_class, base->info->owner); base2ref(env, base, t); ref2base(env, t, base); + env_pop(env, scope); return t; } diff --git a/src/lib/tmpl_info.c b/src/lib/tmpl_info.c index 43d0f4cc..79f91cfd 100644 --- a/src/lib/tmpl_info.c +++ b/src/lib/tmpl_info.c @@ -80,6 +80,9 @@ ANN static Type _tmpl_exists(const Env env, const Symbol name) { ANN Type tmpl_exists(const Env env, struct tmpl_info *const info) { if(template_match(info->list, info->td->types) < 0) // invalid template ERR_N(info->td->pos, _("invalid template types number")) - DECL_ON(const Symbol, name, = info->name = template_id(env, info)) - return _tmpl_exists(env, name); + if(!info->name) { + DECL_ON(const Symbol, name, = info->name = template_id(env, info)) + return _tmpl_exists(env, name); + } + return _tmpl_exists(env, info->name); } diff --git a/src/parse/check.c b/src/parse/check.c index 31ec343b..3b972e7e 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -855,6 +855,19 @@ ANN static Type check_exp_dot(const Env env, Exp_Dot* member) { return check_dot(env, member); } +/* +// enable static checking +ANN static OP_CHECK(opck_predicate) { + const Exp_Call *call = (Exp_Call*)data; + const Exp predicate = call->args; +const Func f = exp_self(call)->type->info->func; +//f->def->d.code->d.stmt_code.stmt_list->stmt->d.stmt_exp.val; + if(predicate->exp_type != ae_exp_primary || + predicate->d.prim.prim_type != ae_prim_num || + !predicate->d.prim.d.num) exit(12); +} +*/ + ANN m_bool check_type_def(const Env env, const Type_Def tdef) { if(tdef->when) { const Var_Decl decl = new_var_decl(env->gwion->mp, insert_symbol("self"), NULL, tdef->when->pos); @@ -863,10 +876,11 @@ ANN m_bool check_type_def(const Env env, const Type_Def tdef) { insert_symbol("@implicit"), args, ae_flag_none, tdef->pos); set_fbflag(fb, fbflag_op); const Exp helper = new_prim_id(env->gwion->mp, insert_symbol("@predicate"), tdef->when->pos); - tdef->when->next = helper; - const Stmt stmt = new_stmt_exp(env->gwion->mp, ae_stmt_exp, cpy_exp(env->gwion->mp, tdef->when), tdef->when->pos);// copy exp + const Exp when = cpy_exp(env->gwion->mp, tdef->when); + when->next = helper; + const Stmt stmt = new_stmt_exp(env->gwion->mp, ae_stmt_exp, when, when->pos); const Stmt_List body = new_stmt_list(env->gwion->mp, stmt, NULL);//ret_list); - const Stmt code = new_stmt_code(env->gwion->mp, body, tdef->when->pos); + const Stmt code = new_stmt_code(env->gwion->mp, body, when->pos); const Func_Def fdef = new_func_def(env->gwion->mp, fb, code); CHECK_BB(traverse_func_def(env, fdef)) const Exp predicate = stmt->d.stmt_exp.val; @@ -874,7 +888,7 @@ ANN m_bool check_type_def(const Env env, const Type_Def tdef) { char explain[strlen(predicate->type->name) + 7]; sprintf(explain, "found `{/+}%s{0}`", predicate->type->name); gwerr_basic("Invalid `{/+}when{0}` predicate expression type", explain, "use `{/+}bool{0}`", - env->name, tdef->when->pos, 0); + env->name, when->pos, 0); char from[strlen(tdef->type->name) + 39]; sprintf(from, "in `{/+}%s{0}` definition", tdef->type->name); gwerr_secondary(from, env->name, tdef->pos); @@ -882,10 +896,18 @@ ANN m_bool check_type_def(const Env env, const Type_Def tdef) { env->context->error++; return GW_ERROR; } +/* + // enable static checking + const Func f = fdef->base->func; + const struct Op_Func opfunc = { .ck=opck_predicate }; + const struct Op_Import opi = { .rhs=f->value_ref->type, + .func=&opfunc, .data=(uintptr_t)f, .pos=tdef->pos, .op=insert_symbol("@func_check") }; + CHECK_BB(add_op(env->gwion, &opi)) +*/ // we handle the return after, so that we don't get *cant' use implicit casting while defining it* - const Exp ret_id = new_prim_id(env->gwion->mp, insert_symbol("self"), tdef->when->pos); + const Exp ret_id = new_prim_id(env->gwion->mp, insert_symbol("self"), when->pos); ret_id->d.prim.value = new_value(env->gwion->mp, tdef->type, "self"); - const Stmt ret = new_stmt_exp(env->gwion->mp, ae_stmt_return, ret_id, tdef->when->pos); + const Stmt ret = new_stmt_exp(env->gwion->mp, ae_stmt_return, ret_id, when->pos); const Stmt_List ret_list = new_stmt_list(env->gwion->mp, ret, NULL); ret_id->type = tdef->type; body->next = ret_list; -- 2.43.0