aboutsummaryrefslogtreecommitdiffstats
path: root/filter/f-util.c
diff options
context:
space:
mode:
Diffstat (limited to 'filter/f-util.c')
-rw-r--r--filter/f-util.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/filter/f-util.c b/filter/f-util.c
index 98b7d1a8..7ce3f9c8 100644
--- a/filter/f-util.c
+++ b/filter/f-util.c
@@ -30,7 +30,8 @@ filter_name(const struct filter *filter)
return filter->sym->name;
}
-struct filter *f_new_where(struct f_inst *where)
+struct filter *
+f_new_where(struct f_inst *where)
{
struct f_inst *cond = f_new_inst(FI_CONDITION, where,
f_new_inst(FI_DIE, F_ACCEPT),
@@ -41,6 +42,43 @@ struct filter *f_new_where(struct f_inst *where)
return f;
}
+static inline int
+f_match_signature(const struct f_method *dsc, struct f_inst *args)
+{
+ uint i;
+
+ for (i = 1; args && (i < dsc->arg_num); args = args->next, i++)
+ if (dsc->args_type[i] && (args->type != dsc->args_type[i]))
+ return 0;
+
+ return !args && !(i < dsc->arg_num);
+}
+
+struct f_inst *
+f_dispatch_method(struct symbol *sym, struct f_inst *obj, struct f_inst *args)
+{
+ /* Note! We should revert args */
+
+ for (const struct f_method *dsc = sym->method; dsc; dsc = dsc->next)
+ if (f_match_signature(dsc, args))
+ return dsc->new_inst(obj, args);
+
+ cf_error("Cannot dispatch method '%s'", sym->name);
+}
+
+struct f_inst *
+f_dispatch_method_x(const char *name, enum f_type t, struct f_inst *obj, struct f_inst *args)
+{
+ struct sym_scope *scope = f_type_method_scope(t);
+ struct symbol *sym = cf_find_symbol_scope(scope, name);
+
+ if (!sym)
+ cf_error("Cannot dispatch method '%s'", name);
+
+ return f_dispatch_method(sym, obj, args);
+}
+
+
struct f_inst *
f_for_cycle(struct symbol *var, struct f_inst *term, struct f_inst *block)
{