diff options
Diffstat (limited to 'filter/f-util.c')
-rw-r--r-- | filter/f-util.c | 40 |
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) { |