0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-22 09:41:54 +00:00

Filter: Print instructions take only one value (simplification)

This commit is contained in:
Maria Matejka 2023-06-19 17:24:30 +02:00 committed by Ondrej Zajicek
parent 6d411fc7bd
commit fdd39c81bd
4 changed files with 37 additions and 31 deletions

View File

@ -374,7 +374,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
%nonassoc ELSE %nonassoc ELSE
%type <xp> cmds_int cmd_prep %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 term_dot_method method_name_cont %type <x> term term_bs cmd cmd_var cmds cmds_scoped constant constructor var var_list function_call symbol_value bgp_path_expr bgp_path bgp_path_tail term_dot_method method_name_cont
%type <fda> dynamic_attr %type <fda> dynamic_attr
%type <fsa> static_attr %type <fsa> static_attr
%type <f> filter where_filter %type <f> filter where_filter
@ -963,16 +963,6 @@ break_command:
| ERROR { $$ = F_ERROR; } | ERROR { $$ = F_ERROR; }
; ;
print_list: /* EMPTY */ { $$ = NULL; }
| term { $$ = $1; }
| term ',' print_list {
ASSERT($1);
ASSERT($1->next == NULL);
$1->next = $3;
$$ = $1;
}
;
var: var:
type symbol '=' term ';' { type symbol '=' term ';' {
struct symbol *sym = cf_define_symbol(new_config, $2, SYM_VARIABLE | $1, offset, f_new_var(sym_->scope)); struct symbol *sym = cf_define_symbol(new_config, $2, SYM_VARIABLE | $1, offset, f_new_var(sym_->scope));
@ -1049,23 +1039,14 @@ cmd:
| UNSET '(' dynamic_attr ')' ';' { | UNSET '(' dynamic_attr ')' ';' {
$$ = f_new_inst(FI_EA_UNSET, $3); $$ = f_new_inst(FI_EA_UNSET, $3);
} }
| break_command print_list ';' { | break_command var_list ';' {
struct f_inst *breaker = f_new_inst(FI_DIE, $1); $$ = f_print($2, !!$2, $1);
if ($2) {
struct f_inst *printer = f_new_inst(FI_PRINT, $2);
struct f_inst *flusher = f_new_inst(FI_FLUSH);
printer->next = flusher;
flusher->next = breaker;
$$ = printer;
} else
$$ = breaker;
} }
| PRINT print_list ';' { | PRINT var_list ';' {
$$ = f_new_inst(FI_PRINT, $2); $$ = f_print($2, 1, F_NOP);
$$->next = f_new_inst(FI_FLUSH);
} }
| PRINTN print_list ';' { | PRINTN var_list ';' {
$$ = f_new_inst(FI_PRINT, $2); $$ = f_print($2, 0, F_NOP);
} }
| function_call ';' { $$ = f_new_inst(FI_DROP_RESULT, $1); } | function_call ';' { $$ = f_new_inst(FI_DROP_RESULT, $1); }
| CASE term '{' switch_body '}' { | CASE term '{' switch_body '}' {

View File

@ -625,13 +625,12 @@
LINE(3,0); LINE(3,0);
} }
INST(FI_PRINT, 0, 0) { INST(FI_PRINT, 1, 0) {
NEVER_CONSTANT; NEVER_CONSTANT;
VARARG; ARG_ANY(1);
if (whati->varcount && !(fs->flags & FF_SILENT)) if (!(fs->flags & FF_SILENT))
for (uint i=0; i<whati->varcount; i++) val_format(&v1, &fs->buf);
val_format(&(vv(i)), &fs->buf);
} }
INST(FI_FLUSH, 0, 0) { INST(FI_FLUSH, 0, 0) {

View File

@ -97,6 +97,7 @@ void f_add_lines(const struct f_line_item *what, struct filter_iterator *fit);
struct filter *f_new_where(struct f_inst *); struct filter *f_new_where(struct f_inst *);
struct f_inst *f_for_cycle(struct symbol *var, struct f_inst *term, struct f_inst *block); struct f_inst *f_for_cycle(struct symbol *var, struct f_inst *term, struct f_inst *block);
struct f_inst *f_print(struct f_inst *vars, int flush, enum filter_return fret);
static inline struct f_dynamic_attr f_new_dynamic_attr(u8 type, enum f_type f_type, uint code) /* Type as core knows it, type as filters know it, and code of dynamic attribute */ static inline struct f_dynamic_attr f_new_dynamic_attr(u8 type, enum f_type f_type, uint code) /* Type as core knows it, type as filters know it, and code of dynamic attribute */
{ return (struct f_dynamic_attr) { .type = type, .f_type = f_type, .ea_code = code }; } /* f_type currently unused; will be handy for static type checking */ { return (struct f_dynamic_attr) { .type = type, .f_type = f_type, .ea_code = code }; } /* f_type currently unused; will be handy for static type checking */

View File

@ -75,6 +75,31 @@ f_for_cycle(struct symbol *var, struct f_inst *term, struct f_inst *block)
return ms->method->new_inst(term, loop_start); return ms->method->new_inst(term, loop_start);
} }
struct f_inst *
f_print(struct f_inst *vars, int flush, enum filter_return fret)
{
#define AX(...) do { struct f_inst *_tmp = f_new_inst(__VA_ARGS__); _tmp->next = output; output = _tmp; } while (0)
struct f_inst *output = NULL;
if (fret != F_NOP)
AX(FI_DIE, fret);
if (flush)
AX(FI_FLUSH);
while (vars)
{
struct f_inst *tmp = vars;
vars = vars->next;
tmp->next = NULL;
AX(FI_PRINT, tmp);
}
return output;
#undef AX
}
#define CA_KEY(n) n->name, n->fda.type #define CA_KEY(n) n->name, n->fda.type
#define CA_NEXT(n) n->next #define CA_NEXT(n) n->next
#define CA_EQ(na,ta,nb,tb) (!strcmp(na,nb) && (ta == tb)) #define CA_EQ(na,ta,nb,tb) (!strcmp(na,nb) && (ta == tb))