]> Nishi Git Mirror - gwion.git/commitdiff
:art: more on errors
authorfennecdjay <fennecdjay@gmail.com>
Fri, 22 Mar 2024 15:33:10 +0000 (16:33 +0100)
committerfennecdjay <fennecdjay@gmail.com>
Fri, 22 Mar 2024 15:33:10 +0000 (16:33 +0100)
22 files changed:
include/env/value.h
include/gwion.h
include/gwion_env.h
include/sema_private.h
src/env/env_utils.c
src/gwion.c
src/lib/array.c
src/lib/closure.c
src/lib/instr.c
src/lib/object_op.c
src/lib/prim.c
src/parse/check.c
src/parse/check_traits.c
src/parse/did_you_mean.c
src/parse/func_resolve_tmpl.c
src/parse/operator.c
src/parse/partial.c
src/parse/scan0.c
src/parse/scan1.c
src/parse/template.c
src/sema/sema.c
src/vm/vm.c

index 10c29fd4571c9fab143ede61c3cb2c10719fe170..6ba5613f71044a7feb2fb8e5ec50866b8bace07c 100644 (file)
@@ -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);
index 8675fa53ff4acd376173f748f70cdff8d87840b5..7c6a09152a09d8025b20fed1dd59aebce8481f24 100644 (file)
@@ -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*);
index 387024d5979f105fe197ded2887a88889d72c618..cf17aa7d62efc13ed8fab02e54da66761f523a17 100644 (file)
 #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
 
index a98a6ea448ba53e6aaf1d810ba6ec5fd678e233d..96b50060f09a8f8cc240b94447622519d05ae9d1 100644 (file)
@@ -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;
index d82ccaf6798528cccfd25c3cb67bbbdc24fd5fd1..4c59b4928577dbe11158752b51a81b92de535191 100644 (file)
@@ -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;
 }
index 8b362e57acf328f57bfd9569ea4a7a425f215475..a614bda86541e6e85b557d808b2bb441d8504a7e 100644 (file)
@@ -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
 }
 
index 6910dfd8927d7f33c628c16557e9fa1a63948ba1..cf399a26890c9863f0015501cbc874c22172bcb6 100644 (file)
@@ -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;
 }
index 69d7b736ca00e435db2889ba3f676c1bd2618075..54951c572dd3aafdfcc546f56b4ccf6f831300fc 100644 (file)
@@ -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);
index 5d1b9cb4467945f02b2dc24c03263452ef214813..97e68acd0107575f9a1eda0118fc7de9b1b7cbe6 100644 (file)
@@ -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");
 }
index 04fb501b80a6d837f202606805d2e7b829ef4c43..4e3446376f122abaee4f6487dd2f95dc0e669f0a 100644 (file)
@@ -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);
index 1c998d6eea68a94088a2b61c890e6faddd3d66b5..32eaad495eb6ad86d499e1ae6c4715da51aafb35 100644 (file)
@@ -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];
index 56945468070f6223ef8c0e7c2dfe4edb0107cfb9..17106ef1440a07392bab2bb1c0e31a46ff93d703 100644 (file)
@@ -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 : "<Unknown>");
   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);
index 019d56d2e89556afe77e341f66e80ca10c9f2075..c3d14e4ac5da8876a031eeac81ad129a0b5c3a61 100644 (file)
 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);
     }
   }
index a4d4a6dec46ac512f10e555bf74bff39e1d34d3c..bf750d6ca329134f1a3e358d058531671fab38bd 100644 (file)
@@ -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);
     }
   }
 }
index a8d21e8a6294ad72994c616c08f2d24f76d201ba..0d4fd036392b6c68cc595f59c204a1dba6f2e31d 100644 (file)
@@ -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;
       }
index 247db224cab581c094bff15a94eee5af1a2a31de..3ee1a1207e52f1877ab1ca6a2e83db10bd32a6d5 100644 (file)
@@ -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
index cc3a76a98f59b8c6d8f407929d04ff1c3663d209..f96893a328620e67d8d74006f0e49aceb17fc88c 100644 (file)
@@ -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);
index ab98f37ac1be996f7e2a66101683cab5261b7e7d..5a52787fc8e02fc887e19d541950204f97772b84 100644 (file)
@@ -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);
   }
index 094f1784d3dd5ea4dfd0f6b14d7d3b4416ed2df0..122a6b330b7c5a59e32236ee334d24b283dbf65b 100644 (file)
@@ -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;
   }
index 71db9389283a4cead8824ed5b1b2ae7b22279ff3..bbe51d68f11de51bf4c284fb261cc4cc6169e952 100644 (file)
@@ -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;
index bef5c35eb8fe2433bc03149be1a70e7bdb5252e7..e56faad1f7b02568b0063825e05da369fbd480f0 100644 (file)
@@ -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);
index c13e9b819168f43029c548a6846df7271a487638..7c8c7800a4f44fc13780f6484b9ddbbba0c4fbd4 100644 (file)
@@ -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;