From 9630fb04effc96c26406050684125d098ebe4dac Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Wed, 8 Apr 2020 17:56:12 +0200 Subject: [PATCH] :art: Few fixes --- ast | 2 +- include/import.h | 1 - include/parse.h | 1 + src/emit/emit.c | 5 +++-- src/env/type.c | 16 +++++----------- src/lib/object_op.c | 5 ++++- src/lib/opfunc.c | 5 ----- src/lib/prim.c | 12 ++++++++++-- src/parse/check.c | 15 +++++++++++---- src/parse/scan0.c | 17 +++++++++++++---- src/parse/scan1.c | 33 ++++++++++++++++++++++++--------- src/parse/scan2.c | 7 +++++-- src/parse/stage.c | 6 ++++++ tests/tree/class_cast.gw | 4 ++-- tests/tree/class_template.gw | 3 --- 15 files changed, 85 insertions(+), 47 deletions(-) diff --git a/ast b/ast index db6a920a..50ab3bf5 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit db6a920ab506312eabe2835f41ca8b02ecec153f +Subproject commit 50ab3bf5f4dbbbc493e382d0a74cd8a9cd6f2b7b diff --git a/include/import.h b/include/import.h index a5502758..6c9056a7 100644 --- a/include/import.h +++ b/include/import.h @@ -49,7 +49,6 @@ OP_CHECK(opck_post); OP_CHECK(opck_rassign); OP_CHECK(opck_rhs_emit_var); OP_CHECK(opck_basic_cast); -OP_CHECK(opck_simple_cast); OP_CHECK(opck_usr_implicit); OP_CHECK(opck_new); OP_EMIT(opem_new); diff --git a/include/parse.h b/include/parse.h index 43ffc4cc..af616b36 100644 --- a/include/parse.h +++ b/include/parse.h @@ -48,6 +48,7 @@ ANN static m_bool prefix##_stmt_##name(const Env env, const type stmt) { \ ANN m_uint union_push(const Env, const Union_Def); ANN void union_pop(const Env, const Union_Def, const m_uint); +ANN void union_flag(const Union_Def, const ae_flag); ANN m_bool check_stmt(const Env env, const Stmt stmt); typedef m_bool (*_exp_func)(const void*, const void*); diff --git a/src/emit/emit.c b/src/emit/emit.c index 153a2ab8..1faf6cbb 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1946,9 +1946,10 @@ ANN static m_bool emit_struct_body2(const Emitter emit, Section *const section) emit_section(emit, section) : GW_OK; } -ANN static m_bool emit_class_def(const Emitter emit, const Class_Def cdef) { - if(tmpl_base(cdef->base.tmpl)) +ANN static m_bool emit_class_def(const Emitter emit, const Class_Def c) { + if(tmpl_base(c->base.tmpl)) return GW_OK; + const Class_Def cdef = c->base.type->e->def; if(GET_FLAG(cdef->base.type, emit)) return GW_OK; const Type type = cdef->base.type; diff --git a/src/env/type.c b/src/env/type.c index 0c67f6d2..df582888 100644 --- a/src/env/type.c +++ b/src/env/type.c @@ -7,28 +7,22 @@ #include "gwion.h" ANN static inline m_bool freeable(const Type a) { - return !GET_FLAG(a, nonnull) && - (GET_FLAG(a, template) || GET_FLAG(a, global)); + return !GET_FLAG(a, nonnull) && GET_FLAG(a, template); } ANN static void free_type(Type a, Gwion gwion) { if(freeable(a)) { if(GET_FLAG(a, union)) { if(a->e->def->union_def) { - if(!GET_FLAG(a, pure)) { // <=> decl_list - UNSET_FLAG(a->e->def->union_def, global); + if(!GET_FLAG(a, pure)) free_union_def(gwion->mp, a->e->def->union_def); - } else + else free_decl_list(gwion->mp, a->e->def->list); } a->e->def->union_def = NULL; - } else if(a->e->def) { - if(!(a->e->ctx && a->e->ctx->error)) { - UNSET_FLAG(a->e->def, template); - UNSET_FLAG(a->e->def, global); - free_class_def(gwion->mp, a->e->def); - } } + if(a->e->def) + free_class_def(gwion->mp, a->e->def); } if(a->nspc) REM_REF(a->nspc, gwion); diff --git a/src/lib/object_op.c b/src/lib/object_op.c index 8026bf66..d33a54d1 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -141,7 +141,7 @@ OP_CHECK(opck_object_scan) { struct TemplateScan *ts = (struct TemplateScan*)data; if(ts->td->types) return scan_class(env, ts->t, ts->td); - if(GET_FLAG(ts->t, unary)) + if(!GET_FLAG(ts->t, template) || GET_FLAG(ts->t, unary)) return ts->t; ERR_O(td_pos(ts->td), _("you must provide template types for type '%s'"), ts->t->name) } @@ -383,10 +383,13 @@ ANN static m_bool class2udef(const Env env, const Class_Def a, const Type t) { a->union_def = new_union_def(env->gwion->mp, a->list, loc_cpy(env->gwion->mp, t->e->def->pos)); a->union_def->type_xid = a->base.xid; + if(GET_FLAG(t, global)) + SET_FLAG(a->union_def, global); CHECK_BB(scan0_union_def(env, a->union_def)) SET_FLAG(a, scan0); a->base.type = a->union_def->type; a->base.type->e->def = a; + a->union_def->tmpl = cpy_tmpl(env->gwion->mp, a->base.tmpl); return GW_OK; } diff --git a/src/lib/opfunc.c b/src/lib/opfunc.c index 979afb03..a7884390 100644 --- a/src/lib/opfunc.c +++ b/src/lib/opfunc.c @@ -16,11 +16,6 @@ OP_CHECK(opck_basic_cast) { exp_self(cast)->info->type : env->gwion->type[et_null]; } -OP_CHECK(opck_simple_cast) { - const Exp_Cast* cast = (Exp_Cast*)data; - return cast->exp->info->cast_to = exp_self(cast)->info->type; -} - OP_CHECK(opck_usr_implicit) { struct Implicit* imp = (struct Implicit*)data; imp->e->info->cast_to = imp->t; diff --git a/src/lib/prim.c b/src/lib/prim.c index b6081a86..e8deb93c 100644 --- a/src/lib/prim.c +++ b/src/lib/prim.c @@ -133,10 +133,18 @@ static GWION_IMPORT(int) { return GW_OK; } +static OP_CHECK(opck_cast_f2i) { + return env->gwion->type[et_int]; +} + static OP_CHECK(opck_implicit_f2i) { return env->gwion->type[et_null]; } +static OP_CHECK(opck_cast_i2f) { + return env->gwion->type[et_float]; +} + static OP_CHECK(opck_implicit_i2f) { struct Implicit* imp = (struct Implicit*)data; return imp->e->info->cast_to = env->gwion->type[et_float]; @@ -166,7 +174,7 @@ static GWION_IMPORT(intfloat) { CHECK_IF("-=>", rassign, r_minus) CHECK_IF("*=>", rassign, r_mul) CHECK_IF("/=>", rassign, r_div) - _CHECK_OP("$", simple_cast, CastI2F) + _CHECK_OP("$", cast_i2f, CastI2F) _CHECK_OP("@implicit", implicit_i2f, CastI2F) return GW_OK; } @@ -191,7 +199,7 @@ static GWION_IMPORT(floatint) { CHECK_FI("-=>", rassign, r_minus) CHECK_FI("*=>", rassign, r_mul) CHECK_FI("/=>", rassign, r_div) - _CHECK_OP("$", simple_cast, CastF2I) + _CHECK_OP("$", cast_f2i, CastF2I) _CHECK_OP("@implicit", implicit_f2i, CastF2I) return GW_OK; } diff --git a/src/parse/check.c b/src/parse/check.c index de18b019..bddff9fe 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -625,6 +625,7 @@ ANN static m_uint get_type_number(ID_List list) { ANN static Func get_template_func(const Env env, const Exp_Call* func, const Value v) { const Func f = find_template_match(env, v, func); if(f) { +// copy that tmpl->call? Tmpl* tmpl = new_tmpl_call(env->gwion->mp, func->tmpl->call); tmpl->list = v->d.func_ref ? v->d.func_ref->def->base->tmpl->list : func->func->info->type->e->d.func->def->base->tmpl->list; ((Exp_Call*)func)->tmpl = tmpl; @@ -771,7 +772,10 @@ ANN static Type check_exp_cast(const Env env, const Exp_Cast* cast) { CHECK_OO((exp_self(cast)->info->type = cast->td->xid ? known_type(env, cast->td) : check_td(env, cast->td))) struct Op_Import opi = { .op=insert_symbol("$"), .lhs=t, .rhs=exp_self(cast)->info->type, .data=(uintptr_t)cast, .pos=exp_self(cast)->pos, .op_type=op_cast }; - return op_check(env, &opi); +// return op_check(env, &opi); + const Type ret = op_check(env, &opi); +printf("[%s] %p\n", __func__, t); + return ret; } ANN static Type check_exp_post(const Env env, const Exp_Postfix* post) { @@ -1090,6 +1094,8 @@ ANN m_bool check_union_def(const Env env, const Union_Def udef) { if(!udef->xid && !udef->type_xid && env->class_def && !GET_FLAG(udef, static)) env->class_def->nspc->info->offset = udef->o + udef->s; union_pop(env, udef, scope); + union_flag(udef, ae_flag_check); + union_flag(udef, ae_flag_checked); return ret; } @@ -1337,10 +1343,11 @@ ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) { return ret; } -ANN m_bool check_class_def(const Env env, const Class_Def cdef) { - if(tmpl_base(cdef->base.tmpl)) +ANN m_bool check_class_def(const Env env, const Class_Def c) { + if(tmpl_base(c->base.tmpl)) return GW_OK; -if(GET_FLAG(cdef->base.type, checked))return GW_OK; + const Class_Def cdef = c->base.type->e->def; + if(GET_FLAG(cdef->base.type, checked))return GW_OK; const Type type = cdef->base.type; SET_FLAG(type, check); if(cdef->base.ext) diff --git a/src/parse/scan0.c b/src/parse/scan0.c index d35c3760..ce12253b 100644 --- a/src/parse/scan0.c +++ b/src/parse/scan0.c @@ -154,7 +154,7 @@ ANN static m_bool typedef_complex(const Env env, const Type_Def tdef, const Type loc_cpy(env->gwion->mp, td_pos(tdef->ext))); CHECK_BB(scan0_class_def(env, cdef)) tdef->type = cdef->base.type; - cdef->base.tmpl = tdef->tmpl; + cdef->base.tmpl = tdef->tmpl;// check cpy return GW_OK; } @@ -238,7 +238,7 @@ ANN static void union_tmpl(const Env env, const Union_Def udef) { const Class_Def cdef = new_class_def(env->gwion->mp, udef->flag, udef->type_xid, NULL, (Ast)udef->l, loc_cpy(env->gwion->mp, udef->pos)); udef->type->e->def = cdef; - cdef->base.tmpl = udef->tmpl; + cdef->base.tmpl = cpy_tmpl(env->gwion->mp, udef->tmpl); cdef->base.type = udef->type; cdef->list = cpy_decl_list(env->gwion->mp, udef->l); SET_FLAG(cdef, union); @@ -246,6 +246,8 @@ ANN static void union_tmpl(const Env env, const Union_Def udef) { SET_FLAG(udef, template); SET_FLAG(udef->type, template); } + if(GET_FLAG(udef, global)) + SET_FLAG(udef->type, global); SET_FLAG(udef->type, union); } @@ -331,7 +333,8 @@ ANN static Type scan0_class_def_init(const Env env, const Class_Def cdef) { inherit_tmpl(env, cdef); set_template(t, cdef); } else if(SAFE_FLAG(env->class_def, template)) { - cdef->base.tmpl = new_tmpl_base(env->gwion->mp, env->class_def->e->def->base.tmpl->list); + cdef->base.tmpl = new_tmpl_base(env->gwion->mp, cpy_id_list(env->gwion->mp, env->class_def->e->def->base.tmpl->list)); +// cdef->base.tmpl = cpy_tmpl(env->gwion->mp, env->class_def->e->def->base.tmpl); set_template(t, cdef); } if(cdef->base.ext && cdef->base.ext->array) @@ -377,7 +380,13 @@ ANN m_bool scan0_class_def(const Env env, const Class_Def cdef) { scan0_class_def_inner(env, cdef) : GW_ERROR; if(GET_FLAG(cdef, global)) env->curr = (Nspc)vector_pop(&env->scope->nspc_stack); - return ret; + CHECK_BB(ret) + if(cdef->base.tmpl && !cdef->base.tmpl->call) { + const Class_Def c = cpy_class_def(env->gwion->mp, cdef); + c->base.type = cdef->base.type; + c->base.type->e->def = c; + } + return GW_OK; } ANN m_bool scan0_ast(const Env env, Ast ast) { diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 4b177e7e..175bc7c4 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -105,6 +105,13 @@ ANN static m_bool scan1_decl(const Env env, const Exp_Decl* decl) { return GW_OK; } +ANN int is_global(const Nspc nspc, Nspc global) { + do if(nspc == global) + return 1; + while((global = global->parent)); + return 0; +} + ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) { CHECK_BB(env_storage(env, decl->td->flag, exp_self(decl)->pos)) ((Exp_Decl*)decl)->type = scan1_exp_decl_type(env, (Exp_Decl*)decl); @@ -113,7 +120,7 @@ ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) { exp_setmeta(exp_self(decl), 1); // SET_FLAG(decl->td, const); const m_bool global = GET_FLAG(decl->td, global); - if(global && decl->type->e->owner != env->global_nspc) + if(global && !is_global(decl->type->e->owner, env->global_nspc)) ERR_B(exp_self(decl)->pos, _("type '%s' is not global"), decl->type->name) if(env->context) env->context->global = 1; @@ -326,15 +333,21 @@ ANN m_bool scan1_union_def_action(const Env env, const Union_Def udef, SET_FLAG(decl.td, member); else if(GET_FLAG(udef, static)) SET_FLAG(decl.td, static); - CHECK_BB(scan1_exp(env, l->self)) -Var_Decl_List list = decl.list; -do ADD_REF(list->self->value) -while((list = list->next)); + if(udef->tmpl && udef->tmpl->call) + CHECK_BB(template_push_types(env, udef->tmpl)) + const m_bool ret = scan1_exp(env, l->self); + if(udef->tmpl && udef->tmpl->call) + nspc_pop_type(env->gwion->mp, env->curr); + CHECK_BB(ret) + Var_Decl_List list = decl.list; + do ADD_REF(list->self->value) + while((list = list->next)); if(global) SET_FLAG(decl.td, global); + union_flag(udef, ae_flag_scan1); return GW_OK; } @@ -342,7 +355,7 @@ ANN m_bool scan1_union_def_inner(const Env env, const Union_Def udef) { Decl_List l = udef->l; do CHECK_BB(scan1_union_def_action(env, udef, l)) while((l = l->next)); - return GW_OK; + return GW_OK; } ANN m_bool scan1_union_def(const Env env, const Union_Def udef) { @@ -355,7 +368,8 @@ ANN m_bool scan1_union_def(const Env env, const Union_Def udef) { } const m_bool ret = scan1_union_def_inner(env, udef); union_pop(env, udef, scope); - SET_FLAG(udef, scan1); + const Type type = udef->xid || udef->type_xid ? udef->value->type : udef->type; + SET_FLAG(type, scan1); return ret; } @@ -499,9 +513,10 @@ ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) { return ret; } -ANN m_bool scan1_class_def(const Env env, const Class_Def cdef) { - if(tmpl_base(cdef->base.tmpl)) +ANN m_bool scan1_class_def(const Env env, const Class_Def c) { + if(tmpl_base(c->base.tmpl)) return GW_OK; + const Class_Def cdef = c->base.type->e->def; if(GET_FLAG(cdef->base.type, scan1))return GW_OK; SET_FLAG(cdef->base.type, scan1); if(cdef->base.ext) diff --git a/src/parse/scan2.c b/src/parse/scan2.c index 7ac3000f..d35b517d 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -272,6 +272,8 @@ ANN m_bool scan2_union_def(const Env env, const Union_Def udef) { const m_uint scope = union_push(env, udef); const m_bool ret = scan2_union_decl(env, udef->l); union_pop(env, udef, scope); + SET_FLAG(udef, scan2); + union_flag(udef, ae_flag_scan2); return ret; } @@ -552,9 +554,10 @@ ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) { return ret; } -ANN m_bool scan2_class_def(const Env env, const Class_Def cdef) { - if(tmpl_base(cdef->base.tmpl)) +ANN m_bool scan2_class_def(const Env env, const Class_Def c) { + if(tmpl_base(c->base.tmpl)) return GW_OK; + const Class_Def cdef = c->base.type->e->def; if(GET_FLAG(cdef->base.type, scan2))return GW_OK; SET_FLAG(cdef->base.type, scan2); if(cdef->base.ext) diff --git a/src/parse/stage.c b/src/parse/stage.c index 12646234..784e298a 100644 --- a/src/parse/stage.c +++ b/src/parse/stage.c @@ -13,3 +13,9 @@ ANN void union_pop(const Env env, const Union_Def udef, const m_uint scope) { if(udef->xid || udef->type_xid || GET_FLAG(udef, global)) env_pop(env, scope); } + +ANN void union_flag(const Union_Def udef, const ae_flag flag) { + const Type type = udef->xid || !udef->type_xid ? + udef->value->type : udef->type; + type->flag |= flag; +} diff --git a/tests/tree/class_cast.gw b/tests/tree/class_cast.gw index b2cc576e..5620fb81 100644 --- a/tests/tree/class_cast.gw +++ b/tests/tree/class_cast.gw @@ -1,4 +1,4 @@ class C { - 1 $ float; + <<< 1 $ float >>>; } - +C c; diff --git a/tests/tree/class_template.gw b/tests/tree/class_template.gw index 2c687b99..6b10dd70 100644 --- a/tests/tree/class_template.gw +++ b/tests/tree/class_template.gw @@ -16,10 +16,7 @@ class<~A,B~> C { #!C c; <<< c.a >>>; <<< d.a >>>; -<<< e.a >>>; <<< c.test() >>>; <<< d.test() >>>; -<<< e.test() >>>; -<<< f.test() >>>; <<< g.test() >>>; c.test2(2); -- 2.43.0