From 9d8818df83ce6674afff09a42af1da5c104e9194 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Thu, 3 Oct 2019 02:14:36 +0200 Subject: [PATCH] :art: Improve push scoping [internal] --- src/emit/emit.c | 51 +++++++++++++++++----------- src/parse/check.c | 86 ++++++++++++++++++++++++++++------------------- src/parse/scan1.c | 32 ++++++++++-------- src/parse/scan2.c | 28 +++++++++------ 4 files changed, 119 insertions(+), 78 deletions(-) diff --git a/src/emit/emit.c b/src/emit/emit.c index afcde902..8a07b594 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -690,18 +690,13 @@ ANN static inline m_bool emit_exp_decl_template(const Emitter emit, const Exp_De 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) { - Var_Decl_List list = decl->list; - const uint ref = GET_FLAG(decl->td, ref) || type_ref(decl->type); - const uint var = exp_self(decl)->emit_var; - if(GET_FLAG(decl->type, template)) - CHECK_BB(emit_exp_decl_template(emit, decl)) +ANN static m_bool emit_decl(const Emitter emit, const Exp_Decl* decl) { const m_bool global = GET_FLAG(decl->td, global); - const m_uint scope = !global ? emit->env->scope->depth : emit_push_global(emit); + const uint var = exp_self(decl)->emit_var; + const uint ref = GET_FLAG(decl->td, ref) || type_ref(decl->type); + Var_Decl_List list = decl->list; do { const uint r = (list->self->array && list->self->array->exp && ref) ? 0 : (uint)(GET_FLAG(list->self->value, ref) + ref); -// if(!GET_FLAG(list->self->value, used)) -// continue; if(GET_FLAG(decl->td, static)) CHECK_BB(emit_exp_decl_static(emit, list->self, r, var)) else if(!global) @@ -711,9 +706,18 @@ ANN static m_bool emit_exp_decl(const Emitter emit, const Exp_Decl* decl) { if(GET_FLAG(list->self->value->type, nonnull)) emit_add_instr(emit, GWOP_EXCEPT); } while((list = list->next)); + return GW_OK; +} + +ANN static m_bool emit_exp_decl(const Emitter emit, const Exp_Decl* decl) { + if(GET_FLAG(decl->type, template)) + CHECK_BB(emit_exp_decl_template(emit, decl)) + const m_bool global = GET_FLAG(decl->td, global); + const m_uint scope = !global ? emit->env->scope->depth : emit_push_global(emit); + const m_bool ret = emit_decl(emit, decl); if(global) emit_pop(emit, scope); - return GW_OK; + return ret; } ANN static m_uint vararg_size(const Exp_Call* exp_call, const Vector kinds) { @@ -1128,16 +1132,22 @@ ANN static m_bool emit_exp_if(const Emitter emit, const Exp_If* exp_if) { return ret; } +ANN static m_bool emit_lambda(const Emitter emit, const Exp_Lambda * lambda) { + CHECK_BB(emit_func_def(emit, lambda->def)) + if(GET_FLAG(lambda->def, member)) + emit_add_instr(emit, RegPushMem); + regpushi(emit, (m_uint)lambda->def->base->func->code); + return GW_OK; +} + ANN static m_bool emit_exp_lambda(const Emitter emit, const Exp_Lambda * lambda) { if(lambda->def) { const m_uint scope = !lambda->owner ? emit->env->scope->depth : emit_push_type(emit, lambda->owner); - CHECK_BB(emit_func_def(emit, lambda->def)) - if(GET_FLAG(lambda->def, member)) - emit_add_instr(emit, RegPushMem); - regpushi(emit, (m_uint)lambda->def->base->func->code); + const m_bool ret = emit_lambda(emit, lambda); if(lambda->owner) emit_pop(emit, scope); + return ret; } else emit_add_instr(emit, RegPushImm); return GW_OK; @@ -1167,8 +1177,7 @@ ANN2(1) static m_bool emit_exp(const Emitter emit, Exp exp, const m_bool ref) { return GW_OK; } -ANN static m_bool emit_stmt_if(const Emitter emit, const Stmt_If stmt) { - emit_push_scope(emit); +ANN static m_bool emit_if(const Emitter emit, const Stmt_If stmt) { DECL_OB(const Instr, op, = emit_flow(emit, stmt->cond)) CHECK_BB(scoped_stmt(emit, stmt->if_body, 1)) const Instr op2 = emit_add_instr(emit, Goto); @@ -1176,10 +1185,16 @@ ANN static m_bool emit_stmt_if(const Emitter emit, const Stmt_If stmt) { if(stmt->else_body) CHECK_BB(scoped_stmt(emit, stmt->else_body, 1)) op2->m_val = emit_code_size(emit); - emit_pop_scope(emit); return GW_OK; } +ANN static m_bool emit_stmt_if(const Emitter emit, const Stmt_If stmt) { + emit_push_scope(emit); + const m_bool ret = emit_if(emit, stmt); + emit_pop_scope(emit); + return ret; +} + ANN static m_bool emit_stmt_code(const Emitter emit, const Stmt_Code stmt) { ++emit->env->scope->depth; const m_bool ret = stmt->stmt_list ? emit_stmt_list(emit, stmt->stmt_list) : 1; @@ -1425,8 +1440,6 @@ ANN static m_bool emit_union_def(const Emitter emit, const Union_Def udef) { emit_union_offset(udef->l, udef->o); if(udef->xid || udef->type_xid || global) emit_pop(emit, scope); -puts(emit->env->name); -// SET_FLAG(udef->xid ? udef->value->type : udef->type, emit); return GW_OK; } diff --git a/src/parse/check.c b/src/parse/check.c index 214816aa..975a4e7c 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -126,21 +126,57 @@ ANN static Type no_xid(const Env env, const Exp_Decl *decl) { return decl->type; } -ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) { +ANN static m_bool check_var(const Env env, const Var_Decl var) { + if(env->class_def && !env->scope->depth && env->class_def->e->parent) + CHECK_BB(check_exp_decl_parent(env, var)) + if(var->array && var->array->exp) + return check_subscripts(env, var->array); + return GW_OK; +} + +ANN static m_bool check_var_td(const Env env, const Var_Decl var, Type_Decl *const td) { + const Value v = var->value; + if(env->class_def) { + if(GET_FLAG(td, member)) { + decl_member(env, v); + if(isa(env->class_def, env->gwion->type[et_object]) > 0) + tuple_info(env, td, var); + } else if(GET_FLAG(td, static)) + decl_static(env, v); + } else if(GET_FLAG(td, global) || (env->func && GET_FLAG(env->func->def, global))) + SET_FLAG(v, abstract); + return GW_OK; +} + +ANN static m_bool check_decl(const Env env, const Exp_Decl *decl) { Var_Decl_List list = decl->list; + do { + const Var_Decl var = list->self; + CHECK_BB(check_var(env, var)) + CHECK_BB(check_var_td(env, var, decl->td)) + if(is_fptr(env->gwion, decl->type)) + CHECK_BB(check_fptr_decl(env, var)) + SET_FLAG(var->value, checked | ae_flag_used); + nspc_add_value(env->curr, var->xid, var->value); + } while((list = list->next)); + return GW_OK; +} + +ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) { if(!decl->td->xid) return no_xid(env, decl); if(decl->td->xid->xid == insert_symbol("auto")) { // should be better clear_decl(env, decl); CHECK_BO(scan1_exp(env, exp_self(decl))) CHECK_BO(scan2_exp(env, exp_self(decl))) + const Type t_auto = env->gwion->type[et_auto]; if(is_class(env->gwion, decl->type)) { - do { - list->self->value->type = env->gwion->type[et_auto]; - } while((list = list->next)); - ((Exp_Decl*)decl)->type = env->gwion->type[et_auto]; + Var_Decl_List list = decl->list; + do list->self->value->type = t_auto; + while((list = list->next)); + ((Exp_Decl*)decl)->type = t_auto; } - if(decl->type == env->gwion->type[et_auto]) + if(decl->type == t_auto) ERR_O(td_pos(decl->td), _("can't infer type.")); } if(!decl->type) @@ -152,31 +188,10 @@ ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) { } const m_bool global = GET_FLAG(decl->td, global); const m_uint scope = !global ? env->scope->depth : env_push_global(env); - do { - const Var_Decl var = list->self; - const Value v = var->value; - if(env->class_def && !env->scope->depth && env->class_def->e->parent) - CHECK_BO(check_exp_decl_parent(env, var)) - if(var->array && var->array->exp) - CHECK_BO(check_subscripts(env, var->array)) - if(env->class_def) { - if(GET_FLAG(decl->td, member)) { - decl_member(env, v); - if(isa(env->class_def, env->gwion->type[et_object]) > 0) - tuple_info(env, decl->td, var); - } else if(GET_FLAG(decl->td, static)) - decl_static(env, v); - } - else if(global || (env->func && GET_FLAG(env->func->def, global))) - SET_FLAG(v, abstract); - if(is_fptr(env->gwion, decl->type)) - CHECK_BO(check_fptr_decl(env, var)) - SET_FLAG(v, checked | ae_flag_used); - nspc_add_value(env->curr, var->xid, v); - } while((list = list->next)); + const m_bool ret = check_decl(env, decl); if(global) env_pop(env, scope); - return decl->type; + return ret > 0 ? decl->type : NULL; } @@ -577,9 +592,9 @@ CHECK_BO(check_call(env, exp)) 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) + if(check_call(env, exp) < 0 || + find_func_match(env, env->func, exp->args)) continue; - CHECK_OO(find_func_match(env, env->func, exp->args)) m_func = env->func; break; } @@ -702,8 +717,9 @@ ANN static Type check_exp_call_template(const Env env, Exp_Call *exp) { DECL_OO(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->from->owner_class, value->from->owner); - CHECK_BO(traverse_func_def(env, func->def)) + const m_bool ret = traverse_func_def(env, func->def); env_pop(env, scope); + CHECK_BO(ret) } exp->m_func = func; return func->def->base->ret_type; @@ -1346,16 +1362,16 @@ ANN m_bool check_fdef(const Env env, const Func_Def fdef) { ANN m_bool check_func_def(const Env env, const Func_Def fdef) { const Func func = fdef->base->func; assert(func == fdef->base->func); + if(env->class_def) // tmpl ? + CHECK_BB(check_parent_match(env, fdef)) if(tmpl_base(fdef->base->tmpl)) - return env->class_def ? check_parent_match(env, fdef) : 1; + return GW_OK; if(fdef->base->td && !fdef->base->td->xid) { // tmpl ? fdef->base->ret_type = check_td(env, fdef->base->td); 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)) const Func former = env->func; env->func = func; ++env->scope->depth; diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 976e3d31..0cf1cf86 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -66,18 +66,8 @@ ANN static Type scan1_exp_decl_type(const Env env, Exp_Decl* decl) { return decl->type = t; } -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)) +ANN static m_bool scan1_decl(const Env env, const Exp_Decl* decl) { Var_Decl_List list = decl->list; - ((Exp_Decl*)decl)->type = scan1_exp_decl_type(env, (Exp_Decl*)decl); - CHECK_OB(decl->type) - const m_bool global = GET_FLAG(decl->td, global); - if(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; - const m_uint scope = !global ? env->scope->depth : env_push_global(env); - const Nspc nspc = !global ? env->curr : env->global_nspc; do { const Var_Decl var = list->self; CHECK_BB(isres(env, var->xid, exp_self(decl)->pos)) @@ -89,7 +79,7 @@ ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) { if(var->array) { if(var->array->exp) { if(GET_FLAG(decl->td, ref)) - ERR_B(td_pos(decl->td), _("ref array must not have array expression.\n" + ERR_B(var->array->exp->pos, _("ref array must not have array expression.\n" "e.g: int @my_array[];\nnot: int @my_array[2];")) CHECK_BB(scan1_exp(env, var->array->exp)) } @@ -99,7 +89,7 @@ ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) { if(env->class_def) type_contains(env->class_def, t); const Value v = var->value = former ?: new_value(env->gwion->mp, t, s_name(var->xid)); - nspc_add_value(nspc, var->xid, v); + nspc_add_value(env->curr, var->xid, v); v->flag = decl->td->flag; v->type = t; if(var->array && !var->array->exp) @@ -111,9 +101,23 @@ ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) { valuefrom(env, v->from); } while((list = list->next)); ((Exp_Decl*)decl)->type = decl->list->self->value->type; + return GW_OK; +} + +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); + CHECK_OB(decl->type) + const m_bool global = GET_FLAG(decl->td, global); + if(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; + const m_uint scope = !global ? env->scope->depth : env_push_global(env); + const m_bool ret = scan1_decl(env, decl); if(global) env_pop(env, scope); - return GW_OK; + return ret; } ANN static inline m_bool scan1_exp_binary(const Env env, const Exp_Binary* bin) { diff --git a/src/parse/scan2.c b/src/parse/scan2.c index 9bd15dd6..b870d119 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -22,14 +22,10 @@ ANN static m_bool scan2_stmt(const Env, const Stmt); ANN static m_bool scan2_stmt_list(const Env, Stmt_List); -ANN m_bool scan2_exp_decl(const Env env, const Exp_Decl* decl) { - const m_bool global = GET_FLAG(decl->td, global); - const m_uint scope = !global ? env->scope->depth : env_push_global(env); -{ +ANN static m_bool scan2_decl(const Env env, const Exp_Decl* decl) { const Type t = get_type(decl->type); if(GET_FLAG(t, template) && !GET_FLAG(t, scan2)) CHECK_BB(scan2_cdef(env, t->e->def)) -} Var_Decl_List list = decl->list; do { const Var_Decl var = list->self; @@ -38,9 +34,16 @@ ANN m_bool scan2_exp_decl(const Env env, const Exp_Decl* decl) { CHECK_BB(scan2_exp(env, array)) nspc_add_value(env->curr, var->xid, var->value); } while((list = list->next)); + return GW_OK; +} + +ANN m_bool scan2_exp_decl(const Env env, const Exp_Decl* decl) { + const m_bool global = GET_FLAG(decl->td, global); + const m_uint scope = !global ? env->scope->depth : env_push_global(env); + const m_bool ret = scan2_decl(env, decl); if(global) env_pop(env, scope); - return GW_OK; + return ret; } ANN static Value arg_value(MemPool p, const Arg_List list) { @@ -272,15 +275,20 @@ ANN static m_bool scan2_stmt_jump(const Env env, const Stmt_Jump stmt) { return GW_OK; } +ANN static m_bool scan2_union_decl(const Env env, const Decl_List list) { + Decl_List l = list; + do CHECK_BB(scan2_exp_decl(env, &l->self->d.exp_decl)) + while((l = l->next)); + return GW_OK; +} + ANN m_bool scan2_union_def(const Env env, const Union_Def udef) { if(tmpl_base(udef->tmpl)) return GW_OK; const m_uint scope = union_push(env, udef); - Decl_List l = udef->l; - do CHECK_BB(scan2_exp(env, l->self)) - while((l = l->next)); + const m_bool ret = scan2_union_decl(env, udef->l); union_pop(env, udef, scope); - return GW_OK; + return ret; } static const _exp_func stmt_func[] = { -- 2.43.0