From c23fff6f2542236fa4201bf7c0b3d367591f850c Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Fri, 22 Mar 2024 16:33:10 +0100 Subject: [PATCH] :art: more on errors --- include/env/value.h | 9 ------- include/gwion.h | 2 +- include/gwion_env.h | 26 +++++++++++++----- include/sema_private.h | 2 +- src/env/env_utils.c | 2 +- src/gwion.c | 4 +-- src/lib/array.c | 12 +++++---- src/lib/closure.c | 8 +++--- src/lib/instr.c | 4 +-- src/lib/object_op.c | 2 +- src/lib/prim.c | 2 +- src/parse/check.c | 51 ++++++++++++++++++----------------- src/parse/check_traits.c | 24 ++++++++--------- src/parse/did_you_mean.c | 2 +- src/parse/func_resolve_tmpl.c | 4 +-- src/parse/operator.c | 3 ++- src/parse/partial.c | 3 ++- src/parse/scan0.c | 12 ++++----- src/parse/scan1.c | 15 ++++++----- src/parse/template.c | 4 +-- src/sema/sema.c | 49 +++++++++++++++++---------------- src/vm/vm.c | 2 +- 22 files changed, 127 insertions(+), 115 deletions(-) diff --git a/include/env/value.h b/include/env/value.h index 10c29fd4..6ba5613f 100644 --- a/include/env/value.h +++ b/include/env/value.h @@ -47,15 +47,6 @@ FLAG_FUNC(Value, v) ANEW ANN Value new_value(const Env, const Type type, const Tag tag); ANN void valuefrom(const Env, ValueFrom *); -ANN static inline void defined_here(const Value v) { - if (v->from->filename) {// TODO: check why is that from check - char c[256]; - c[255] = '\0'; - snprintf(c, 256, _("%.*s defined here"), 240, v->name); - gwerr_secondary(c, v->from->filename, v->from->loc); - } -} - ANN static inline void valid_value(const Env env, const Symbol xid, const Value v) { set_vflag(v, vflag_valid); nspc_add_value(env->curr, xid, v); diff --git a/include/gwion.h b/include/gwion.h index 8675fa53..7c6a0915 100644 --- a/include/gwion.h +++ b/include/gwion.h @@ -15,7 +15,7 @@ struct Gwion_ { Emitter emit; struct GwionData_ *data; Type * type; - struct PPArg_ * ppa; + PPArg * ppa; }; ANN bool gwion_ini(const Gwion, CliArg*); diff --git a/include/gwion_env.h b/include/gwion_env.h index 387024d5..cf17aa7d 100644 --- a/include/gwion_env.h +++ b/include/gwion_env.h @@ -13,17 +13,31 @@ #include "env/tuple.h" #include "env/envset.h" -ANN2(1,4) static inline void gwerr_basic_from(const m_str msg, const m_str explain, - const m_str fix, const ValueFrom *from, +ANN2(1,3) static inline void gwlog_error_from(const m_str msg, const m_str explain, + const ValueFrom *from, const uint code) { - gwerr_basic(msg, explain, fix, from->filename, from->loc, code); + gwlog_error(msg, explain, from->filename, from->loc, code); } -ANN static inline void gwerr_secondary_from(const m_str msg, const ValueFrom *from) { - gwerr_secondary(msg, from->filename, from->loc); +ANN static inline void gwlog_warning_from(const m_str msg, const ValueFrom *from) { + gwlog_warning(msg, from->filename, from->loc); +} +ANN static inline void gwlog_related_from(const m_str msg, const ValueFrom *from) { + gwlog_related(msg, from->filename, from->loc); } ANN static inline void declared_here(const Value v) { - gwerr_secondary_from((m_str)"declared here", v->from); + gwlog_related_from((m_str)"declared here", v->from); +} + +ANN static inline void defined_here(const Value v) { + if (v->from->filename) {// TODO: check why is that from check + char c[256]; + c[255] = '\0'; + snprintf(c, 256, _("%.*s defined here"), 240, v->name); + gwlog_related_from(c, v->from); + } } + + #endif diff --git a/include/sema_private.h b/include/sema_private.h index a98a6ea4..96b50060 100644 --- a/include/sema_private.h +++ b/include/sema_private.h @@ -4,7 +4,7 @@ typedef struct { SymTable *st; MP_Vector *tmpls; Stmt_List *stmt_list; - struct PPArg_ *ppa; + PPArg *ppa; bool error; bool func; bool scope; diff --git a/src/env/env_utils.c b/src/env/env_utils.c index d82ccaf6..4c59b492 100644 --- a/src/env/env_utils.c +++ b/src/env/env_utils.c @@ -68,7 +68,7 @@ ANN Type find_type(const Env env, Type_Decl *td) { ANN bool can_define(const Env env, const Symbol s, const loc_t loc) { const Value v = nspc_lookup_value0(env->curr, s); if (!v || is_class(env->gwion, v->type)) return true; - gwerr_basic(_("already declared as variable"), NULL, NULL, env->name, loc, 0); + gwlog_error(_("already declared as variable"), NULL, env->name, loc, 0); declared_here(v); return false; } diff --git a/src/gwion.c b/src/gwion.c index 8b362e57..a614bda8 100644 --- a/src/gwion.c +++ b/src/gwion.c @@ -188,7 +188,7 @@ ANN static void env_xxx(const Env env, const loc_t loc, const m_str fmt, va_end(tmpa); char c[size + 1]; vsprintf(c, fmt, arg); - gwerr_basic(c, NULL, NULL, env->name, loc, 0); + gwlog_error(c, NULL, env->name, loc, 0); #endif } @@ -201,7 +201,7 @@ ANN static void _env_warn(const Env env, const loc_t loc, const m_str fmt, va_end(tmpa); char c[size + 1]; vsprintf(c, fmt, arg); - gwerr_warn(c, NULL, NULL, env->name, loc); + gwlog_warning(c, env->name, loc); #endif } diff --git a/src/lib/array.c b/src/lib/array.c index 6910dfd8..cf399a26 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -806,13 +806,13 @@ static OP_CHECK(opck_array_scan) { DECL_ON(const Type, base, = ts->t != t_array ? ts->t : known_type(env, mp_vector_at(ts->td->types, TmplArg, 0)->d.td)); if (base->size == 0) { - gwerr_basic("Can't use type of size 0 as array base", NULL, NULL, + gwlog_error("Can't use type of size 0 as array base", NULL, env->name, ts->td->tag.loc, 0); env_set_error(env, true); return env->gwion->type[et_error]; } if (tflag(base, tflag_ref)) { - gwerr_basic("Can't use ref types as array base", NULL, NULL, + gwlog_error("Can't use ref types as array base", NULL, env->name, ts->td->tag.loc, 0); env_set_error(env, true); return env->gwion->type[et_error]; @@ -1201,9 +1201,11 @@ ANN2(1,2) bool check_array_instance(const Env env, Type_Decl *td, Exp* args) { if (!args) ERR_B(td->tag.loc, "declaration of abstract type arrays needs lambda"); } else { - if(args) - gwerr_warn("array is empty", "no need to provide a lambda", - NULL, env->name, td->array->exp->loc); + if(args) { + gwlog_warning("array is empty", + env->name, td->array->exp->loc); + gwlog_hint(_("no need to provide a lambda"), env->name, td->tag.loc); + } } return true; } diff --git a/src/lib/closure.c b/src/lib/closure.c index 69d7b736..54951c57 100644 --- a/src/lib/closure.c +++ b/src/lib/closure.c @@ -216,14 +216,14 @@ ANN static bool fptr_args(const Env env, Func_Base *base[2]) { ANN static bool fptr_effects(const Env env, struct FptrInfo *info) { if (!info->lhs->def->base->effects.ptr) return true; if (!info->rhs->def->base->effects.ptr) { - gwerr_secondary("too many effects", env->name, info->exp->loc); + gwlog_warning("too many effects", env->name, info->exp->loc); return false; } const Vector lhs = &info->lhs->def->base->effects; const Vector rhs = &info->rhs->def->base->effects; for (m_uint i = 0; i < vector_size(lhs); i++) { if (vector_find(rhs, vector_at(lhs, 0)) == -1) { - gwerr_secondary("effect not handled", env->name, info->exp->loc); + gwlog_warning("effect not handled", env->name, info->exp->loc); return false; } } @@ -467,8 +467,8 @@ static OP_CHECK(opck_fptr_cast) { } static void op_narg_err(const Env env, const Func_Def fdef, const loc_t loc) { - gwerr_basic(_("invalid operator decay"), - _("Decayed operators take two arguments"), NULL, env->name, loc, + gwlog_error(_("invalid operator decay"), + _("Decayed operators take two arguments"), env->name, loc, 0); if (fdef) defined_here(fdef->base->func->value_ref); env_set_error(env, true); diff --git a/src/lib/instr.c b/src/lib/instr.c index 5d1b9cb4..97e68acd 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -159,9 +159,9 @@ INSTR(fast_except) { return; } else if(info) { if(info->file) - gwerr_basic("Object not instantiated", NULL, NULL, info->file, info->loc, 0); + gwlog_error("Object not instantiated", NULL, info->file, info->loc, 0); if(info->file2) - gwerr_warn("declared here", NULL, NULL, info->file2, info->loc2); + gwlog_related("declared here", info->file2, info->loc2); } handle(shred, "NullPtrException"); } diff --git a/src/lib/object_op.c b/src/lib/object_op.c index 04fb501b..4e344637 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -186,7 +186,7 @@ ANN static inline Value get_value(const Env env, const Exp_Dot *member, ANN static bool member_access(const Env env, Exp* exp, const Value value) { if (!env->class_def || !isa(env->class_def, value->from->owner_class)) { if (GET_FLAG(value, private)) { - gwerr_basic("invalid variable access", "is private", NULL, env->name, + gwlog_error("invalid variable access", "is private", env->name, exp->loc, 0); defined_here(value); env_set_error(env, true); diff --git a/src/lib/prim.c b/src/lib/prim.c index 1c998d6e..32eaad49 100644 --- a/src/lib/prim.c +++ b/src/lib/prim.c @@ -252,7 +252,7 @@ static GACK(gack_bool) { static OP_CHECK(bool2float) { struct Implicit *impl = (struct Implicit *)data; - gwerr_basic("Can't implicitely cast {G+}bool{0} to {G+}float{0}", NULL, "Did you forget a cast?", + gwlog_error("Can't implicitely cast {G+}bool{0} to {G+}float{0}", "Did you forget a cast?", env->name, impl->e->loc, 0); env_set_error(env, true); return env->gwion->type[et_error]; diff --git a/src/parse/check.c b/src/parse/check.c index 56945468..17106ef1 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -201,12 +201,12 @@ ANN static bool check_collection(const Env env, Type type, Exp* e, char fst[20 + strlen(type->name)]; sprintf(fst, "expected `{+/}%s{0}`", type->name); - gwerr_basic(_("literal contains incompatible types"), fst, "the first element determines the type", env->name, - loc, 0); - // suggested fix: rewrite int 2 as float 2.0" + gwlog_error(_("literal contains incompatible types"), fst, + env->name, loc, 0); + gwlog_hint(_("the first element determines the type"), env->name, loc); char sec[16 + strlen(e->type->name)]; sprintf(sec, "got `{+/}%s{0}`", e->type->name); - gwerr_secondary(sec, env->name, e->loc); + gwlog_related(sec, env->name, e->loc); return false; } @@ -364,9 +364,9 @@ ANN static Type check_dot(const Env env, const Exp_Dot *member) { ANN static bool check_upvalue(const Env env, const Exp_Primary *prim, const Value v) { if(not_upvalue(env, v)) return true; - gwerr_basic(_("value not in lambda scope"), NULL, NULL, env->name, exp_self(prim)->loc, 4242); + gwlog_error(_("value not in lambda scope"), NULL, env->name, exp_self(prim)->loc, 4242); declared_here(v); - gw_err("{-}hint:{0} try adding it to capture list"); + gwlog_hint(_("{0} try adding it to capture list"), env->name, exp_self(prim)->loc); env_set_error(env, true); return false; } @@ -406,7 +406,7 @@ ANN static Type prim_id_non_res(const Env env, const Symbol *data) { } m_str str = NULL; gw_asprintf(env->gwion->mp, &str, "Invalid variable {R}%s{0}\n", name); - gwerr_basic(str, _("not legit at this point."), NULL, + gwlog_error(str, _("not legit at this point."), env->name, prim_pos(data), 0); free_mstr(env->gwion->mp, str); did_you_mean_nspc(v ? v->from->owner : env->curr, s_name(sym)); @@ -693,7 +693,6 @@ ANN static inline Exp* next_arg_exp(const Exp *e) { } ANN static void print_current_args(Exp* e) { - gw_err(_("and not\n ")); do gw_err(" {G}%s{0}", e->type ? e->type->name : ""); while ((e = next_arg_exp(e))); gw_err("\n"); @@ -707,14 +706,16 @@ static void function_alternative(const Env env, const Type t, Exp* args, ? t->info->func : closure_def(t)->base->func; if(!f) return; - gwerr_basic("Argument type mismatch", "call site", - "valid alternatives:", env->name, loc, 0); + gwlog_error("Argument type mismatch", "call site", + env->name, loc, 0); + // TODO: hint valid alternatives do print_signature(f); while ((f = f->next)); + gw_err(_("and not\n ")); if (args) print_current_args(args); else - gw_err(_("and not:\n {G}void{0}\n")); + gw_err(_(" {G}void{0}\n")); env_set_error(env, true); } @@ -1156,7 +1157,7 @@ ANN static bool predefined_call(const Env env, const Type t, str); free_mstr(env->gwion->mp, str); if (tflag(t, tflag_typedef)) { - gwerr_secondary("from definition:", env->name, + gwlog_related("from definition:", env->name, t->info->func->def->base->tag.loc); } return false; @@ -1314,11 +1315,12 @@ ANN bool check_type_def(const Env env, const Type_Def tdef) { if (!isa(when->type, env->gwion->type[et_bool])) { char explain[strlen(when->type->name) + 20]; sprintf(explain, "found `{/+}%s{0}`", when->type->name); - gwerr_basic("Invalid `{/+}when{0}` predicate expression type", explain, - "use `{/+}bool{0}`", env->name, when->loc, 0); + gwlog_error("Invalid `{/+}when{0}` predicate expression type", explain, + env->name, when->loc, 0); + gwlog_hint(_("use `bool`"), env->name, when->loc); char from[strlen(tdef->type->name) + 39]; sprintf(from, "in `{/+}%s{0}` definition", tdef->type->name); - gwerr_secondary(from, env->name, tdef->tag.loc); + gwlog_related(from, env->name, tdef->tag.loc); env_set_error(env, true); return false; } @@ -1455,9 +1457,9 @@ ANN static inline bool repeat_type(const Env env, Exp* e) { if (!check_implicit(env, e, t_int)) { char explain[40 + strlen(e->type->name)]; sprintf(explain, "expected `{/+}int{0}`, got `{/+}%s{0}`", e->type->name); - gwerr_basic(_("invalid repeat condition type"), explain, - _("use an integer or cast to int if possible"), env->name, - e->loc, 0); + gwlog_error(_("invalid repeat condition type"), explain, + env->name, e->loc, 0); + gwlog_hint(_("use an integer or cast to int if possible"), env->name, e->loc); env_set_error(env, true); return false; } @@ -1767,8 +1769,8 @@ ANN static bool check_signature_match(const Env env, const Func_Def fdef, } if(fdef->base->tmpl || isa(fdef->base->ret_type, parent->def->base->ret_type)) return true; - gwerr_basic_from("invalid overriding", NULL, NULL, fdef->base->func->value_ref->from, 0); - gwerr_secondary_from("does not match", parent->value_ref->from); + gwlog_error_from("invalid overriding", NULL, fdef->base->func->value_ref->from, 0); + gwlog_related_from("does not match", parent->value_ref->from); env_set_error(env, true); return false; } @@ -2112,13 +2114,12 @@ ANN bool check_abstract(const Env env, const Class_Def cdef) { if (f && f->def->base && GET_FLAG(f->def->base, abstract)) { if (!err) { err = true; - gwerr_basic(_("missing function definition"), + gwlog_error(_("missing function definition"), _("must be declared 'abstract'"), - _("provide an implementation for the following:"), env->name, cdef->base.tag.loc, 0); } ValueFrom *from = f->value_ref->from; - gwerr_secondary_from("implementation missing", from); + gwlog_related_from("implementation missing", from); env_set_error(env, true); } } @@ -2160,7 +2161,7 @@ ANN static bool recursive_value(const Env env, const Type t, const Value v) { if(type_is_recurs(t, tgt)) { env_err(env, v->from->loc, _("recursive type")); env_set_error(env, false); - gwerr_secondary("in class", t->name, t->info->cdef->base.tag.loc); + gwlog_related("in class", t->name, t->info->cdef->base.tag.loc); const Type first = tgt->info->value->from->loc.first.line < t->info->value->from->loc.first.line ? v->type : t; @@ -2287,7 +2288,7 @@ ANN static inline void check_unhandled(const Env env) { struct ScopeEffect *eff = mp_vector_at(w, struct ScopeEffect, j); if(s_name(eff->sym)[0] == '!') continue; - gwerr_secondary("Unhandled effect", env->name, eff->loc); + gwlog_warning("Unhandled effect", env->name, eff->loc); env_set_error(env, false); } free_mp_vector(env->gwion->mp, struct ScopeEffect, w); diff --git a/src/parse/check_traits.c b/src/parse/check_traits.c index 019d56d2..c3d14e4a 100644 --- a/src/parse/check_traits.c +++ b/src/parse/check_traits.c @@ -15,26 +15,26 @@ ANN static bool var_match(const Value a, const Value b) { bool error = true; if (!isa(a->type, a->type)) { - gwerr_basic_from("invalid variable type", NULL, NULL, a->from, 0); + gwlog_error_from("invalid variable type", NULL, a->from, 0); error = false; } if (GET_FLAG(a, const) && !GET_FLAG(b, const)) { - gwerr_basic_from("variable differs in {/}constness{0}", NULL, NULL, a->from, 0); + gwlog_error_from("variable differs in {/}constness{0}", NULL, a->from, 0); error = false; } if (GET_FLAG(a, static) && !GET_FLAG(b, static)) { - gwerr_basic_from("variable differs in {/}storage{0}", NULL, NULL, a->from, 0); + gwlog_error_from("variable differs in {/}storage{0}", NULL, a->from, 0); error = false; } if (error) return true; - gwerr_secondary_from("from requested variable", b->from); + gwlog_related_from("from requested variable", b->from); return error; } ANN static bool request_var(const Env env, const Type t, const Value request) { const Value value = nspc_lookup_value0(t->nspc, insert_symbol(request->name)); if (!value) { - gwerr_basic("missing requested variable", NULL, NULL, + gwlog_error("missing requested variable", NULL, request->from->filename, request->from->loc, 0); return false; } @@ -91,7 +91,7 @@ ANN static bool request_found(const Env env, const Type t, const Value v = nspc_lookup_value0(t->nspc, request->base->tag.sym); if (!v) return false; if (!is_func(env->gwion, v->type)) { - gwerr_basic_from("is not a function", NULL, NULL, v->from, 0); + gwlog_error_from("is not a function", NULL, v->from, 0); return false; } Func f = v->d.func_ref; @@ -149,10 +149,10 @@ ANN static bool request_fun(const Env env, const Type t, const Value parent = nspc_lookup_value1(env->global_nspc, request->base->tag.sym); if(parent) { const Value v = nspc_lookup_value1(env->curr, request->base->tag.sym); - gwerr_basic_from("is missing {+G}global{0}", NULL, NULL, v->from, 0); - gwerr_secondary("from requested func", env->name, request->base->tag.loc); + gwlog_error_from("is missing {+G}global{0}", NULL, v->from, 0); + gwlog_related("from requested func", env->name, request->base->tag.loc); env_set_error(env, true); - } else gwerr_basic("missing requested function", NULL, NULL, env->name, + } else gwlog_error("missing requested function", NULL, env->name, request->base->tag.loc, 0); return false; } @@ -186,13 +186,13 @@ ANN bool check_trait_requests(const Env env, const Type t, const ID_List list, c const Symbol xid = *mp_vector_at(list, Symbol, i); const Trait trait = nspc_lookup_trait1(env->curr, xid); if (!trait_nodup(list, i)) { - gwerr_secondary_from("class has duplicated trait", from); + gwlog_warning_from("class has duplicated trait", from); return trait_error(env); } if (trait->var ? check_trait_variables(env, t, trait) : false || trait->fun ? check_trait_functions(env, t, trait) : false) { - gwerr_secondary("in trait", trait->filename, trait->loc); - gwerr_secondary("requested here", from->filename, from->loc); + gwlog_warning("in trait", trait->filename, trait->loc); + gwlog_related_from("requested here", from); return trait_error(env); } } diff --git a/src/parse/did_you_mean.c b/src/parse/did_you_mean.c index a4d4a6de..bf750d6c 100644 --- a/src/parse/did_you_mean.c +++ b/src/parse/did_you_mean.c @@ -55,7 +55,7 @@ ANN static void trait_ressembles(const Scope scope, const char *name, gw_err("{-/}did you mean{0}:\n"); } if (trait->filename) // TODO: check why is that from check - gwerr_secondary(_("defined here"), trait->filename, trait->loc); + gwlog_related(_("defined here"), trait->filename, trait->loc); } } } diff --git a/src/parse/func_resolve_tmpl.c b/src/parse/func_resolve_tmpl.c index a8d21e8a..0d4fd036 100644 --- a/src/parse/func_resolve_tmpl.c +++ b/src/parse/func_resolve_tmpl.c @@ -109,9 +109,9 @@ ANN static Func create_tmpl(const Env env, struct ResolverArgs *ra, sprintf(c, "arg%u", idx); TmplArg targ = *mp_vector_at(ra->types, TmplArg, idx); if(targ.type != tmplarg_td) { - gwerr_basic("invalid const expression in variadic template", NULL, "can't use expression in spread", env->name, targ.d.exp->loc, 0); + gwlog_error("invalid const expression in variadic template", "can't use expression in spread", env->name, targ.d.exp->loc, 0); Specialized *spec = mp_vector_at(value->d.func_ref->def->base->tmpl->list, Specialized, value->d.func_ref->def->base->tmpl->list->len - 1); - gwerr_secondary("spread starts here", env->name, spec->tag.loc); + gwlog_related("spread starts here", env->name, spec->tag.loc); env_set_error(env, true); return NULL; } diff --git a/src/parse/operator.c b/src/parse/operator.c index 247db224..3ee1a120 100644 --- a/src/parse/operator.c +++ b/src/parse/operator.c @@ -352,7 +352,8 @@ ANN Type op_check(const Env env, struct Op_Import *opi) { return opi->rhs; if (!strcmp(op, "@func_check")) return NULL; if(!strcmp(op, "=>") && !strcmp(opi->rhs->name, "@now")) { - gwerr_basic(_("no match found for operator"), "expected duration", "did you try converting to `dur`?", env->name, opi->loc, 0); + gwlog_error(_("no match found for operator"), "expected duration", env->name, opi->loc, 0); + gwlog_hint(_("did you try converting to `dur`?"), env->name, opi->loc); env_set_error(env, true); } else if (strcmp(op, "@implicit")) { if (opi->rhs && opi->lhs && is_func(env->gwion, opi->rhs)) { // is_callable diff --git a/src/parse/partial.c b/src/parse/partial.c index cc3a76a9..f96893a3 100644 --- a/src/parse/partial.c +++ b/src/parse/partial.c @@ -151,7 +151,8 @@ ANN static Func partial_match(const Env env, const Func up, Exp* args, const loc if(next) { const Type tnext = next->value_ref->from->owner_class; if(!t || !tnext || !isa(t, tnext)) { - gwerr_basic(_("can't resolve ambiguity"), _("in this partial application"), _("use typed holes: _ $ type"), env->name, loc, 0); + gwlog_error(_("can't resolve ambiguity"), _("in this partial application"), env->name, loc, 0); + gwlog_hint(_("use typed holes: `_ $ type`"), env->name, loc); gw_err(_("\nthose functions could match:\n")); print_signature(f); ambiguity(env, next, args, loc); diff --git a/src/parse/scan0.c b/src/parse/scan0.c index ab98f37a..5a52787f 100644 --- a/src/parse/scan0.c +++ b/src/parse/scan0.c @@ -335,7 +335,7 @@ ANN static bool find_traits(const Env env, ID_List traits, const loc_t loc) { for(uint32_t i = 0; i < traits->len; i++) { Symbol xid = *mp_vector_at(traits, Symbol, i); if (!nspc_lookup_trait1(env->curr, xid)) { - gwerr_basic(_("can't find trait"), NULL, NULL, env->name, loc, 0); + gwlog_error(_("can't find trait"), NULL, env->name, loc, 0); did_you_mean_trait(env->curr, s_name(xid)); env_set_error(env, true); POISON(ok, env); @@ -348,7 +348,7 @@ ANN static Type scan0_class_def_init(const Env env, const Class_Def cdef) { CHECK_O(scan0_defined(env, cdef->base.tag)); DECL_O(const Type, parent, = cdef_parent(env, cdef)); if(GET_FLAG(cdef, global) && !isa(parent, env->gwion->type[et_closure]) && !type_global(env, parent)) { - gwerr_basic(_("parent type is not global"), NULL, NULL, env->name, cdef->base.ext ? cdef->base.ext->tag.loc : cdef->base.tag.loc, 0); + gwlog_error(_("parent type is not global"), NULL, env->name, cdef->base.ext ? cdef->base.ext->tag.loc : cdef->base.tag.loc, 0); declared_here(parent->info->value); env_set_error(env, true); return NULL; @@ -412,8 +412,8 @@ ANN static bool scan0_extend_def(const Env env, const Extend_Def xdef) { const Trait global = nspc_lookup_trait1(env->global_nspc, xid); if(!global) { const Trait trait = nspc_lookup_trait1(env->curr, xid); - gwerr_basic("trait should be declared global", NULL, NULL, trait->filename, trait->loc, 0); - gwerr_secondary("from the request ", env->name, xdef->td->tag.loc); + gwlog_error("trait should be declared global", NULL, trait->filename, trait->loc, 0); + gwlog_related("from the request ", env->name, xdef->td->tag.loc); env_set_error(env, true); POISON(ok, env); } @@ -464,8 +464,8 @@ ANN static bool scan0_trait_def(const Env env, const Trait_Def pdef) { const Symbol s = pdef->tag.sym; const Trait exists = nspc_lookup_trait1(env->curr, s); if (exists) { - gwerr_basic("trait already defined", NULL, NULL, env->name, pdef->tag.loc, 0); - gwerr_secondary("defined here", env->name, exists->loc); + gwlog_error("trait already defined", NULL, env->name, pdef->tag.loc, 0); + gwlog_related("defined here", env->name, exists->loc); env_set_error(env, true); return can_define(env, s, pdef->tag.loc); } diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 094f1784..122a6b33 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -44,10 +44,10 @@ ANN static bool check_global(const Env env, const Type t, const loc_t loc) { if(from_global_nspc(env, from->owner) || (from->owner_class && type_global(env, from->owner_class))) return true; - gwerr_basic("can't use non-global type in a global class", NULL, NULL, env->name, loc, 0); - gwerr_secondary_from("not declared global", from); + gwlog_error("can't use non-global type in a global class", NULL, env->name, loc, 0); + gwlog_related_from("not declared global", from); const ValueFrom *ownerFrom = env->class_def->info->value->from; - gwerr_secondary_from("is global", ownerFrom); + gwlog_related_from("is global", ownerFrom); env_set_error(env, true); return false; } @@ -320,7 +320,7 @@ ANN static inline bool stmt_each_defined(const restrict Env env, ANN static inline bool shadow_err(const Env env, const Value v, const loc_t loc) { if(env->scope->shadowing) return true; - gwerr_basic(_("shadowing a previously defined variable"), NULL, NULL, + gwlog_error(_("shadowing a previously defined variable"), NULL, env->name, loc, 0); defined_here(v); env_set_error(env, true); @@ -774,9 +774,12 @@ ANN static bool _scan1_func_def(const Env env, const Func_Def fdef) { !fake.memoize) ERR_B(fdef->base->td->tag.loc, _("missing return statement in a non void function")); + // check gack is called. + // there **may** be a better way using effects if (fdef->base->tag.sym == insert_symbol("@gack") && !fake.weight) { - gwerr_basic(_("`@gack` operator does not print anything"), NULL, - _("use `<<<` `>>>` in the function"), env->name, fdef->base->tag.loc, 0); + gwlog_error(_("`@gack` operator does not print anything"), NULL, + env->name, fdef->base->tag.loc, 0); + gwlog_hint(_("use `<<<` `>>>` in the function"), env->name, fdef->base->tag.loc); env_set_error(env, true); return false; } diff --git a/src/parse/template.c b/src/parse/template.c index 71db9389..bbe51d68 100644 --- a/src/parse/template.c +++ b/src/parse/template.c @@ -107,9 +107,9 @@ ANN bool const_generic_typecheck(const Env env, const Specialized *spec, const T if(!isa(targ->d.exp->type, target)) { char msg[256]; tcol_snprintf(msg, 255, "expected {G+}%s{0}", target->name); - gwerr_basic("invalid type for const generic argument", msg, NULL, env->name, spec->tag.loc, 0); + gwlog_error("invalid type for const generic argument", msg, env->name, spec->tag.loc, 0); tcol_snprintf(msg, 255, "got {G+}%s{0}", targ->d.exp->type->name); - gwerr_secondary(msg, env->name, targ->d.exp->loc); + gwlog_related(msg, env->name, targ->d.exp->loc); return false; } return true; diff --git a/src/sema/sema.c b/src/sema/sema.c index bef5c35e..e56faad1 100644 --- a/src/sema/sema.c +++ b/src/sema/sema.c @@ -25,8 +25,8 @@ ANN static bool unique_expression(Sema *a, Exp *b, const char *ctx) { const bool ok = sema_exp(a, b); if(!b->next) return true && ok; - gwerr_basic("can't use multiple expressions", ctx, - NULL, a->filename, b->next->loc, 0); + gwlog_error("can't use multiple expressions", ctx, + a->filename, b->next->loc, 0); return false; } @@ -35,8 +35,8 @@ ANN static bool array_not_empty(Sema *a, Array_Sub b, const char *ctx, const loc_t loc) { if(b->exp) return true; - gwerr_basic(_("must provide values/expressions for array [...]"), - ctx, NULL, a->filename, loc, 0); + gwlog_error(_("must provide values/expressions for array [...]"), + ctx, a->filename, loc, 0); return false; } @@ -45,8 +45,8 @@ ANN static bool array_empty(Sema *a, Array_Sub b, const char *ctx, const loc_t loc) { if(!b->exp) return true; - gwerr_basic(_("array must be empty []"), - ctx, NULL, a->filename, loc, 0); + gwlog_error(_("array must be empty []"), + ctx, a->filename, loc, 0); return false; } @@ -272,10 +272,9 @@ ANN static bool sema_stmt_until(Sema *a, Stmt_Flow b) { ANN static bool sema_stmt_for(Sema *a, Stmt_For b) { bool ok = sema_stmt(a, b->c1, false); if (!b->c2 || !b->c2->d.stmt_exp.val) { - gwerr_basic( + gwlog_error( _("empty for loop condition..."), _("...(note: explicitly use 'true' if it's the intent)"), - _("...(e.g., 'for(; true;){{ /*...*/ }')"), a->filename, stmt_self(b)->loc, 0); ok = false; } else if(!sema_stmt(a, b->c2, false)) @@ -327,12 +326,12 @@ ANN static bool sema_stmt_continue(Sema *a, Stmt_Index b) { ANN static bool sema_stmt_return(Sema *a, Stmt_Exp b) { bool ok = true; if(!a->func) { - gwerr_basic("'return' statement found outside function definition", NULL, NULL, a->filename, stmt_self(b)->loc, 0); + gwlog_error("'return' statement found outside function definition", NULL, a->filename, stmt_self(b)->loc, 0); POISON(a, stmt_self(b)); ok = false; } if(a->in_defer) { - gwerr_basic("'return' statement in defered action", NULL, NULL, a->filename, stmt_self(b)->loc, 0); + gwlog_error("'return' statement in defered action", NULL, a->filename, stmt_self(b)->loc, 0); POISON(a, stmt_self(b)); ok = false; } @@ -382,7 +381,7 @@ ANN static bool sema_stmt_pp(Sema *a, Stmt_PP b) { ANN static bool sema_stmt_retry(Sema *a NUSED, Stmt_Exp b NUSED) { if(a->handling) return true; - gwerr_basic("`retry` outside of `handle` block", NULL, NULL, a->filename, stmt_self(b)->loc, 0); + gwlog_error("`retry` outside of `handle` block", NULL, a->filename, stmt_self(b)->loc, 0); return false; } @@ -391,12 +390,12 @@ ANN static bool sema_handler(Sema *a, Handler *b, ID_List *tags) { for(uint32_t i = 0; i < (*tags)->len; i++) { Tag *tag = mp_vector_at(*tags, Tag, i); if(!tag->sym && b->tag.sym) { - gwerr_basic("named handler after a catch-all one", NULL, NULL, a->filename, b->tag.loc, 0); - gwerr_secondary("catch-all used here", a->filename, b->tag.loc); + gwlog_error("named handler after a catch-all one", NULL, a->filename, b->tag.loc, 0); + gwlog_related("catch-all used here", a->filename, b->tag.loc); ok = false; } else if(b->tag.sym == tag->sym) { - gwerr_basic("duplicate handler tag", NULL, NULL, a->filename, b->tag.loc, 0); - gwerr_secondary("handler used here", a->filename, b->tag.loc); + gwlog_error("duplicate handler tag", NULL, a->filename, b->tag.loc, 0); + gwlog_related("handler used here", a->filename, b->tag.loc); ok = false; } } @@ -508,7 +507,7 @@ ANN static Stmt_List spread_to_stmt_list(Sema *a, const Spread_Def spread) { free_mp_vector(a->mp, Section, ast); return stmt_list; } - gwerr_basic(_("invalid spread section"), NULL, NULL, a->filename, spread->tag.loc, 0); + gwlog_error(_("invalid spread section"), NULL, a->filename, spread->tag.loc, 0); free_ast(a->mp, ast); return NULL; } @@ -518,7 +517,7 @@ ANN static bool sema_stmt_spread(Sema *a, Spread_Def b) { if(!a->tmpls) { if(a->in_variadic) return sema_spread(a, b, NULL); else { - gwerr_basic(_("spread statement outside of variadic environment"), NULL, NULL, + gwlog_error(_("spread statement outside of variadic environment"), NULL, a->filename, b->tag.loc, 0); return false; } @@ -584,7 +583,7 @@ ANN static bool sema_arg(Sema *a, Arg *b, const bool no_default) { ok = false; if (b->exp) { if(no_default) { - gwerr_basic("'default' argument not allowed", NULL, NULL, a->filename, b->var.vd.tag.loc, 0); + gwlog_error("'default' argument not allowed", NULL, a->filename, b->var.vd.tag.loc, 0); ok = false; } if(!unique_expression(a, b->exp, "in argument list")) @@ -599,14 +598,14 @@ ANN static bool sema_arg_list(Sema *a, Arg_List b, for(uint32_t i = 0; i < b->len; i++) { Arg *c = mp_vector_at(b, Arg, i); if(!c->var.vd.tag.sym && arg_needs_sym) { - gwerr_basic("argument needs name", NULL, NULL, a->filename, c->var.vd.tag.loc, 0); + gwlog_error("argument needs name", NULL, a->filename, c->var.vd.tag.loc, 0); ok = false; } if(!sema_arg(a, c, no_default)) ok = false; if(c->exp) *has_default = true; else if(*has_default) { - gwerr_basic("missing default argument", NULL, NULL, a->filename, c->var.vd.tag.loc, 0); + gwlog_error("missing default argument", NULL, a->filename, c->var.vd.tag.loc, 0); ok = false; } } @@ -647,12 +646,12 @@ ANN static bool fill(Sema *a, const Tmpl *tmpl) { for(uint32_t i = tmpl->list->len - 1; i < tmpl->call->len; i++) { TmplArg targ = *mp_vector_at(tmpl->call, TmplArg, i); if(targ.type != tmplarg_td) { - gwerr_basic("invalid const expression in variadic template", NULL, + gwlog_error("invalid const expression in variadic template", "can't use expression in spread", a->filename, targ.d.exp->loc, 0); Specialized *spec = mp_vector_at(tmpl->list, Specialized, tmpl->list->len - 1); - gwerr_secondary("spread starts here", a->filename, spec->tag.loc); + gwlog_related("spread starts here", a->filename, spec->tag.loc); ok = false; } mp_vector_add(a->mp, &a->tmpls, Type_Decl*, targ.d.td); @@ -750,7 +749,7 @@ ANN static bool sema_union_def(Sema *a, Union_Def b) { if(!sema_tmpl(a, b->tmpl)) ok = false; if(is_spread_tmpl(b->tmpl)) { - gwerr_basic(_("unions can't be variadic"), NULL, NULL, + gwlog_error(_("unions can't be variadic"), NULL, a->filename, b->tag.loc, 0); ok = false; } @@ -825,12 +824,12 @@ ANN static bool ext_fill(const Gwion gwion, MP_Vector **vec, const Tmpl *tmpl) { for(uint32_t i = tmpl->list->len - 1; i < tmpl->call->len; i++) { TmplArg targ = *mp_vector_at(tmpl->call, TmplArg, i); if(targ.type != tmplarg_td) { - gwerr_basic("invalid const expression in variadic template", NULL, + gwlog_error("invalid const expression in variadic template", "can't use expression in spread", gwion->env->name, targ.d.exp->loc, 0); Specialized *spec = mp_vector_at(tmpl->list, Specialized, tmpl->list->len - 1); - gwerr_secondary("spread starts here", gwion->env->name, spec->tag.loc); + gwlog_related("spread starts here", gwion->env->name, spec->tag.loc); return false; } mp_vector_add(gwion->mp, vec, Type_Decl*, targ.d.td); diff --git a/src/vm/vm.c b/src/vm/vm.c index c13e9b81..7c8c7800 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -120,7 +120,7 @@ ANN static void trace(VM_Shred shred, const m_uint size) { } loc_t loc = {.first = {.line = line, .column = 1}, .last = {.line = line, .column = 1}}; - gwerr_secondary("called from here", code_name(shred->code->name, true), loc); + gwlog_related("called from here", code_name(shred->code->name, true), loc); gw_err(" {M}┗━╸{0} {-}in code{0} {+W}%s{0}{-}:{0}\n", shred->code->name); if (shred->mem == (m_bit *)shred + sizeof(struct VM_Shred_) + SIZEOF_REG) return; -- 2.43.0