]> Nishi Git Mirror - gwion.git/commitdiff
:art: Improve push scoping [internal]
authorfennecdjay <astor.jeremie@wanadoo.fr>
Thu, 3 Oct 2019 00:14:36 +0000 (02:14 +0200)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Thu, 3 Oct 2019 00:14:36 +0000 (02:14 +0200)
src/emit/emit.c
src/parse/check.c
src/parse/scan1.c
src/parse/scan2.c

index afcde902a25ffb21d66eea42f5a8beec4633a8f6..8a07b59494cd57fd32c451660792656507beb997 100644 (file)
@@ -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;
 }
 
index 214816aac1af92f79f4520530fbc8ed1391b658d..975a4e7cae1e881965c76025e748287ddd2c0ff1 100644 (file)
@@ -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;
index 976e3d31e0b0ba7041b8fa116388cc0554bc859e..0cf1cf862d0883d7bbe7a05e18853f82dcf5dc13 100644 (file)
@@ -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) {
index 9bd15dd607078dd9032d44b6f7a35d8c0f2afd19..b870d1195e823da2666753b3b106f46edc6064a7 100644 (file)
 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[] = {