]> Nishi Git Mirror - gwion.git/commitdiff
:fire: now poison scan1
authorfennecdjay <fennecdjay@gmail.com>
Mon, 12 Feb 2024 13:10:03 +0000 (14:10 +0100)
committerfennecdjay <fennecdjay@gmail.com>
Mon, 12 Feb 2024 13:11:25 +0000 (14:11 +0100)
include/parse.h
include/traverse.h
src/lib/opfunc.c
src/parse/check.c
src/parse/scan1.c
src/parse/scanx.c
src/parse/traverse.c
src/pass.c

index 7a9feb87c46607f0176316bbb2d1748b1ba8ee26..87d1de7bf3f063ab62c3079acfb6e067d2bfdf26 100644 (file)
   --env->scope->depth;                                                         \
   return ret;
 
+#define RET_NSPC_B(exp)                                                        \
+  ++env->scope->depth;                                                         \
+  nspc_push_value(env->gwion->mp, env->curr);                                  \
+  const bool ret = exp;                                                        \
+  nspc_pop_value(env->gwion->mp, env->curr);                                   \
+  --env->scope->depth;                                                         \
+  return ret;
+
 #define SET_ACCESS(a, b)                                                       \
   if (GET_FLAG(a, private))                                                    \
     SET_FLAG(b, private);                                                      \
 #define HANDLE_EXP_FUNC_B(prefix, type, Arg)                                   \
   DECL_EXP_FUNC(prefix, type, Arg)                                             \
   ANN type prefix##_exp(const Arg arg, Exp* exp) {                             \
+    bool ok = true;                                                            \
     do {                                                                       \
       if(!exp->poison) {                                                       \
-        if(!prefix##_exp_func[exp->exp_type](arg, &exp->d))                  \
+        if(!prefix##_exp_func[exp->exp_type](arg, &exp->d)) {                  \
           exp->poison = true;                                                  \
+          ok = false;                                                          \
+        }                                                                      \
       }                                                                        \
     } while ((exp = exp->next));                                               \
-    return GW_OK;                                                              \
+    return ok;                                                                 \
   }
 
 #define describe_stmt_func(prefix, name, type, prolog, exp)                    \
     RET_NSPC(exp)                                                              \
   }
 
+#define describe_stmt_func_b(prefix, name, type, prolog, exp)                  \
+  ANN static bool prefix##_stmt_##name(const Env env, const type stmt) {       \
+    RET_NSPC_B(exp)                                                            \
+  }
+
 ANN m_bool check_stmt(const Env env, Stmt* stmt);
 ANN m_bool check_stmt_list(const Env env, const Stmt_List);
 
@@ -117,7 +133,8 @@ static inline m_bool prefix##_union_def_b(const Env env, const Union_Def udef) {
                       (_exp_func)prefix##_union_def_b);                          \
   }
 
-xxx_cdef_b(scan0)
+xxx_cdef_b(scan0);
+xxx_cdef_b(scan1);
 
 #define xxx_cdef(prefix)                                                       \
   static inline m_bool prefix##_cdef(const Env env, const Type t) {            \
@@ -125,13 +142,14 @@ xxx_cdef_b(scan0)
                       (_exp_func)prefix##_union_def);                          \
   }
 
-xxx_cdef(scan1)
-xxx_cdef(scan2)
-xxx_cdef(check)
-xxx_cdef(traverse)
+xxx_cdef(scan2);
+xxx_cdef(check);
+xxx_cdef(traverse);
 
-        ANN m_bool
-    scanx_fdef(const Env, void *, const Func_Def, const _exp_func);
+ANN m_bool
+scanx_fdef(const Env, void *, const Func_Def, const _exp_func);
+ANN bool
+scanx_fdef_b(const Env, void *, const Func_Def, const _exp_func_b);
 
 ANN m_bool check_subscripts(const Env, const Array_Sub, const m_bool is_decl);
 ANN m_bool check_implicit(const Env env, Exp* e, const Type t);
@@ -174,7 +192,7 @@ ANN static inline bool not_upvalue(const Env env, const Value v) {
       nspc_lookup_value1(env->curr, insert_symbol(v->name));
 }
 
-ANN m_bool abstract_array(const Env env, const Array_Sub array);
+ANN bool abstract_array(const Env env, const Array_Sub array);
 
 ANN static inline bool is_static_call(const Gwion gwion, Exp* e) {
   if (e->exp_type != ae_exp_dot) return true;
index d39ac62cb768f652e7e7f305870e5101d2a048b9..09544baba7f892daa84bd53e367bbefcf73fdb1a 100644 (file)
@@ -10,41 +10,41 @@ ANN m_bool traverse_type_def(const Env env, const Type_Def);
 ANN m_bool traverse_exp(const Env, Exp*);
 
 ANN bool scan0_ast(const Env, Ast*);
-ANN m_bool scan1_ast(const Env, Ast*);
+ANN bool scan1_ast(const Env, Ast*);
 ANN m_bool scan2_ast(const Env, Ast*);
 ANN m_bool check_ast(const Env, Ast*);
 
-ANN m_bool scan1_exp(const Env, Exp*);
+ANN bool scan1_exp(const Env, Exp*);
 ANN m_bool scan2_exp(const Env, Exp*);
 ANN Type   check_exp(const Env, Exp*);
 
 ANN bool scan0_func_def(const Env, const Func_Def);
-ANN m_bool scan1_func_def(const Env, const Func_Def);
+ANN bool scan1_func_def(const Env, const Func_Def);
 ANN m_bool scan2_func_def(const Env, const Func_Def);
 ANN m_bool check_func_def(const Env, const Func_Def);
 
 ANN bool scan0_fptr_def(const Env, const Fptr_Def);
-ANN m_bool scan1_fptr_def(const Env, const Fptr_Def);
+ANN bool scan1_fptr_def(const Env, const Fptr_Def);
 ANN m_bool scan2_fptr_def(const Env, const Fptr_Def);
 ANN m_bool check_fptr_def(const Env, const Fptr_Def);
 
 ANN bool scan0_union_def(const Env, const Union_Def);
-ANN m_bool scan1_union_def(const Env, const Union_Def);
+ANN bool scan1_union_def(const Env, const Union_Def);
 ANN m_bool scan2_union_def(const Env, const Union_Def);
 ANN m_bool check_union_def(const Env, const Union_Def);
 
 ANN bool scan0_enum_def(const Env, const Enum_Def);
-ANN m_bool scan1_enum_def(const Env, const Enum_Def);
+ANN bool scan1_enum_def(const Env, const Enum_Def);
 // ANN m_bool scan2_enum_def(const Env, const Enum_Def);
 ANN m_bool check_enum_def(const Env, const Enum_Def);
 
 ANN bool scan0_type_def(const Env, const Type_Def);
-ANN m_bool scan1_type_def(const Env, const Type_Def);
+ANN bool scan1_type_def(const Env, const Type_Def);
 ANN m_bool scan2_type_def(const Env, const Type_Def);
 ANN m_bool check_type_def(const Env, const Type_Def);
 
 ANN bool scan0_class_def(const Env, const Class_Def);
-ANN m_bool scan1_class_def(const Env, const Class_Def);
+ANN bool scan1_class_def(const Env, const Class_Def);
 ANN m_bool scan2_class_def(const Env, const Class_Def);
 ANN m_bool check_class_def(const Env, const Class_Def);
 
index 955cf06e942af0e6ab38fe8045092a5aaabd319c..527e5d51130ea09469f3a4079a19f2f2410e712e 100644 (file)
@@ -122,7 +122,7 @@ OP_CHECK(opck_new) {
   if(array && !unary->ctor.exp) {
     const Type base = array_base(t);
     if(GET_FLAG(base, abstract))
-      CHECK_BN(abstract_array(env, array));
+      CHECK_ON(abstract_array(env, array));
     if(GET_FLAG(base, abstract))
       CHECK_BN(check_array_instance(env, unary->ctor.td, unary->ctor.exp));
   }
index 3f1392e2a02605a98e48b9c07a90287dc91d54a8..1c709323b41c51bff5daf2009dffa997683bc4c1 100644 (file)
@@ -170,7 +170,7 @@ ANN Type check_exp_decl(const Env env, Exp_Decl *const decl) {
     e->ref = exp_self(decl);
   }
   if (decl->var.td->tag.sym == insert_symbol("auto")) { // should be better
-    CHECK_BO(scan1_exp(env, exp_self(decl)));
+    CHECK_O(scan1_exp(env, exp_self(decl)));
     CHECK_BO(scan2_exp(env, exp_self(decl)));
   }
   if (!decl->type) ERR_O(decl->var.td->tag.loc, _("can't find type"));
index 82b5fd9414c70fccea3b9c49ca10ce12b49191af..45261db087e50aa6c4ea71534b889375b0dc3fa6 100644 (file)
 #include "instr.h"
 #include "import.h"
 
-ANN static m_bool scan1_stmt_list(const Env env, Stmt_List list);
-ANN static m_bool scan1_stmt(const Env env, Stmt* stmt);
+#undef ERR_B
+#define ERR_B(a, b, ...)                                                       \
+  {                                                                            \
+    env_err(env, (a), (b), ##__VA_ARGS__);                                     \
+    return false;                                                              \
+  }
+
+ANN static bool scan1_stmt_list(const Env env, Stmt_List list);
+ANN static bool scan1_stmt(const Env env, Stmt* stmt);
 
-ANN static inline m_bool type_cyclic(const Env env, const Type t,
+ANN static inline bool type_cyclic(const Env env, const Type t,
                                      const Type_Decl *td) {
   Type owner = env->class_def;
   do {
@@ -23,13 +30,13 @@ ANN static inline m_bool type_cyclic(const Env env, const Type t,
         ERR_B(td->tag.loc, _("%s declared inside %s"), t->name, owner->name);
     } while ((parent = parent->info->parent));
   } while ((owner = owner->info->value->from->owner_class));
-  return GW_OK;
+  return true;
 }
 
-ANN static inline m_bool ensure_scan1(const Env env, const Type t) {
+ANN static inline bool ensure_scan1(const Env env, const Type t) {
 //  if (tflag(t, tflag_scan1) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef)))
   if (tflag(t, tflag_scan1) || !(tflag(t, tflag_cdef) || tflag(t, tflag_union)))
-    return GW_OK;
+    return true;
   struct EnvSet es = {.env   = env,
                       .data  = env,
                       .func  = (_exp_func)scan1_cdef,
@@ -38,7 +45,7 @@ ANN static inline m_bool ensure_scan1(const Env env, const Type t) {
   return envset_run(&es, t);
 }
 
-ANN static m_bool check_global(const Env env, const Type t, const loc_t loc) {
+ANN static bool check_global(const Env env, const Type t, const loc_t loc) {
   const ValueFrom *from = t->info->value->from;
   if(from->owner_class && isa(from->owner_class, env->class_def) > 0)
     return true;
@@ -54,23 +61,23 @@ ANN static m_bool check_global(const Env env, const Type t, const loc_t loc) {
 }
 
 ANN static Type scan1_type(const Env env, Type_Decl *td) {
-  DECL_OO(const Type, t, = known_type(env, td));
+  DECL_O(const Type, t, = known_type(env, td));
   const Type base = array_base(t);
   if (!env->func && env->class_def && !GET_FLAG(td, late))
-    CHECK_BO(type_cyclic(env, base, td));
-  CHECK_BO(ensure_scan1(env, t));
+    CHECK_O(type_cyclic(env, base, td));
+  CHECK_O(ensure_scan1(env, t));
   return t;
 }
 
 ANN static Type void_type(const Env env, Type_Decl *td) {
-  DECL_OO(const Type, type, = scan1_type(env, td));
+  DECL_O(const Type, type, = scan1_type(env, td));
   if (type->size) return type;
   ERR_O(td->tag.loc, _("cannot declare variables of size '0' (i.e. 'void')..."))
 }
 
 ANN static Type scan1_exp_decl_type(const Env env, Exp_Decl *decl) {
   if (decl->type) return decl->type;
-  DECL_OO(const Type, t, = void_type(env, decl->var.td));
+  DECL_O(const Type, t, = void_type(env, decl->var.td));
   if(env->class_def && type_global(env, env->class_def) && !check_global(env, t, decl->var.td->tag.loc))
       return NULL;
   if (decl->var.td->tag.sym == insert_symbol("auto") && decl->type) return decl->type;
@@ -81,9 +88,9 @@ ANN static Type scan1_exp_decl_type(const Env env, Exp_Decl *decl) {
   return t;
 }
 
-static inline m_bool scan1_defined(const Env env, const Var_Decl *var) {
+static inline bool scan1_defined(const Env env, const Var_Decl *var) {
   if (var->value) // from an auto declaration
-    return GW_OK;
+    return true;
   const Value v = ((!env->class_def || !GET_FLAG(env->class_def, final) ||
         env->scope->depth)
            ? nspc_lookup_value1
@@ -92,32 +99,32 @@ static inline m_bool scan1_defined(const Env env, const Var_Decl *var) {
     ERR_B(var->tag.loc,
           _("variable %s has already been defined in the same scope..."),
           s_name(var->tag.sym))
-  return GW_OK;
+  return true;
 }
 
-ANN m_bool abstract_array(const Env env, const Array_Sub array) {
+ANN bool abstract_array(const Env env, const Array_Sub array) {
   Exp* e = array->exp;
   while(e) {
     if(!exp_is_zero(e))
       ERR_B(e->loc, _("arrays of abstract type should use `0` size"));
     e = e->next;
   }
-  return GW_OK;
+  return true;
 }
 
-ANN static m_bool scan1_decl(const Env env, Exp_Decl *const decl) {
+ANN static bool scan1_decl(const Env env, Exp_Decl *const decl) {
   const bool decl_ref = decl->var.td->array && !decl->var.td->array->exp;
   Var_Decl *const vd = &decl->var.vd;
-  CHECK_b(isres(env, vd->tag));
+  CHECK_B(isres(env, vd->tag));
   Type t = decl->type;
-  CHECK_BB(scan1_defined(env, vd));
+  CHECK_B(scan1_defined(env, vd));
   const Type base = array_base_simple(t);
   if(decl->var.td->array) {
     if (!GET_FLAG(decl->var.td, late) && !decl->var.td->array->exp)
       ERR_B(decl->var.td->tag.loc, _("arrays with no expressions should be declared `late`"));
     if (GET_FLAG(decl->var.td, late) && decl->var.td->array->exp)
       ERR_B(decl->var.td->array->exp->loc, _("late array should have no size"));
-    if (!decl->args && GET_FLAG(base, abstract)) CHECK_BB(abstract_array(env, decl->var.td->array));
+    if (!decl->args && GET_FLAG(base, abstract)) CHECK_B(abstract_array(env, decl->var.td->array));
   }
   const Value v = vd->value =
       vd->value ?: new_value(env, t, vd->tag);
@@ -148,14 +155,14 @@ ANN static m_bool scan1_decl(const Env env, Exp_Decl *const decl) {
     SET_FLAG(v, global);
   nspc_add_value(env->curr, vd->tag.sym, v);
   ((Exp_Decl *)decl)->type = decl->var.vd.value->type;
-  return GW_OK;
+  return true;
 }
 
-ANN m_bool scan1_exp_decl(const Env env, Exp_Decl *const decl) {
-  CHECK_b(env_storage(env, decl->var.td->flag, exp_self(decl)->loc));
+ANN bool scan1_exp_decl(const Env env, Exp_Decl *const decl) {
+  CHECK_B(env_storage(env, decl->var.td->flag, exp_self(decl)->loc));
   ((Exp_Decl *)decl)->type = scan1_exp_decl_type(env, (Exp_Decl *)decl);
-  CHECK_OB(decl->type);
-  if(decl->args) CHECK_BB(scan1_exp(env, decl->args));
+  CHECK_B(decl->type);
+  if(decl->args) CHECK_B(scan1_exp(env, decl->args));
   const bool global = GET_FLAG(decl->var.td, global);
   if (global) {
     if (env->context) env->context->global = true;
@@ -163,24 +170,24 @@ ANN m_bool scan1_exp_decl(const Env env, Exp_Decl *const decl) {
       ERR_B(exp_self(decl)->loc, _("type '%s' is not global"), decl->type->name)
   }
   const m_uint scope = !global ? env->scope->depth : env_push_global(env);
-  const m_bool ret   = scan1_decl(env, decl);
+  const bool ret   = scan1_decl(env, decl);
   if (global) env_pop(env, scope);
   return ret;
 }
 
-ANN static inline m_bool scan1_exp_binary(const Env         env,
+ANN static inline bool scan1_exp_binary(const Env         env,
                                           const Exp_Binary *bin) {
-  CHECK_BB(scan1_exp(env, bin->lhs));
+  CHECK_B(scan1_exp(env, bin->lhs));
   return scan1_exp(env, bin->rhs);
 }
 
-ANN static m_bool scan1_range(const Env env, Range *range) {
-  if (range->start) CHECK_BB(scan1_exp(env, range->start));
-  if (range->end) CHECK_BB(scan1_exp(env, range->end));
-  return GW_OK;
+ANN static bool scan1_range(const Env env, Range *range) {
+  if (range->start) CHECK_B(scan1_exp(env, range->start));
+  if (range->end) CHECK_B(scan1_exp(env, range->end));
+  return true;
 }
 
-ANN static inline m_bool scan1_prim(const Env env, const Exp_Primary *prim) {
+ANN static inline bool scan1_prim(const Env env, const Exp_Primary *prim) {
   if (prim->prim_type == ae_prim_dict || prim->prim_type == ae_prim_interp)
     return scan1_exp(env, prim->d.exp);
   if (prim->prim_type == ae_prim_hack) {
@@ -193,135 +200,140 @@ ANN static inline m_bool scan1_prim(const Env env, const Exp_Primary *prim) {
   if (prim->prim_type == ae_prim_range) return scan1_range(env, prim->d.range);
   if (env->func && prim->prim_type == ae_prim_perform && env->scope->depth <= 2)
     env->func->memoize = 1;
-  return GW_OK;
+  return true;
 }
 
-ANN static inline m_bool scan1_exp_array(const Env        env,
+ANN static inline bool scan1_exp_array(const Env        env,
                                          const Exp_Array *array) {
-  CHECK_BB(scan1_exp(env, array->base));
+  CHECK_B(scan1_exp(env, array->base));
   return scan1_exp(env, array->array->exp);
 }
 
-ANN static inline m_bool scan1_exp_slice(const Env        env,
+ANN static inline bool scan1_exp_slice(const Env        env,
                                          const Exp_Slice *range) {
-  CHECK_BB(scan1_exp(env, range->base));
+  CHECK_B(scan1_exp(env, range->base));
   return scan1_range(env, range->range);
 }
 
-ANN static inline m_bool scan1_exp_cast(const Env env, const Exp_Cast *cast) {
+ANN static inline bool scan1_exp_cast(const Env env, const Exp_Cast *cast) {
   return scan1_exp(env, cast->exp);
 }
 
-ANN static m_bool scan1_exp_post(const Env env, const Exp_Postfix *post) {
-  CHECK_BB(scan1_exp(env, post->exp));
+ANN static bool scan1_exp_post(const Env env, const Exp_Postfix *post) {
+  CHECK_B(scan1_exp(env, post->exp));
   const m_str access = exp_access(post->exp);
-  if (!access) return GW_OK;
+  if (!access) return true;
   ERR_B(post->exp->loc,
         _("post operator '%s' cannot be used"
           " on %s data-type..."),
         s_name(post->op), access);
 }
 
-ANN static m_bool scan1_exp_call(const Env env, const Exp_Call *exp_call) {
-  if (exp_call->tmpl) return GW_OK;
-  CHECK_BB(scan1_exp(env, exp_call->func));
+ANN static bool scan1_exp_call(const Env env, const Exp_Call *exp_call) {
+  if (exp_call->tmpl) return true;
+  CHECK_B(scan1_exp(env, exp_call->func));
   Exp* args = exp_call->args;
-  return args ? scan1_exp(env, args) : GW_OK;
+  return args ? scan1_exp(env, args) : true;
 }
 
-ANN static inline m_bool scan1_exp_dot(const Env env, const Exp_Dot *member) {
+ANN static inline bool scan1_exp_dot(const Env env, const Exp_Dot *member) {
   return scan1_exp(env, member->base);
 }
 
-ANN static m_bool scan1_exp_if(const Env env, const Exp_If *exp_if) {
-  CHECK_BB(scan1_exp(env, exp_if->cond));
-  if(exp_if->if_exp) CHECK_BB(scan1_exp(env, exp_if->if_exp));
+ANN static bool scan1_exp_if(const Env env, const Exp_If *exp_if) {
+  CHECK_B(scan1_exp(env, exp_if->cond));
+  if(exp_if->if_exp) CHECK_B(scan1_exp(env, exp_if->if_exp));
   return scan1_exp(env, exp_if->else_exp);
 }
 
-ANN static inline m_bool scan1_exp_unary(const restrict Env env,
+ANN static inline bool scan1_exp_unary(const restrict Env env,
                                          Exp_Unary *const  unary) {
   if(unary->unary_type == unary_exp)
     return scan1_exp(env, unary->exp);
   if (unary->unary_type == unary_code)
     return scan1_stmt_list(env, unary->code);
-  return GW_OK;
+  return true;
 }
 
-#define scan1_exp_lambda dummy_func
-#define scan1_exp_td     dummy_func
-HANDLE_EXP_FUNC(scan1, m_bool, Env)
+#define scan1_exp_lambda bdummy_func
+#define scan1_exp_td     bdummy_func
+HANDLE_EXP_FUNC_B(scan1, bool, Env)
 
-ANN static inline m_bool _scan1_stmt_match_case(const restrict Env env,
+ANN static inline bool _scan1_stmt_match_case(const restrict Env env,
                                                 const Stmt_Match   stmt) {
-  CHECK_BB(scan1_exp(env, stmt->cond));
-  if (stmt->when) CHECK_BB(scan1_exp(env, stmt->when));
+  CHECK_B(scan1_exp(env, stmt->cond));
+  if (stmt->when) CHECK_B(scan1_exp(env, stmt->when));
   return scan1_stmt_list(env, stmt->list);
 }
 
-ANN static inline m_bool scan1_stmt_match_case(const restrict Env env,
+ANN static inline bool scan1_stmt_match_case(const restrict Env env,
                                                const Stmt_Match   stmt) {
-    RET_NSPC(_scan1_stmt_match_case(env, stmt))}
+    RET_NSPC_B(_scan1_stmt_match_case(env, stmt))}
 
-ANN static inline m_bool
+ANN static inline bool
     _scan1_stmt_match(const restrict Env env, const Stmt_Match stmt) {
-  if (stmt->where) CHECK_BB(scan1_stmt(env, stmt->where));
+  if (stmt->where) CHECK_B(scan1_stmt(env, stmt->where));
   Stmt_List l = stmt->list;
+  bool ok = true;
   for(m_uint i = 0; i < l->len; i++) {
     Stmt* s = mp_vector_at(l, Stmt, i);
-    CHECK_BB(scan1_stmt_match_case(env, &s->d.stmt_match));
+    if(!scan1_stmt_match_case(env, &s->d.stmt_match))
+      ok = false;
   }
-  return GW_OK;
+  return ok;
 }
 
-ANN static inline m_bool scan1_stmt_match(const restrict Env env,
+ANN static inline bool scan1_stmt_match(const restrict Env env,
                                           const Stmt_Match   stmt) {
-  CHECK_BB(scan1_exp(env, stmt->cond));
-  RET_NSPC(_scan1_stmt_match(env, stmt))
+  CHECK_B(scan1_exp(env, stmt->cond));
+  RET_NSPC_B(_scan1_stmt_match(env, stmt))
 }
 
-ANN static inline m_bool scan1_handler(const restrict Env env,
+ANN static inline bool scan1_handler(const restrict Env env,
                                             const Handler *handler) {
-  RET_NSPC(scan1_stmt(env, handler->stmt));
+  RET_NSPC_B(scan1_stmt(env, handler->stmt));
 }
 
-ANN static inline m_bool scan1_handler_list(const restrict Env env,
+ANN static inline bool scan1_handler_list(const restrict Env env,
                                             const Handler_List handlers) {
+  bool ok = true;
   for(uint32_t i = 0; i < handlers->len; i++) {
     Handler * handler = mp_vector_at(handlers, Handler, i);
-    CHECK_BB(scan1_handler(env, handler));
+    if(!scan1_handler(env, handler))
+      ok = false;
   }
-  return GW_OK;
+  return ok;
 }
 
-ANN static inline m_bool scan1_stmt_try(const restrict Env env,
+ANN static inline bool scan1_stmt_try(const restrict Env env,
                                         const Stmt_Try     stmt) {
-  CHECK_BB(scan1_handler_list(env, stmt->handler));
-  RET_NSPC(scan1_stmt(env, stmt->stmt))
+  CHECK_B(scan1_handler_list(env, stmt->handler));
+  RET_NSPC_B(scan1_stmt(env, stmt->stmt))
 }
 
-ANN static inline m_bool stmt_each_defined(const restrict Env env,
+ANN static inline bool stmt_each_defined(const restrict Env env,
                                            const Stmt_Each    stmt) {
+  bool ok = true;
   if (nspc_lookup_value1(env->curr, stmt->tag.sym))
-    ERR_B(stmt_self(stmt)->loc, _("foreach value '%s' is already defined"),
+    ERR_OK(ok, stmt_self(stmt)->loc, _("foreach value '%s' is already defined"),
           s_name(stmt->tag.sym))
   if (stmt->idx && nspc_lookup_value1(env->curr, stmt->idx->var.tag.sym))
-    ERR_B(stmt->idx->var.tag.loc, _("foreach index '%s' is already defined"),
+    ERR_OK(ok, stmt->idx->var.tag.loc, _("foreach index '%s' is already defined"),
           s_name(stmt->idx->var.tag.sym))
-  return GW_OK;
+  return ok;
 }
 
-ANN static inline m_bool shadow_err(const Env env, const Value v,
+ANN static inline bool shadow_err(const Env env, const Value v,
                                     const loc_t loc) {
-  if(env->scope->shadowing) return GW_OK;
+  if(env->scope->shadowing) return true;
   gwerr_basic(_("shadowing a previously defined variable"), NULL, NULL,
               env->name, loc, 0);
   defined_here(v);
   env_set_error(env, true);
-  return GW_ERROR;
+  return false;
 }
 
-ANN static inline m_bool shadow_arg(const Env env, const Tag tag) {
+ANN static inline bool shadow_arg(const Env env, const Tag tag) {
   Nspc nspc = env->curr;
   do {
     const Value v = nspc_lookup_value0(nspc, tag.sym);
@@ -332,27 +344,27 @@ ANN static inline m_bool shadow_arg(const Env env, const Tag tag) {
       return shadow_err(env, v, tag.loc);
     }
   } while ((nspc = nspc->parent));
-  return GW_OK;
+  return true;
 }
 
-ANN static inline m_bool shadow_var(const Env env, const Tag tag){
+ANN static inline bool shadow_var(const Env env, const Tag tag){
   const Value v = nspc_lookup_value1(env->curr, tag.sym);
-  return !v ? GW_OK : shadow_err(env, v, tag.loc);
+  return !v ? true : shadow_err(env, v, tag.loc);
 }
 
 #define describe_ret_nspc(name, type, prolog, exp)                             \
-  describe_stmt_func(scan1, name, type, prolog, exp)
-describe_ret_nspc(flow, Stmt_Flow,, !(scan1_exp(env, stmt->cond) < 0 ||
-    scan1_stmt(env, stmt->body) < 0) ? 1 : -1)
-describe_ret_nspc(for, Stmt_For,, !(scan1_stmt(env, stmt->c1) < 0 ||
-    scan1_stmt(env, stmt->c2) < 0 ||
-    (stmt->c3 && scan1_exp(env, stmt->c3) < 0) ||
-    scan1_stmt(env, stmt->body) < 0) ? 1 : -1)
-describe_ret_nspc(each, Stmt_Each,, !(stmt_each_defined(env, stmt) < 0 || scan1_exp(env, stmt->exp) < 0 ||
-    scan1_stmt(env, stmt->body) < 0) ? 1 : -1)
-describe_ret_nspc(loop, Stmt_Loop,, !( (!stmt->idx ? GW_OK : shadow_var(env, stmt->idx->var.tag)) < 0 ||
-    scan1_exp(env, stmt->cond) < 0 ||
-    scan1_stmt(env, stmt->body) < 0) ? 1 : -1)
+  describe_stmt_func_b(scan1, name, type, prolog, exp)
+describe_ret_nspc(flow, Stmt_Flow,, !(!scan1_exp(env, stmt->cond) ||
+    !scan1_stmt(env, stmt->body)) ? true : false)
+describe_ret_nspc(for, Stmt_For,, !(!scan1_stmt(env, stmt->c1) ||
+    !scan1_stmt(env, stmt->c2) ||
+    (stmt->c3 && !scan1_exp(env, stmt->c3)) ||
+    !scan1_stmt(env, stmt->body)) ? true : false)
+describe_ret_nspc(each, Stmt_Each,, !(!stmt_each_defined(env, stmt) || !scan1_exp(env, stmt->exp) ||
+    !scan1_stmt(env, stmt->body)) ? true : false)
+describe_ret_nspc(loop, Stmt_Loop,, !( (!stmt->idx ? true : !shadow_var(env, stmt->idx->var.tag)) ||
+    !scan1_exp(env, stmt->cond) ||
+    !scan1_stmt(env, stmt->body)) ? true : false)
 
 ANN static inline bool if_stmt_is_return(Stmt* stmt) {
   if (stmt->stmt_type == ae_stmt_return) return true;
@@ -365,33 +377,33 @@ ANN static inline bool if_stmt_is_return(Stmt* stmt) {
   return false;
 }
 
-ANN static inline m_bool _scan1_stmt_if(const Env env, const Stmt_If stmt) {
-  CHECK_BB(scan1_exp(env, stmt->cond));
-  CHECK_BB(scan1_stmt(env, stmt->if_body));
+ANN static inline bool _scan1_stmt_if(const Env env, const Stmt_If stmt) {
+  CHECK_B(scan1_exp(env, stmt->cond));
+  CHECK_B(scan1_stmt(env, stmt->if_body));
   if(stmt->else_body) {
     const bool is_ret = if_stmt_is_return(stmt->if_body);
     if(is_ret) env->scope->depth--;
-    CHECK_BB(scan1_stmt(env, stmt->else_body));
+    CHECK_B(scan1_stmt(env, stmt->else_body));
     if(is_ret) env->scope->depth++;
   }
-  return GW_OK;
+  return true;
 }
 
-ANN static inline m_bool scan1_stmt_if(const Env env, const Stmt_If stmt) {
-  RET_NSPC(_scan1_stmt_if(env, stmt));
-  return GW_OK;
+ANN static inline bool scan1_stmt_if(const Env env, const Stmt_If stmt) {
+  RET_NSPC_B(_scan1_stmt_if(env, stmt));
+  return true;
 }
 
-ANN static inline m_bool scan1_stmt_code(const Env env, const Stmt_Code stmt) {
-  if (stmt->stmt_list) { RET_NSPC(scan1_stmt_list(env, stmt->stmt_list)) }
-  return GW_OK;
+ANN static inline bool scan1_stmt_code(const Env env, const Stmt_Code stmt) {
+  if (stmt->stmt_list) { RET_NSPC_B(scan1_stmt_list(env, stmt->stmt_list)) }
+  return true;
 }
 
-ANN static inline m_bool scan1_stmt_exp(const Env env, const Stmt_Exp stmt) {
+ANN static inline bool scan1_stmt_exp(const Env env, const Stmt_Exp stmt) {
   return stmt->val ? scan1_exp(env, stmt->val) : 1;
 }
 
-ANN m_bool scan1_enum_def(const Env env, const Enum_Def edef) {
+ANN bool scan1_enum_def(const Env env, const Enum_Def edef) {
   const Type t = edef->type;
   t->nspc = new_nspc(env->gwion->mp, t->name);
   const m_uint scope = env_push_type(env, t);
@@ -410,7 +422,7 @@ ANN m_bool scan1_enum_def(const Env env, const Enum_Def edef) {
     set_vflag(v, vflag_builtin);
   }
   env_pop(env, scope);
-  return GW_OK;
+  return true;
 }
 
 ANN static Value arg_value(const Env env, Arg *const arg) {
@@ -422,44 +434,49 @@ ANN static Value arg_value(const Env env, Arg *const arg) {
   return v;
 }
 
-ANN static m_bool scan1_args(const Env env, Arg_List args) {
+ANN static bool scan1_args(const Env env, Arg_List args) {
+  bool ok = true;
   for(uint32_t i = 0; i < args->len; i++) {
     Arg *arg = mp_vector_at(args, Arg, i);
     Var_Decl *const vd = &arg->var.vd;
-    if (vd->tag.sym) CHECK_b(isres(env, vd->tag));
+    if (vd->tag.sym) {
+      if(!isres(env, vd->tag))
+        ok = false;
+    }
     if (arg->var.td) {
       SET_FLAG(arg->var.td, late);
-      CHECK_OB((arg->type = void_type(env, arg->var.td)));
+      if(!(arg->type = void_type(env, arg->var.td)))
+        ok = false;
       if (GET_FLAG(env->func->def->base, global) && !type_global(env, arg->type))
-        ERR_B(arg->var.td->tag.loc, "is not global");
-      UNSET_FLAG(arg->var.td, late);
+        ERR_OK(ok, arg->var.td->tag.loc, "is not global");
+      UNSET_FLAG(arg->var.td, late); // ???
     }
     vd->value = arg_value(env, arg);
-    if (vd->tag.sym) nspc_add_value(env->curr, vd->tag.sym, vd->value);
+    if (ok && vd->tag.sym) nspc_add_value(env->curr, vd->tag.sym, vd->value);
   }
-  return GW_OK;
+  return ok;
 }
 
 ANN static Type scan1_noret(const Env env, const Func_Base *base) {
   assert(base->td);
-  DECL_OO(const Type, t, = known_type(env, base->td));
+  DECL_O(const Type, t, = known_type(env, base->td));
   if (!tflag(t, tflag_noret)) return t;
   ERR_O(base->tag.loc, _("Can't use type `{+G}%s{0}` for return"), t->name);
 }
 
-ANN static m_bool _scan1_fbase_tmpl(const Env env, Func_Base *base) {
+ANN static bool _scan1_fbase_tmpl(const Env env, Func_Base *base) {
   Specialized_List sl = base->tmpl->list;
   for(uint32_t i = 0; i < sl->len; i++) {
     Specialized *spec = mp_vector_at(sl, Specialized, i);
     nspc_add_type(env->curr, spec->tag.sym, env->gwion->type[et_auto]);
   }
-  CHECK_OB((base->ret_type = scan1_noret(env, base)));
-  return GW_OK;
+  CHECK_B((base->ret_type = scan1_noret(env, base)));
+  return true;
 }
 
-ANN static m_bool scan1_fbase_tmpl(const Env env, Func_Base *const base) {
+ANN static bool scan1_fbase_tmpl(const Env env, Func_Base *const base) {
   nspc_push_type(env->gwion->mp, env->curr);
-  const m_bool ret = _scan1_fbase_tmpl(env, base);
+  const bool ret = _scan1_fbase_tmpl(env, base);
   nspc_pop_type(env->gwion->mp, env->curr);
   return ret;
 }
@@ -484,7 +501,7 @@ ANN static bool find_op_template_type(const MemPool mp, const Symbol xid, const
   return false;
 }
 
-ANN static m_bool scan1_fdef_base_tmpl(const Env env, const Func_Def fdef) {
+ANN static bool scan1_fdef_base_tmpl(const Env env, const Func_Def fdef) {
   Func_Base *const base = fdef->base;
   if (!fbflag(base, fbflag_op)) return scan1_fbase_tmpl(env, base);
   Arg_List         args = fdef->base->args;
@@ -504,27 +521,27 @@ ANN static m_bool scan1_fdef_base_tmpl(const Env env, const Func_Def fdef) {
   const Vector v = &env->curr->operators->tmpl;
   if (!v->ptr) vector_init(v);
   vector_add(v, (m_uint)cpy_func_def(env->gwion->mp, fdef));
-  return GW_OK;
+  return true;
 }
 
-ANN m_bool scan1_fptr_def(const Env env, const Fptr_Def fptr) {
+ANN bool scan1_fptr_def(const Env env, const Fptr_Def fptr) {
   const bool global = GET_FLAG(fptr->cdef, global);
   if(global) env_push_global(env);
-  const m_bool ret = scan1_class_def(env, fptr->cdef);
+  const bool ret = scan1_class_def(env, fptr->cdef);
   if(global) env_pop(env, 0);
   return ret;
 }
 
-ANN m_bool scan1_type_def(const Env env, const Type_Def tdef) {
-  if (tdef->when) CHECK_BB(scan1_exp(env, tdef->when));
+ANN bool scan1_type_def(const Env env, const Type_Def tdef) {
+  if (tdef->when) CHECK_B(scan1_exp(env, tdef->when));
   if(tflag(tdef->type->info->parent, tflag_ref))
     ERR_B(tdef->tag.loc, "can't typedef a reference type");
   if (tflag(tdef->type, tflag_cdef))
     return scan1_class_def(env, tdef->type->info->cdef);
-  return tdef->type->info->cdef ? scan1_cdef(env, tdef->type) : GW_OK;
+  return tdef->type->info->cdef ? scan1_cdef(env, tdef->type) : true;
 }
 
-ANN static inline m_bool scan1_union_def_inner_loop(const Env env,
+ANN static inline bool scan1_union_def_inner_loop(const Env env,
                                                     Union_Def udef) {
   nspc_allocdata(env->gwion->mp, udef->type->nspc);
   Variable_List  l  = udef->l;
@@ -533,36 +550,39 @@ ANN static inline m_bool scan1_union_def_inner_loop(const Env env,
   const Value v = new_value(env, env->gwion->type[et_int], MK_TAG(sym, udef->tag.loc));
   nspc_add_value_front(env->curr, sym, v);
   valuefrom(env, v->from);
+  bool ok = true;
   for(uint32_t i = 0; i < l->len; i++) {
     Variable *um = mp_vector_at(l, Variable, i);
-    DECL_OB(const Type, t, = known_type(env, um->td));
     if (nspc_lookup_value0(env->curr, um->vd.tag.sym))
-      ERR_B(um->vd.tag.loc, _("'%s' already declared in union"), s_name(um->vd.tag.sym))
-    if(tflag(t, tflag_ref))
-      ERR_B(um->vd.tag.loc, _("can't declare ref type in union"));
-    const Value v = new_value(env, t, um->vd.tag);
-    tuple_contains(env, v);
-    valuefrom(env, v->from);
-    nspc_add_value_front(env->curr, um->vd.tag.sym, v);
-    if (t->size > sz) sz = t->size;
+      ERR_OK(ok, um->vd.tag.loc, _("'%s' already declared in union"), s_name(um->vd.tag.sym))
+    const Type t = known_type(env, um->td);
+    if(t) {
+      if(tflag(t, tflag_ref))
+        ERR_OK(ok, um->vd.tag.loc, _("can't declare ref type in union"));
+      const Value v = new_value(env, t, um->vd.tag);
+      tuple_contains(env, v);
+      valuefrom(env, v->from);
+      nspc_add_value_front(env->curr, um->vd.tag.sym, v);
+      if (t->size > sz) sz = t->size;
+    } else ok = false;
   }
   udef->type->nspc->offset = SZ_INT + sz;
   udef->type->size = SZ_INT + sz;
-  return GW_OK;
+  return ok;
 }
 
-ANN static m_bool scan1_union_def_inner(const Env env, const Union_Def udef) {
+ANN static bool scan1_union_def_inner(const Env env, const Union_Def udef) {
   if (udef->tmpl && udef->tmpl->call)
-    CHECK_b(template_push_types(env, udef->tmpl));
-  const m_bool ret = scan1_union_def_inner_loop(env, udef);
+    CHECK_B(template_push_types(env, udef->tmpl));
+  const bool ret = scan1_union_def_inner_loop(env, udef);
   if (udef->tmpl && udef->tmpl->call) nspc_pop_type(env->gwion->mp, env->curr);
   return ret;
 }
 
-ANN m_bool scan1_union_def(const Env env, const Union_Def udef) {
-  if (tmpl_base(udef->tmpl)) return GW_OK;
+ANN bool scan1_union_def(const Env env, const Union_Def udef) {
+  if (tmpl_base(udef->tmpl)) return true;
   const m_uint scope = env_push_type(env, udef->type);
-  const m_bool ret   = scan1_union_def_inner(env, udef);
+  const bool ret   = scan1_union_def_inner(env, udef);
   env_pop(env, scope);
   set_tflag(udef->type, tflag_scan1);
   return ret;
@@ -570,39 +590,39 @@ ANN m_bool scan1_union_def(const Env env, const Union_Def udef) {
 
 #define scan1_stmt_while    scan1_stmt_flow
 #define scan1_stmt_until    scan1_stmt_flow
-#define scan1_stmt_continue dummy_func
-#define scan1_stmt_break    dummy_func
-#define scan1_stmt_retry    dummy_func
+#define scan1_stmt_continue bdummy_func
+#define scan1_stmt_break    bdummy_func
+#define scan1_stmt_retry    bdummy_func
 
-ANN static m_bool scan1_stmt_return(const Env env, const Stmt_Exp stmt) {
+ANN static bool scan1_stmt_return(const Env env, const Stmt_Exp stmt) {
   if (!env->func)
     ERR_B(stmt_self(stmt)->loc,
           _("'return' statement found outside function definition"))
   if (env->scope->depth == 1) env->func->memoize = 1;
-  if(stmt->val) CHECK_BB(scan1_exp(env, stmt->val));
-  return GW_OK;
+  if(stmt->val) CHECK_B(scan1_exp(env, stmt->val));
+  return true;
 }
 
-ANN static m_bool scan1_stmt_pp(const Env env, const Stmt_PP stmt) {
+ANN static bool scan1_stmt_pp(const Env env, const Stmt_PP stmt) {
   if (stmt->pp_type == ae_pp_include) env->name = stmt->data;
   if (stmt->pp_type == ae_pp_pragma && !strcmp(stmt->data, "packed")) {
     if(env->class_def && !tflag(env->class_def, tflag_union)) set_tflag(env->class_def, tflag_packed);
     else ERR_B(stmt_self(stmt)->loc, "`packed` pragma outside of {G+}class{0} or {G+}struct{0} declaration");
   }
-  return GW_OK;
+  return true;
 }
 
-ANN static m_bool scan1_stmt_defer(const Env env, const Stmt_Defer stmt) {
+ANN static bool scan1_stmt_defer(const Env env, const Stmt_Defer stmt) {
   return scan1_stmt(env, stmt->stmt);
 }
 
-ANN static m_bool scan1_stmt_spread(const Env env, const Spread_Def spread) {
+ANN static bool scan1_stmt_spread(const Env env, const Spread_Def spread) {
   ERR_B(stmt_self(spread)->loc, "spread statement outside of variadic environment");
 }
 
-DECL_STMT_FUNC(scan1, m_bool, Env)
+DECL_STMT_FUNC(scan1, bool, Env)
 
-ANN static inline m_bool scan1_stmt(const Env env, Stmt* stmt) {
+ANN static inline bool scan1_stmt(const Env env, Stmt* stmt) {
   return scan1_stmt_func[stmt->stmt_type](env, &stmt->d);
 }
 
@@ -621,18 +641,19 @@ ANN static void dead_code(const Env env, Stmt_List l, uint32_t len) {
   l->len = len;
 }
 
-ANN static m_bool scan1_stmt_list(const Env env, Stmt_List l) {
+ANN static bool scan1_stmt_list(const Env env, Stmt_List l) {
   uint32_t i;
+  bool ok = true;
   for(i = 0; i < l->len; i++) {
     Stmt* s = mp_vector_at(l, Stmt, i);
-    CHECK_BB(scan1_stmt(env, s));
+    if(!scan1_stmt(env, s)) ok = false;
     if(end_flow(s)) break;
   }
   if(++i < l->len) dead_code(env, l, i);
-  return GW_OK;
+  return ok;
 }
 
-ANN static m_bool class_internal(const Env env, const Func_Base *base) {
+ANN static bool class_internal(const Env env, const Func_Base *base) {
   assert(base->td);
   if (!env->class_def)
     ERR_B(base->td->tag.loc, _("'%s' must be in class def!!"), s_name(base->tag.sym))
@@ -640,26 +661,26 @@ ANN static m_bool class_internal(const Env env, const Func_Base *base) {
     ERR_B(base->td->tag.loc, _("'%s' must not have args"), s_name(base->tag.sym))
   if (base->ret_type != env->gwion->type[et_void])
     ERR_B(base->td->tag.loc, _("'%s' must return 'void'"), s_name(base->tag.sym))
-  return GW_OK;
+  return true;
 }
 
-ANN static inline m_bool scan_internal_arg(const Env        env,
+ANN static inline bool scan_internal_arg(const Env        env,
                                            const Func_Base *base) {
-  if (mp_vector_len(base->args) == 1) return GW_OK;
+  if (mp_vector_len(base->args) == 1) return true;
   assert(base->td);
   ERR_B(base->td->tag.loc, _("'%s' must have one (and only one) argument"),
         s_name(base->tag.sym))
 }
 
-ANN static inline m_bool scan_internal_int(const Env        env,
+ANN static inline bool scan_internal_int(const Env        env,
                                            const Func_Base *base) {
   assert(base->td);
-  CHECK_BB(scan_internal_arg(env, base));
-  if (isa(base->ret_type, env->gwion->type[et_int]) > 0) return GW_OK;
+  CHECK_B(scan_internal_arg(env, base));
+  if (isa(base->ret_type, env->gwion->type[et_int]) > 0) return true;
   ERR_B(base->td->tag.loc, _("'%s' must return 'int'"), s_name(base->tag.sym))
 }
 
-ANN static m_bool scan_internal(const Env env, const Func_Base *base) {
+ANN static bool scan_internal(const Env env, const Func_Base *base) {
   const Symbol op = base->tag.sym;
   if (op == insert_symbol("@dtor")) {
     if(safe_tflag(env->class_def, tflag_struct))
@@ -679,67 +700,69 @@ ANN static m_bool scan_internal(const Env env, const Func_Base *base) {
      op == insert_symbol("@each_val")   ||
      op == insert_symbol("@partial"))
       ERR_B(base->tag.loc, "operator '%s' not allowed", s_name(op));
-  return GW_OK;
+  return true;
 }
 
-ANN static m_bool scan1_fdef_args(const Env env, Arg_List args) {
+ANN static bool scan1_fdef_args(const Env env, Arg_List args) {
+  bool ok = true;
   for(uint32_t i = 0; i < args->len; i++) {
     Arg *arg = mp_vector_at(args, Arg, i);
-    CHECK_BB(shadow_arg(env, arg->var.vd.tag));
+    if(!shadow_arg(env, arg->var.vd.tag))
+      ok = false;
   }
-  return GW_OK;
+  return ok;
 }
 
-ANN m_bool scan1_fbody(const Env env, const Func_Def fdef) {
+ANN bool scan1_fbody(const Env env, const Func_Def fdef) {
   if (fdef->base->args) {
-    CHECK_BB(scan1_fdef_args(env, fdef->base->args));
-    CHECK_BB(scan1_args(env, fdef->base->args));
+    CHECK_B(scan1_fdef_args(env, fdef->base->args));
+    CHECK_B(scan1_args(env, fdef->base->args));
   }
   if (!fdef->builtin && fdef->d.code)
-    CHECK_BB(scan1_stmt_list(env, fdef->d.code));
-  return GW_OK;
+    CHECK_B(scan1_stmt_list(env, fdef->d.code));
+  return true;
 }
 
-ANN m_bool scan1_fdef(const Env env, const Func_Def fdef) {
+ANN bool scan1_fdef(const Env env, const Func_Def fdef) {
   if (fdef->base->td)
-    CHECK_OB((fdef->base->ret_type = scan1_noret(env, fdef->base)));
+    CHECK_B((fdef->base->ret_type = scan1_noret(env, fdef->base)));
   if (fbflag(fdef->base, fbflag_internal))
-    CHECK_BB(scan_internal(env, fdef->base));
+    CHECK_B(scan_internal(env, fdef->base));
   else if (fbflag(fdef->base, fbflag_op) && env->class_def)
     SET_FLAG(fdef->base, static);
   if(!is_ctor(fdef)) {
-    RET_NSPC(scan1_fbody(env, fdef))
+    RET_NSPC_B(scan1_fbody(env, fdef))
   } else if(!fdef->builtin)
-      CHECK_BB(scan1_stmt_list(env, fdef->d.code));
-  return GW_OK;
+      CHECK_B(scan1_stmt_list(env, fdef->d.code));
+  return true;
 }
 
-ANN static inline m_bool scan1_fdef_defined(const Env      env,
+ANN static inline bool scan1_fdef_defined(const Env      env,
                                             const Func_Def fdef) {
   const Value v = nspc_lookup_value1(env->curr, fdef->base->tag.sym);
-  if (!v) return GW_OK;
-  if (is_func(env->gwion, actual_type(env->gwion, v->type))) return GW_OK; // is_callable
-  if(fdef->builtin) return GW_OK;
+  if (!v) return true;
+  if (is_func(env->gwion, actual_type(env->gwion, v->type))) return true; // is_callable
+  if(fdef->builtin) return true;
   if ((!env->class_def || !GET_FLAG(env->class_def, final)) &&
       !nspc_lookup_value0(env->curr, fdef->base->tag.sym))
     ERR_B(fdef->base->tag.loc,
           _("function '%s' has already been defined in the same scope..."),
           s_name(fdef->base->tag.sym));
-  return GW_OK;
+  return true;
 }
 
-ANN static m_bool _scan1_func_def(const Env env, const Func_Def fdef) {
+ANN static bool _scan1_func_def(const Env env, const Func_Def fdef) {
   if(GET_FLAG(fdef->base, abstract) && !env->class_def)
     ERR_B(fdef->base->tag.loc, "file scope function can't be abstract");
-  CHECK_b(env_storage(env, fdef->base->flag, fdef->base->tag.loc));
-  CHECK_BB(scan1_fdef_defined(env, fdef));
+  CHECK_B(env_storage(env, fdef->base->flag, fdef->base->tag.loc));
+  CHECK_B(scan1_fdef_defined(env, fdef));
   const bool   global = GET_FLAG(fdef->base, global);
   const m_uint scope  = !global ? env->scope->depth : env_push_global(env);
   if (tmpl_base(fdef->base->tmpl)) return scan1_fdef_base_tmpl(env, fdef);
   struct Func_ fake = {.name = s_name(fdef->base->tag.sym), .def = fdef }, *const former =
                                                              env->func;
   env->func = &fake;
-  const m_bool ret = scanx_fdef(env, env, fdef, (_exp_func)scan1_fdef);
+  const bool ret = scanx_fdef_b(env, env, fdef, (_exp_func_b)scan1_fdef);
   env->func = former;
   if (global) env_pop(env, scope);
   if ((strcmp(s_name(fdef->base->tag.sym), "@implicit") || fbflag(fdef->base, fbflag_internal)) && !fdef->builtin && fdef->base->ret_type &&
@@ -751,23 +774,23 @@ ANN static m_bool _scan1_func_def(const Env env, const Func_Def fdef) {
     gwerr_basic(_("`@gack` operator does not print anything"), NULL,
       _("use `<<<` `>>>` in the function"), env->name, fdef->base->tag.loc, 0);
     env_set_error(env,  true);
-    return GW_ERROR;
+    return false;
   }
   return ret;
 }
 
-ANN m_bool scan1_func_def(const Env env, const Func_Def fdef) {
+ANN bool scan1_func_def(const Env env, const Func_Def fdef) {
   const uint16_t depth = env->scope->depth;
   env->scope->depth = 0;
-  const m_bool ret = _scan1_func_def(env, fdef);
+  const bool ret = _scan1_func_def(env, fdef);
   env->scope->depth = depth;
   return ret;
 }
 
-#define scan1_trait_def dummy_func
-#define scan1_extend_def dummy_func
-#define scan1_prim_def dummy_func
-HANDLE_SECTION_FUNC(scan1, m_bool, Env)
+#define scan1_trait_def bdummy_func
+#define scan1_extend_def bdummy_func
+#define scan1_prim_def bdummy_func
+HANDLE_SECTION_FUNC(scan1, bool, Env)
 
 ANN static Type scan1_get_parent(const Env env, const Type_Def tdef) {
   const Type parent = tdef->type->info->parent;
@@ -780,35 +803,35 @@ ANN static Type scan1_get_parent(const Env env, const Type_Def tdef) {
   return parent;
 }
 
-ANN static m_bool scan1_parent(const Env env, const Class_Def cdef) {
+ANN static bool scan1_parent(const Env env, const Class_Def cdef) {
   const loc_t loc = cdef->base.ext->tag.loc;
   if (cdef->base.ext->array && cdef->base.ext->array->exp)
-    CHECK_BB(scan1_exp(env, cdef->base.ext->array->exp));
-  DECL_OB(const Type, parent, = scan1_get_parent(env, &cdef->base));
+    CHECK_B(scan1_exp(env, cdef->base.ext->array->exp));
+  DECL_B(const Type, parent, = scan1_get_parent(env, &cdef->base));
   if (isa(parent, env->gwion->type[et_object]) < 0 &&
 //      !(tflag(cdef->base.type, tflag_cdef) || tflag(cdef->base.type, tflag_udef)))
       !(tflag(cdef->base.type, tflag_cdef) || tflag(cdef->base.type, tflag_union)))
     ERR_B(loc, _("cannot extend primitive type '%s'"), parent->name)
   if (type_ref(parent)) ERR_B(loc, _("can't use ref type in class extend"))
-  return GW_OK;
+  return true;
 }
 
 ANN static inline Type scan1_final(const Env env, Type_Decl *td, const bool tdef) {
-  DECL_OO(const Type, t, = known_type(env, td));
+  DECL_O(const Type, t, = known_type(env, td));
   if (!GET_FLAG(t, final) || tdef) return t;
   ERR_O(td->tag.loc, _("can't inherit from final parent class '%s'\n."), t->name);
 }
 
-ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) {
-  CHECK_OB((cdef->base.type->info->parent = scan1_final(env, cdef->base.ext, tflag(cdef->base.type, tflag_typedef))));
+ANN static bool cdef_parent(const Env env, const Class_Def cdef) {
+  CHECK_B((cdef->base.type->info->parent = scan1_final(env, cdef->base.ext, tflag(cdef->base.type, tflag_typedef))));
   const bool tmpl = !!cdef->base.tmpl;
-  if (tmpl) CHECK_b(template_push_types(env, cdef->base.tmpl));
-  const m_bool ret = scan1_parent(env, cdef);
+  if (tmpl) CHECK_B(template_push_types(env, cdef->base.tmpl));
+  const bool ret = scan1_parent(env, cdef);
   if (tmpl) nspc_pop_type(env->gwion->mp, env->curr);
   return ret;
 }
 
-ANN static m_bool scan1_class_def_body(const Env env, const Class_Def cdef) {
+ANN static bool scan1_class_def_body(const Env env, const Class_Def cdef) {
   if(!tmpl_base(cdef->base.tmpl) && isa(cdef->base.type, env->gwion->type[et_closure]) < 0 &&
    isa(cdef->base.type, env->gwion->type[et_dict]) < 0) {
     MemPool mp = env->gwion->mp;
@@ -833,21 +856,21 @@ ANN static m_bool scan1_class_def_body(const Env env, const Class_Def cdef) {
     free_mp_vector(mp, Section, base);
     cdef->body = body;
   }
-  return env_body(env, cdef, scan1_section);
+  return env_body_b(env, cdef, scan1_section);
 }
 
-ANN static m_bool scan1_class_tmpl(const Env env, const Class_Def c) {
+ANN static bool scan1_class_tmpl(const Env env, const Class_Def c) {
   Specialized_List sl = c->base.tmpl->list;
   TmplArg_List tl = c->base.tmpl->call;
   env_push_type(env, c->base.type);
-  m_bool ret = GW_OK;
+  bool ret = true;
 // check len
   for(uint32_t i = 0; i < sl->len; i++) {
     const TmplArg targ = *mp_vector_at(tl, TmplArg, i);
 //      const Specialized spec = *mp_vector_at(sl, Specialized, i);
     if (targ.type == tmplarg_td) continue;
-    if(scan1_exp(env, targ.d.exp) < 0) {
-      ret = GW_ERROR;
+    if(!scan1_exp(env, targ.d.exp)) {
+      ret = false;
       break;
     }
 /*
@@ -863,28 +886,32 @@ ANN static m_bool scan1_class_tmpl(const Env env, const Class_Def c) {
   return ret;
 }
 
-ANN m_bool scan1_class_def(const Env env, const Class_Def cdef) {
-  if (tmpl_base(cdef->base.tmpl)) return GW_OK;
+ANN bool scan1_class_def(const Env env, const Class_Def cdef) {
+  if (tmpl_base(cdef->base.tmpl)) return true;
   const Type      t = cdef->base.type;
-  if (tflag(t, tflag_scan1)) return GW_OK;
+  if (tflag(t, tflag_scan1)) return true;
   set_tflag(t, tflag_scan1);
   const Class_Def c = t->info->cdef;
-  if (c->base.ext) CHECK_BB(cdef_parent(env, c));
-  if (c->body) CHECK_BB(scan1_class_def_body(env, c));
-  if (c->base.tmpl) CHECK_BB(scan1_class_tmpl(env, c));
-  return GW_OK;
+  if (c->base.ext) CHECK_B(cdef_parent(env, c));
+  if (c->body) CHECK_B(scan1_class_def_body(env, c));
+  if (c->base.tmpl) CHECK_B(scan1_class_tmpl(env, c));
+  return true;
 }
 
-ANN m_bool scan1_ast(const Env env, Ast *ast) {
+ANN bool scan1_ast(const Env env, Ast *ast) {
   Ast a = *ast;
+  bool ok = true;
   for(m_uint i = 0; i < a->len; i++) {
     Section *section = mp_vector_at(a, Section, i);
-//    CHECK_BB(scan1_section(env, section));
-    if(section->poison) continue;
-    if(scan1_section(env, section) < 0) {
+    if(section->poison) {
+      ok = false;
+      continue;
+    }
+    if(!scan1_section(env, section)) {
       section->poison = true;
-      return GW_ERROR;
+      ok = false;
+      return false;
     }
   }
-  return GW_OK;
+  return ok;
 }
index 29012c7994e67fdac789f3eaa7f1fb87d05fd528..8f691c8d1b0f3ad7082e8e29b5eede5201c2474a 100644 (file)
@@ -83,3 +83,13 @@ ANN m_bool scanx_fdef(const Env env, void *data, const Func_Def fdef,
   env->scope->in_try = in_try;
   return ret;
 }
+ANN bool scanx_fdef_b(const Env env, void *data, const Func_Def fdef,
+                      const _exp_func_b func) {
+  if (fdef->base->tmpl) CHECK_B(template_push_types(env, fdef->base->tmpl));
+  const bool   in_try = env->scope->in_try;
+  const bool ret    = func(data, fdef);
+  if (fdef->base->tmpl) nspc_pop_type(env->gwion->mp, env->curr);
+  env->scope->in_try = in_try;
+  return ret;
+}
+
index cb759eb53fa4989fc1c5d4f4f23265819917e370..e269843b81442f1568cd0ee9eaa30ca03f2fcdb8 100644 (file)
@@ -5,20 +5,20 @@
 
 ANN m_bool traverse_ast(const Env env, Ast *const ast) {
   CHECK_b(scan0_ast(env, ast));
-  CHECK_BB(scan1_ast(env, ast));
+  CHECK_b(scan1_ast(env, ast));
   CHECK_BB(scan2_ast(env, ast));
   return check_ast(env, ast);
 }
 
 ANN m_bool traverse_exp(const Env env, Exp* exp) {
-  CHECK_BB(scan1_exp(env, exp));
+  CHECK_b(scan1_exp(env, exp));
   CHECK_BB(scan2_exp(env, exp));
   return check_exp(env, exp) ? 1 : -1;
 }
 
 ANN static m_bool _traverse_func_def(const Env env, const Func_Def fdef) {
   CHECK_b(scan0_func_def(env, fdef));
-  CHECK_BB(scan1_func_def(env, fdef));
+  CHECK_b(scan1_func_def(env, fdef));
   CHECK_BB(scan2_func_def(env, fdef));
   return check_func_def(env, fdef);
 }
@@ -32,7 +32,7 @@ ANN m_bool traverse_func_def(const Env env, const Func_Def fdef) {
 
 ANN m_bool traverse_union_def(const Env env, const Union_Def def) {
   //  if(!GET_FLAG(def, scan1))
-  CHECK_BB(scan1_union_def(env, def));
+  CHECK_b(scan1_union_def(env, def));
   //  if(!GET_FLAG(def, scan2))
   CHECK_BB(scan2_union_def(env, def));
   //  if(!GET_FLAG(def, check))
@@ -42,7 +42,7 @@ ANN m_bool traverse_union_def(const Env env, const Union_Def def) {
 
 ANN m_bool traverse_enum_def(const Env env, const Enum_Def def) {
   CHECK_b(scan0_enum_def(env, def));
-  CHECK_BB(scan1_enum_def(env, def));
+  CHECK_b(scan1_enum_def(env, def));
   //  CHECK_BB(scan2_enum_def(env, def));
   // return check_enum_def(env, def);
   return GW_OK;
@@ -50,21 +50,21 @@ ANN m_bool traverse_enum_def(const Env env, const Enum_Def def) {
 
 ANN m_bool traverse_fptr_def(const Env env, const Fptr_Def def) {
   CHECK_b(scan0_fptr_def(env, def));
-  CHECK_BB(scan1_fptr_def(env, def));
+  CHECK_b(scan1_fptr_def(env, def));
   CHECK_BB(scan2_fptr_def(env, def));
   return check_fptr_def(env, def);
 }
 
 ANN m_bool traverse_type_def(const Env env, const Type_Def def) {
   CHECK_b(scan0_type_def(env, def));
-  CHECK_BB(scan1_type_def(env, def));
+  CHECK_b(scan1_type_def(env, def));
   CHECK_BB(scan2_type_def(env, def));
   return check_type_def(env, def);
 }
 
 ANN m_bool traverse_class_def(const Env env, const Class_Def def) {
   const Type t = def->base.type;
-  if (!tflag(t, tflag_scan1)) CHECK_BB(scan1_class_def(env, def));
+  if (!tflag(t, tflag_scan1)) CHECK_b(scan1_class_def(env, def));
   if (!tflag(t, tflag_scan2)) CHECK_BB(scan2_class_def(env, def));
   if (!tflag(t, tflag_check)) return check_class_def(env, def);
   return GW_OK;
index 7ae91d14d105111e201331db8429e297a56f7f29..9d8f0c94428a2f71ae921b1e430a59e263b96ff8 100644 (file)
@@ -12,6 +12,7 @@
 #define N_SCANPASS 4
 
 static m_bool typecheck_ast(const Env env, Ast *ast) {
+  env->scope->poison = false; // move me
   CHECK_BB(traverse_ast(env, ast));
   if(env->scope->poison)env->context->error = true;
   if(env->context->error)return GW_ERROR;