struct keyword {
byte *name;
int value;
+ enum keyword_scope scope;
};
#include "conf/keywords.h"
{
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));
+ global_root_scope = lp_allocz(kwlp, sizeof(*global_root_scope) * CFK__MAX);
for (const struct keyword *k = keyword_list; k->name; k++)
{
- struct symbol *sym = cf_new_symbol(global_root_scope, global_root_scope_pool, kwlp, k->name);
+ struct symbol *sym = cf_new_symbol(&global_root_scope[k->scope], global_root_scope_pool, kwlp, k->name);
sym->class = SYM_KEYWORD;
sym->keyword = k;
}
- global_root_scope->readonly = 1;
+ for (int s = 0; s < CFK__MAX; s++)
+ global_root_scope[s].readonly = 1;
}
ifs_head = ifs = push_ifs(NULL);
if (is_cli)
c->current_scope->next = config->root_scope;
else
- c->current_scope->next = global_root_scope;
+ c->current_scope->next = &global_root_scope[CFK_KEYWORDS];
}
/**
byte readonly:1; /* Do not add new symbols */
};
+enum keyword_scope {
+ CFK_KEYWORDS,
+ CFK_METHODS,
+ CFK__MAX
+};
+
extern struct sym_scope *global_root_scope;
struct bytestring {
%start config
-CF_KEYWORDS(DEFINE, ON, OFF, YES, NO, S, MS, US, PORT, VPN, MPLS, FROM)
+CF_KEYWORDS(DEFINE, ON, OFF, YES, NO, S, MS, US, PORT, VPN, MPLS, FROM, MAX, AS)
CF_GRAMMAR
m4_define(CF_DEFINES, `m4_divert(-1)')
# Keywords are translated to C initializers
-m4_define(CF_handle_kw, `m4_divert(1){ "m4_translit($1,[[A-Z]],[[a-z]])", $1 },
+m4_define(CF_handle_kw, `m4_divert(1){ "m4_translit($1,[[A-Z]],[[a-z]])", $1, CF_keywd_target },
m4_divert(-1)')
-m4_define(CF_keywd, `m4_ifdef([[CF_tok_$1]],,[[m4_define([[CF_tok_$1]],1)CF_handle_kw($1)]])')
-m4_define(CF_KEYWORDS, `CF_iterate([[CF_keywd]], [[$@]])DNL')
+m4_define(CF_keywd, `m4_ifdef([[CF_tok_]]CF_keywd_target[[_$1]],,[[m4_define([[CF_tok_]]CF_keywd_target[[_$1]],1)CF_handle_kw($1)]])')
+m4_define(CF_KEYWORDS, `m4_define([[CF_keywd_target]],CFK_KEYWORDS)CF_iterate([[CF_keywd]], [[$@]])DNL')
+m4_define(CF_METHODS, `m4_define([[CF_keywd_target]],CFK_METHODS)CF_iterate([[CF_keywd]], [[$@]])DNL')
m4_define(CF_KEYWORDS_EXCLUSIVE, `CF_KEYWORDS($@)')
# CLI commands generate keywords as well
m4_define(CF_keywd, `m4_ifdef([[CF_tok_$1]],,[[m4_define([[CF_tok_$1]],1)CF_append([[CF_kw_rule]],$1,[[ | ]])m4_define([[CF_toks]],CF_toks $1)]])')
m4_define(CF_KEYWORDS, `m4_define([[CF_toks]],[[]])CF_iterate([[CF_keywd]], [[$@]])m4_ifelse(CF_toks,,,%token<s>[[]]CF_toks
)DNL')
+m4_define(CF_METHODS, `m4_define([[CF_toks]],[[]])CF_iterate([[CF_keywd]], [[$@]])m4_ifelse(CF_toks,,,%token<s>[[]]CF_toks
+)DNL')
m4_define(CF_keywd2, `m4_ifdef([[CF_tok_$1]],,[[m4_define([[CF_tok_$1]],1)m4_define([[CF_toks]],CF_toks $1)]])')
m4_define(CF_KEYWORDS_EXCLUSIVE, `m4_define([[CF_toks]],[[]])CF_iterate([[CF_keywd2]], [[$@]])m4_ifelse(CF_toks,,,%token<s>[[]]CF_toks
static struct f_method_scope {
struct f_inst *object;
+ struct sym_scope scope;
} f_method_scope_stack[32];
static int f_method_scope_pos = -1;
cf_error("Too many nested method calls");
FM = (struct f_method_scope) {
.object = object,
+ .scope = {
+ .next = new_config->current_scope,
+ .hash = global_root_scope[CFK_METHODS].hash,
+ .active = 1,
+ .block = 1,
+ .readonly = 1,
+ },
};
+ new_config->current_scope = &FM.scope;
}
static inline void f_pop_method_scope(void)
{
ASSERT_DIE(f_method_scope_pos >= 0);
+
+ ASSERT_DIE(&FM.scope == new_config->current_scope);
+ new_config->current_scope = FM.scope.next;
+
f_method_scope_pos--;
}
CF_KEYWORDS_EXCLUSIVE(IN)
CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
ACCEPT, REJECT, ERROR,
- INT, BOOL, IP, TYPE, PREFIX, RD, PAIR, QUAD, EC, LC,
+ INT, BOOL, IP, PREFIX, RD, PAIR, QUAD, EC, LC,
SET, STRING, BYTESTRING, BGPMASK, BGPPATH, CLIST, ECLIST, LCLIST,
IF, THEN, ELSE, CASE,
FOR, DO,
TRUE, FALSE, RT, RO, UNKNOWN, GENERIC,
- FROM, GW, NET, MASK, PROTO, SOURCE, SCOPE, DEST, IFNAME, IFINDEX, WEIGHT, GW_MPLS, ONLINK,
+ FROM, GW, NET, PROTO, SOURCE, SCOPE, DEST, IFNAME, IFINDEX, WEIGHT, GW_MPLS, ONLINK,
PREFERENCE,
- ROA_CHECK, ASN, SRC, DST,
- IS_V4, IS_V6,
- LEN, MAXLEN,
- DATA, DATA1, DATA2,
+ ROA_CHECK,
DEFINED,
ADD, DELETE, RESET,
- PREPEND, FIRST, LAST, LAST_NONAGGREGATED,
- MIN, MAX,
+ PREPEND,
EMPTY,
FILTER, WHERE, EVAL, ATTRIBUTE,
FROM_HEX,
BT_ASSERT, BT_TEST_SUITE, BT_CHECK_ASSIGN, BT_TEST_SAME, FORMAT)
+CF_METHODS(IS_V4, TYPE, IP, RD, LEN, MAXLEN, ASN, SRC, DST, MASK,
+ FIRST, LAST, LAST_NONAGGREGATED, DATA, DATA1, DATA2, MIN, MAX,
+ EMPTY, PREPEND, ADD, DELETE, FILTER)
+
%nonassoc THEN
%nonassoc ELSE