CF_DECLS
+CF_KEYWORDS_EXCLUSIVE(IN)
CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
ACCEPT, REJECT, ERROR,
INT, BOOL, IP, TYPE, PREFIX, RD, PAIR, QUAD, EC, LC,
- SET, STRING, BGPMASK, BGPPATH, CLIST, ECLIST, LCLIST,
+ SET, STRING, BYTESTRING, BGPMASK, BGPPATH, CLIST, ECLIST, LCLIST,
IF, THEN, ELSE, CASE,
- FOR, IN, DO,
+ FOR, DO,
TRUE, FALSE, RT, RO, UNKNOWN, GENERIC,
- FROM, GW, NET, MASK, PROTO, SOURCE, SCOPE, DEST, IFNAME, IFINDEX, WEIGHT, GW_MPLS,
+ FROM, GW, NET, MASK, PROTO, SOURCE, SCOPE, DEST, IFNAME, IFINDEX, WEIGHT, GW_MPLS, ONLINK,
PREFERENCE,
ROA_CHECK, ASN, SRC, DST,
IS_V4, IS_V6,
MIN, MAX,
EMPTY,
FILTER, WHERE, EVAL, ATTRIBUTE,
+ FROM_HEX,
BT_ASSERT, BT_TEST_SUITE, BT_CHECK_ASSIGN, BT_TEST_SAME, FORMAT)
%nonassoc THEN
%nonassoc ELSE
%type <xp> cmds_int cmd_prep
-%type <x> term cmd cmd_var cmds cmds_scoped constant constructor print_list var var_init 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
%type <fda> dynamic_attr
%type <fsa> static_attr
%type <f> filter where_filter
conf: filter_eval ;
filter_eval:
- EVAL term { f_eval_int(f_linearize($2, 1)); }
+ EVAL term { cf_eval_int($2); }
;
conf: custom_attr ;
| EC { $$ = T_EC; }
| LC { $$ = T_LC; }
| STRING { $$ = T_STRING; }
+ | BYTESTRING { $$ = T_BYTESTRING; }
| BGPMASK { $$ = T_PATH_MASK; }
| BGPPATH { $$ = T_PATH; }
| CLIST { $$ = T_CLIST; }
| VPN_RD { $$.type = T_RD; $$.val.ec = $1; }
| ENUM { $$.type = pair_a($1); $$.val.i = pair_b($1); }
| '(' term ')' {
- if (f_eval(f_linearize($2, 1), cfg_mem, &($$)) > F_RETURN) cf_error("Runtime error");
+ $$ = cf_eval($2, T_VOID);
if (!f_valid_set_type($$.type)) cf_error("Set-incompatible type");
}
| CF_SYM_KNOWN {
switch_atom:
NUM { $$.type = T_INT; $$.val.i = $1; }
- | '(' term ')' { $$.type = T_INT; $$.val.i = f_eval_int(f_linearize($2, 1)); }
+ | '(' term ')' { $$ = cf_eval($2, T_INT); }
| fipa { $$ = $1; }
| ENUM { $$.type = pair_a($1); $$.val.i = pair_b($1); }
;
cnum:
- term { $$ = f_eval_int(f_linearize($1, 1)); }
+ term { $$ = cf_eval_int($1); }
pair_item:
'(' cnum ',' cnum ')' { $$ = f_new_pair_item($2, $2, $4, $4); }
| switch_body switch_items ':' cmds_scoped {
/* Fill data fields */
struct f_tree *t;
- struct f_line *line = f_linearize($4, 0);
for (t = $2; t; t = t->left)
- t->data = line;
+ t->data = $4;
$$ = f_merge_items($1, $2);
}
| switch_body ELSECOL cmds_scoped {
struct f_tree *t = f_new_tree();
t->from.type = t->to.type = T_VOID;
t->right = t;
- t->data = f_linearize($3, 0);
+ t->data = $3;
$$ = f_merge_items($1, t);
}
;
;
constant:
- NUM { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_INT, .val.i = $1, }); }
- | TRUE { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_BOOL, .val.i = 1, }); }
- | FALSE { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_BOOL, .val.i = 0, }); }
- | TEXT { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_STRING, .val.s = $1, }); }
- | fipa { $$ = f_new_inst(FI_CONSTANT, $1); }
- | VPN_RD { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_RD, .val.ec = $1, }); }
- | net_ { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_NET, .val.net = $1, }); }
+ NUM { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_INT, .val.i = $1, }); }
+ | TRUE { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_BOOL, .val.i = 1, }); }
+ | FALSE { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_BOOL, .val.i = 0, }); }
+ | TEXT { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_STRING, .val.s = $1, }); }
+ | BYTETEXT { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_BYTESTRING, .val.bs = $1, }); }
+ | fipa { $$ = f_new_inst(FI_CONSTANT, $1); }
+ | VPN_RD { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_RD, .val.ec = $1, }); }
+ | net_ { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_NET, .val.net = $1, }); }
| '[' ']' { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_SET, .val.t = NULL, }); }
| '[' set_items ']' {
DBG( "We've got a set here..." );
| WEIGHT { $$ = f_new_static_attr(T_INT, SA_WEIGHT, 0); }
| PREFERENCE { $$ = f_new_static_attr(T_INT, SA_PREF, 0); }
| GW_MPLS { $$ = f_new_static_attr(T_INT, SA_GW_MPLS, 0); }
+ | ONLINK { $$ = f_new_static_attr(T_BOOL, SA_ONLINK, 0); }
;
term:
/* | term '.' LEN { $$->code = P('P','l'); } */
+ | term_bs
| function_call
;
+term_bs:
+ FROM_HEX '(' term ')' { $$ = f_new_inst(FI_FROM_HEX, $3); }
+ ;
+
break_command:
ACCEPT { $$ = F_ACCEPT; }
| REJECT { $$ = F_REJECT; }
}
;
-var_init:
- /* empty */ { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { }); }
- | '=' term { $$ = $2; }
- ;
-
var:
- type symbol var_init ';' {
+ type symbol '=' term ';' {
struct symbol *sym = cf_define_symbol($2, SYM_VARIABLE | $1, offset, f_new_var(sym_->scope));
- $$ = f_new_inst(FI_VAR_INIT, $3, sym);
+ $$ = f_new_inst(FI_VAR_INIT, $4, sym);
}
+ | type symbol ';' {
+ struct symbol *sym = cf_define_symbol($2, SYM_VARIABLE | $1, offset, f_new_var(sym_->scope));
+ $$ = f_new_inst(FI_VAR_INIT0, sym);
+ }
+ ;
for_var:
type symbol { $$ = cf_define_symbol($2, SYM_VARIABLE | $1, offset, f_new_var(sym_->scope)); }
}
| function_call ';' { $$ = f_new_inst(FI_DROP_RESULT, $1); }
| CASE term '{' switch_body '}' {
- $$ = f_new_inst(FI_SWITCH, $2, build_tree($4));
+ $$ = f_new_inst(FI_SWITCH, $2, $4);
}
| dynamic_attr '.' EMPTY ';' { $$ = f_generate_empty($1); }