Skip to content

Commit

Permalink
🎨 more on errors
Browse files Browse the repository at this point in the history
  • Loading branch information
fennecdjay committed Mar 22, 2024
1 parent 2f1ebe9 commit c23fff6
Show file tree
Hide file tree
Showing 22 changed files with 127 additions and 115 deletions.
9 changes: 0 additions & 9 deletions include/env/value.h
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion include/gwion.h
Expand Up @@ -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*);
Expand Down
26 changes: 20 additions & 6 deletions include/gwion_env.h
Expand Up @@ -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

2 changes: 1 addition & 1 deletion include/sema_private.h
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/env/env_utils.c
Expand Up @@ -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;
}
Expand Down
4 changes: 2 additions & 2 deletions src/gwion.c
Expand Up @@ -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
}

Expand All @@ -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
}

Expand Down
12 changes: 7 additions & 5 deletions src/lib/array.c
Expand Up @@ -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];
Expand Down Expand Up @@ -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;
}
8 changes: 4 additions & 4 deletions src/lib/closure.c
Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions src/lib/instr.c
Expand Up @@ -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");
}
2 changes: 1 addition & 1 deletion src/lib/object_op.c
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/lib/prim.c
Expand Up @@ -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];
Expand Down
51 changes: 26 additions & 25 deletions src/parse/check.c
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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 : "<Unknown>");
while ((e = next_arg_exp(e)));
gw_err("\n");
Expand All @@ -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);
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
}
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit c23fff6

Please sign in to comment.