]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Filter: split out dot-notation methods to separate targets
authorMaria Matejka <mq@ucw.cz>
Mon, 12 Jun 2023 09:20:49 +0000 (11:20 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Tue, 12 Sep 2023 13:27:43 +0000 (15:27 +0200)
This is just a preparationary refactoring to allow type-based method
tables.

filter/config.Y

index fcdbb4a9df700735cd690b971f55002dd5d9763a..d6d96afc48fb418fa9466e8f98d7f28994431ffd 100644 (file)
@@ -19,8 +19,27 @@ static inline u32 pair(u32 a, u32 b) { return (a << 16) | b; }
 static inline u32 pair_a(u32 p) { return p >> 16; }
 static inline u32 pair_b(u32 p) { return p & 0xFFFF; }
 
-#define f_generate_complex(fi_code, da, arg) \
-  f_new_inst(FI_EA_SET, f_new_inst(fi_code, f_new_inst(FI_EA_GET, da), arg), da)
+static struct f_method_scope {
+  struct f_inst *object;
+} f_method_scope_stack[32];
+static int f_method_scope_pos = -1;
+
+#define FM  (f_method_scope_stack[f_method_scope_pos])
+
+static inline void f_push_method_scope(struct f_inst *object)
+{
+  if (++f_method_scope_pos >= (int) ARRAY_SIZE(f_method_scope_stack))
+    cf_error("Too many nested method calls");
+  FM = (struct f_method_scope) {
+    .object = object,
+  };
+}
+
+static inline void f_pop_method_scope(void)
+{
+  ASSERT_DIE(f_method_scope_pos >= 0);
+  f_method_scope_pos--;
+}
 
 static int
 f_new_var(struct sym_scope *s)
@@ -329,7 +348,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
 %nonassoc ELSE
 
 %type <xp> cmds_int cmd_prep
-%type <x> term term_bs cmd cmd_var cmds cmds_scoped constant constructor print_list var var_list function_call symbol_value bgp_path_expr bgp_path bgp_path_tail
+%type <x> term term_bs cmd cmd_var cmds cmds_scoped constant constructor print_list var var_list function_call symbol_value bgp_path_expr bgp_path bgp_path_tail method_cmd method_term
 %type <fda> dynamic_attr
 %type <fsa> static_attr
 %type <f> filter where_filter
@@ -806,6 +825,35 @@ static_attr:
  | ONLINK  { $$ = f_new_static_attr(T_BOOL,       SA_ONLINK,   0); }
  ;
 
+method_term:
+   IS_V4 { $$ = f_new_inst(FI_IS_V4, FM.object); }
+ | TYPE { $$ = f_new_inst(FI_TYPE, FM.object); }
+ | IP { $$ = f_new_inst(FI_IP, FM.object); }
+ | RD { $$ = f_new_inst(FI_ROUTE_DISTINGUISHER, FM.object); }
+ | LEN { $$ = f_new_inst(FI_LENGTH, FM.object); }
+ | MAXLEN { $$ = f_new_inst(FI_ROA_MAXLEN, FM.object); }
+ | ASN { $$ = f_new_inst(FI_ASN, FM.object); }
+ | SRC { $$ = f_new_inst(FI_NET_SRC, FM.object); }
+ | DST { $$ = f_new_inst(FI_NET_DST, FM.object); }
+ | MASK '(' term ')' { $$ = f_new_inst(FI_IP_MASK, FM.object, $3); }
+ | FIRST { $$ = f_new_inst(FI_AS_PATH_FIRST, FM.object); }
+ | LAST  { $$ = f_new_inst(FI_AS_PATH_LAST, FM.object); }
+ | LAST_NONAGGREGATED  { $$ = f_new_inst(FI_AS_PATH_LAST_NAG, FM.object); }
+ | DATA { $$ = f_new_inst(FI_PAIR_DATA, FM.object); }
+ | DATA1 { $$ = f_new_inst(FI_LC_DATA1, FM.object); }
+ | DATA2 { $$ = f_new_inst(FI_LC_DATA2, FM.object); }
+ | MIN  { $$ = f_new_inst(FI_MIN, FM.object); }
+ | MAX  { $$ = f_new_inst(FI_MAX, FM.object); }
+ ;
+
+method_cmd:
+   EMPTY               { $$ = f_const_empty(FM.object->i_FI_EA_GET.da); }
+ | PREPEND '(' term ')'        { $$ = f_new_inst(FI_PATH_PREPEND, FM.object, $3 ); }
+ | ADD '(' term ')'    { $$ = f_new_inst(FI_CLIST_ADD, FM.object, $3 ); }
+ | DELETE '(' term ')' { $$ = f_new_inst(FI_CLIST_DEL, FM.object, $3 ); }
+ | FILTER '(' term ')' { $$ = f_new_inst(FI_CLIST_FILTER, FM.object, $3 ); }
+ ;
+
 term:
    '(' term ')'                { $$ = $2; }
  | term '+' term       { $$ = f_new_inst(FI_ADD, $1, $3); }
@@ -833,32 +881,12 @@ term:
 
  | dynamic_attr { $$ = f_new_inst(FI_EA_GET, $1); }
 
- | term '.' IS_V4 { $$ = f_new_inst(FI_IS_V4, $1); }
- | term '.' TYPE { $$ = f_new_inst(FI_TYPE, $1); }
- | term '.' IP { $$ = f_new_inst(FI_IP, $1); }
- | term '.' RD { $$ = f_new_inst(FI_ROUTE_DISTINGUISHER, $1); }
- | term '.' LEN { $$ = f_new_inst(FI_LENGTH, $1); }
- | term '.' MAXLEN { $$ = f_new_inst(FI_ROA_MAXLEN, $1); }
- | term '.' ASN { $$ = f_new_inst(FI_ASN, $1); }
- | term '.' SRC { $$ = f_new_inst(FI_NET_SRC, $1); }
- | term '.' DST { $$ = f_new_inst(FI_NET_DST, $1); }
- | term '.' MASK '(' term ')' { $$ = f_new_inst(FI_IP_MASK, $1, $5); }
- | term '.' FIRST { $$ = f_new_inst(FI_AS_PATH_FIRST, $1); }
- | term '.' LAST  { $$ = f_new_inst(FI_AS_PATH_LAST, $1); }
- | term '.' LAST_NONAGGREGATED  { $$ = f_new_inst(FI_AS_PATH_LAST_NAG, $1); }
- | term '.' DATA { $$ = f_new_inst(FI_PAIR_DATA, $1); }
- | term '.' DATA1 { $$ = f_new_inst(FI_LC_DATA1, $1); }
- | term '.' DATA2 { $$ = f_new_inst(FI_LC_DATA2, $1); }
- | term '.' MIN  { $$ = f_new_inst(FI_MIN, $1); }
- | term '.' MAX  { $$ = f_new_inst(FI_MAX, $1); }
-
-/* Communities */
-/* This causes one shift/reduce conflict
- | dynamic_attr '.' ADD '(' term ')' { }
- | dynamic_attr '.' DELETE '(' term ')' { }
- | dynamic_attr '.' CONTAINS '(' term ')' { }
- | dynamic_attr '.' RESET{ }
-*/
+ | term '.' {
+     f_push_method_scope($1);
+   } method_term {
+     f_pop_method_scope();
+     $$ = $4;
+   }
 
  | '+' EMPTY '+' { $$ = f_const_empty_path; }
  | '-' EMPTY '-' { $$ = f_const_empty_clist; }
@@ -874,8 +902,6 @@ term:
 
  | FORMAT '(' term ')' {  $$ = f_new_inst(FI_FORMAT, $3); }
 
-/* | term '.' LEN { $$->code = P('P','l'); } */
-
  | term_bs
  | function_call
  ;
@@ -988,11 +1014,12 @@ cmd:
       $$ = f_new_inst(FI_SWITCH, $2, $4);
    }
 
- | dynamic_attr '.' EMPTY ';' { $$ = f_new_inst(FI_EA_SET, f_const_empty($1), $1); }
- | dynamic_attr '.' PREPEND '(' term ')' ';'   { $$ = f_generate_complex( FI_PATH_PREPEND, $1, $5 ); }
- | dynamic_attr '.' ADD '(' term ')' ';'       { $$ = f_generate_complex( FI_CLIST_ADD, $1, $5 ); }
- | dynamic_attr '.' DELETE '(' term ')' ';'    { $$ = f_generate_complex( FI_CLIST_DEL, $1, $5 ); }
- | dynamic_attr '.' FILTER '(' term ')' ';'    { $$ = f_generate_complex( FI_CLIST_FILTER, $1, $5 ); }
+ | dynamic_attr '.' {
+     f_push_method_scope(f_new_inst(FI_EA_GET, $1));
+   } method_cmd ';' {
+     f_pop_method_scope();
+     $$ = f_new_inst(FI_EA_SET, $4, $1);
+   }
  | BT_ASSERT '(' get_cf_position term get_cf_position ')' ';' { $$ = assert_done($4, $3 + 1, $5 - 1); }
  | BT_CHECK_ASSIGN '(' get_cf_position lvalue get_cf_position ',' term ')' ';' { $$ = assert_assign(&$4, $7, $3 + 1, $5 - 1); }
  ;