diff options
author | Maria Matejka <mq@ucw.cz> | 2023-06-16 17:35:37 +0200 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2023-09-12 16:19:33 +0200 |
commit | fc9d471b36b91429e5d86aa794716683a5281449 (patch) | |
tree | ffe1298e55f99f0d6198aa6836213006e6a0dd89 /conf/cf-lex.l | |
parent | 39f8f46d81203ebd6b976da56e83930f972dccab (diff) |
Filter: Methods rework
Methods can now be called as x.m(y), as long as x can have its type
inferred in config time. If used as a command, it modifies the object,
if used as a value, it keeps the original object intact.
Also functions add(x,y), delete(x,y), filter(x,y) and prepend(x,y) now
spit a warning and are considered deprecated.
It's also possible to call a method on a constant, see filter/test.conf
for examples like bgp_path = +empty+.prepend(1).
Inside instruction definitions (filter/f-inst.c), a METHOD_CONSTRUCTOR()
call is added, which registers the instruction as a method for the type
of its first argument. Each type has its own method symbol table and
filter parser switches between them based on the inferred type of the
object calling the method.
Also FI_CLIST_(ADD|DELETE|FILTER) instructions have been split to allow
for this method dispatch. With type inference, it's now possible.
Diffstat (limited to 'conf/cf-lex.l')
-rw-r--r-- | conf/cf-lex.l | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/conf/cf-lex.l b/conf/cf-lex.l index 9e52417a..c4760e40 100644 --- a/conf/cf-lex.l +++ b/conf/cf-lex.l @@ -54,7 +54,6 @@ struct keyword { byte *name; int value; - enum keyword_scope scope; }; #include "conf/keywords.h" @@ -80,7 +79,8 @@ static uint cf_hash(const byte *c); HASH_DEFINE_REHASH_FN(SYM, struct symbol) struct sym_scope *global_root_scope; -static pool *global_root_scope_pool; +pool *global_root_scope_pool; +linpool *global_root_scope_linpool; linpool *cfg_mem; @@ -557,7 +557,7 @@ check_eof(void) static inline void cf_swap_soft_scope(struct config *conf); -static struct symbol * +struct symbol * cf_new_symbol(struct sym_scope *scope, pool *p, struct linpool *lp, const byte *c) { if (scope->readonly) @@ -686,6 +686,8 @@ cf_lex_symbol(const char *data) cf_lval.i = -val; return ENUM; } + case SYM_METHOD: + return sym->method->arg_num ? CF_SYM_METHOD_ARGS : CF_SYM_METHOD_BARE; case SYM_VOID: return CF_SYM_UNDEFINED; default: @@ -693,6 +695,8 @@ cf_lex_symbol(const char *data) } } +void f_type_methods_register(void); + /** * cf_lex_init - initialize the lexer * @is_cli: true if we're going to parse CLI command, false for configuration @@ -707,18 +711,19 @@ cf_lex_init(int is_cli, struct config *c) if (!global_root_scope_pool) { global_root_scope_pool = rp_new(&root_pool, "Keywords pool"); - linpool *kwlp = lp_new(global_root_scope_pool); - global_root_scope = lp_allocz(kwlp, sizeof(*global_root_scope) * CFK__MAX); + global_root_scope_linpool = lp_new(global_root_scope_pool); + global_root_scope = lp_allocz(global_root_scope_linpool, sizeof(*global_root_scope)); for (const struct keyword *k = keyword_list; k->name; k++) { - struct symbol *sym = cf_new_symbol(&global_root_scope[k->scope], global_root_scope_pool, kwlp, k->name); + struct symbol *sym = cf_new_symbol(global_root_scope, global_root_scope_pool, global_root_scope_linpool, k->name); sym->class = SYM_KEYWORD; sym->keyword = k; } - for (int s = 0; s < CFK__MAX; s++) - global_root_scope[s].readonly = 1; + global_root_scope->readonly = 1; + + f_type_methods_register(); } ifs_head = ifs = push_ifs(NULL); @@ -742,7 +747,7 @@ cf_lex_init(int is_cli, struct config *c) if (is_cli) c->current_scope->next = config->root_scope; else - c->current_scope->next = &global_root_scope[CFK_KEYWORDS]; + c->current_scope->next = global_root_scope; } /** |