From: fennecdjay Date: Mon, 12 Feb 2024 13:10:03 +0000 (+0100) Subject: :fire: now poison scan1 X-Git-Tag: nightly~96 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=b6054eed961fb99d9724a13fad23bffe0bc8c52f;p=gwion.git :fire: now poison scan1 --- diff --git a/include/parse.h b/include/parse.h index 7a9feb87..87d1de7b 100644 --- a/include/parse.h +++ b/include/parse.h @@ -40,6 +40,14 @@ --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); \ @@ -65,13 +73,16 @@ #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) \ @@ -79,6 +90,11 @@ 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; diff --git a/include/traverse.h b/include/traverse.h index d39ac62c..09544bab 100644 --- a/include/traverse.h +++ b/include/traverse.h @@ -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); diff --git a/src/lib/opfunc.c b/src/lib/opfunc.c index 955cf06e..527e5d51 100644 --- a/src/lib/opfunc.c +++ b/src/lib/opfunc.c @@ -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)); } diff --git a/src/parse/check.c b/src/parse/check.c index 3f1392e2..1c709323 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -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")); diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 82b5fd94..45261db0 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -10,10 +10,17 @@ #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; } diff --git a/src/parse/scanx.c b/src/parse/scanx.c index 29012c79..8f691c8d 100644 --- a/src/parse/scanx.c +++ b/src/parse/scanx.c @@ -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; +} + diff --git a/src/parse/traverse.c b/src/parse/traverse.c index cb759eb5..e269843b 100644 --- a/src/parse/traverse.c +++ b/src/parse/traverse.c @@ -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; diff --git a/src/pass.c b/src/pass.c index 7ae91d14..9d8f0c94 100644 --- a/src/pass.c +++ b/src/pass.c @@ -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;