describe_nspc_func(Type, type)
describe_nspc_func(Func, func)
/* howere there is no need for lookup_func0, push_func, pop_func */
+ANN void did_you_mean_nspc(const Nspc, const char*);
+ANN void did_you_mean_type(const Type, const char*);
#endif
if(!v || !GET_FLAG(v, checked)) {
env_err(env, exp_self(primary)->pos,
"variable %s not legit at this point.", s_name(primary->d.var));
- did_you_mean(env->gwion->st, s_name(primary->d.var));
+ if(v && v->owner_class)
+ did_you_mean_type(v->owner_class, s_name(primary->d.var));
+ else
+ did_you_mean_nspc(v ? v->owner : env->curr, s_name(primary->d.var));
return NULL;
}
if(env->func && !GET_FLAG(v, const) && v->owner)
ERR_O(exp_self(member)->pos,
"keyword 'this' must be associated with object instance...")
const Value value = find_value(the_base, member->xid);
- if(!value)
- ERR_O(member->base->pos,
- "class '%s' has no member '%s'", the_base->name, str)
+ if(!value) {
+ env_err(env, member->base->pos,
+ "class '%s' has no member '%s'", the_base->name, str);
+ did_you_mean_type(member->t_base, str);
+ return NULL;
+ }
if(!env->class_def || isa(env->class_def, value->owner_class) < 0) {
if(GET_FLAG(value, private))
ERR_O(exp_self(member)->pos,
--- /dev/null
+//#include <stdlib.h>
+#include <string.h>
+#include "gwion_util.h"
+#include "gwion_ast.h"
+#include "oo.h"
+#include "nspc.h"
+#include "value.h"
+#include "env.h"
+#include "type.h"
+
+#ifdef min
+#undef min
+#endif
+
+#define MAX_DISTANCE 2
+#define min2(a, b) ((a) < (b) ? (a) : (b))
+#define min(a, b, c) (min2(min2((a), (b)), (c)))
+
+static m_bool wagner_fisher(const char *s, const char* t) {
+ const size_t m = strlen(s);
+ const size_t n = strlen(t);
+ unsigned int d[m][n];
+ uint i, j;
+ for(i = 0; i < m; ++i)
+ d[i][0] = i;
+ for(i = 0; i < n; ++i)
+ d[0][i] = i;
+ for(j = 1; j < n; ++j) {
+ for(i = 1; i < m; ++i) {
+ if(s[i] == t[j])
+ d[i][j] = d[i-1][j-1];
+ else
+ d[i][j] = min(d[i-1][j] + 1, d[i][j-1] + 1, d[i-1][j-1] + 1);
+ if(d[i][j] > MAX_DISTANCE + 1)
+ return 0;
+ }
+ }
+ return (i && j && d[m-1][n-1] < MAX_DISTANCE);
+}
+
+ANN static void ressembles(const Vector v, const Nspc nspc, const char* name) {
+ struct scope_iter iter = { &nspc->info->value, 0, 0 };
+ Value value;
+ while(scope_iter(&iter, &value) > 0) {
+ if(!strcmp(name, value->name))
+ continue;
+ if(wagner_fisher(name, value->name))
+ vector_add(v, (vtype)value->name);
+ }
+}
+
+ANN void did_you_mean_nspc(Nspc nspc, const char* name) {
+ struct Vector_ v;
+ vector_init(&v);
+ do ressembles(&v, nspc, name);
+ while((nspc = nspc->parent));
+ for(m_uint i = 0; i < vector_size(&v); ++i)
+ gw_err("\t(did you mean '%s'?)\n", (m_str)vector_at(&v, i));
+ vector_release(&v);
+}
+
+ANN void did_you_mean_type(Type type, const char* name) {
+ Type t = type;
+ struct Vector_ v;
+ vector_init(&v);
+ do ressembles(&v, t->nspc, name);
+ while((t = t->parent));
+ for(m_uint i = 0; i < vector_size(&v); ++i)
+ gw_err("\t(did you mean '%s'?)\n", (m_str)vector_at(&v, i));
+ did_you_mean_nspc(type->nspc, name);
+ vector_release(&v);
+}
#include "gwion_ast.h"
#include "oo.h"
#include "env.h"
+#include "nspc.h"
#include "type.h"
#include "vm.h"
#include "parse.h"
char path[id_list_len(id)];
type_path(path, id);
err_msg(id->pos, "unknown type '%s'", path);
- did_you_mean(env->gwion->st, s_name(id->xid));
+ did_you_mean_nspc(env->curr, s_name(id->xid));
return NULL;
}
-Subproject commit adc983bec96f51536b394816048fa7bfe3ccd7c7
+Subproject commit ed43d9d14df891ffd3b9ae09ac63ad2c9de4d24e