Update of filters towards new interface.
This commit is contained in:
parent
5bc512aa3a
commit
ba92164871
5 changed files with 123 additions and 107 deletions
15
bird.conf
15
bird.conf
|
@ -8,19 +8,11 @@ router id 62.168.0.1
|
|||
|
||||
define xyzzy = 120+10
|
||||
|
||||
function test() {
|
||||
int i;
|
||||
function startup () int i; { printdebug; printdebug; i = 5; print( i ); i = 1234 + i; print( i ); if 0 then { puts( "You must not ever see this" ); quitbird; } print( 2 ); if 1 then puts( "jedna dve honza jde" ); quitbird; }
|
||||
|
||||
filter testf int j; { j = const(4321); print( j ); }
|
||||
|
||||
printdebug;
|
||||
i = 5;
|
||||
print( i );
|
||||
printdebug;
|
||||
i = 1234;
|
||||
print( i );
|
||||
printdebug;
|
||||
}
|
||||
|
||||
/*
|
||||
protocol rip MyRIP_test {
|
||||
preference xyzzy
|
||||
debug all
|
||||
|
@ -29,7 +21,6 @@ protocol rip MyRIP_test {
|
|||
garbagetime 30
|
||||
interface "*"
|
||||
}
|
||||
*/
|
||||
|
||||
protocol device {
|
||||
disabled
|
||||
|
|
|
@ -58,10 +58,11 @@ struct symbol {
|
|||
#define SYM_PROTO 1
|
||||
#define SYM_NUMBER 2
|
||||
#define SYM_STAT 3 /* statement */
|
||||
#define SYM_VARIABLE_INT 4
|
||||
#define SYM_FUNCTION 5
|
||||
#define SYM_FILTER 6
|
||||
|
||||
#define SYM_VARIABLE 0x100 /* Reserved 0x100..0x1ff */
|
||||
|
||||
extern int conf_lino;
|
||||
|
||||
void cf_lex_init_tables(void);
|
||||
|
|
181
filter/config.Y
181
filter/config.Y
|
@ -18,29 +18,19 @@ CF_HDR
|
|||
|
||||
CF_DECLS
|
||||
|
||||
CF_KEYWORDS(FUNCTION, FILTER, PRINTDEBUG, INT, PRINT, CONST, VAR, PUTS, IF,
|
||||
ACCEPT, REJECT, ERROR, QUITBIRD)
|
||||
CF_KEYWORDS(FUNCTION, PRINTDEBUG, PRINT, CONST, PUTS,
|
||||
ACCEPT, REJECT, ERROR, QUITBIRD,
|
||||
INT, BOOL, IP, PREFIX, PAIR, SET, STRING,
|
||||
IF, THEN,
|
||||
FILTER
|
||||
)
|
||||
|
||||
%type <x> term
|
||||
%type <x> block
|
||||
%type <x> cmds
|
||||
%type <x> term block cmds cmd function_body
|
||||
%type <f> filter filter_body
|
||||
%type <i> type break_command
|
||||
|
||||
CF_GRAMMAR
|
||||
|
||||
CF_ADDTO(conf, function)
|
||||
function:
|
||||
FUNCTION SYM '(' ')' '{' cmds '}' {
|
||||
extern struct f_inst *autoexec_func;
|
||||
if ($2->class != SYM_VOID) cf_error("Symbol already defined" );
|
||||
$2->class = SYM_FUNCTION;
|
||||
$2->def = $6;
|
||||
if (!strcasecmp($2->name, "autoexec"))
|
||||
autoexec_func = $6;
|
||||
printf("Hmm, we've got one function here\n");
|
||||
}
|
||||
;
|
||||
|
||||
CF_ADDTO(conf, filter_def)
|
||||
filter_def:
|
||||
FILTER SYM filter_body {
|
||||
|
@ -52,11 +42,36 @@ filter_def:
|
|||
}
|
||||
;
|
||||
|
||||
type:
|
||||
INT { $$ = T_INT; }
|
||||
| BOOL { $$ = T_BOOL; }
|
||||
| IP { $$ = T_IP; }
|
||||
| PREFIX { $$ = T_PREFIX; }
|
||||
| PAIR { $$ = T_PAIR; }
|
||||
| STRING { $$ = T_STRING; }
|
||||
| type SET {
|
||||
switch ($1) {
|
||||
default:
|
||||
cf_error( "You can not create sets of this type\n" );
|
||||
case T_INT: case T_IP: case T_PREFIX: case T_PAIR:
|
||||
}
|
||||
$$ = $1 | T_SET;
|
||||
}
|
||||
;
|
||||
|
||||
decls: /* EMPTY */
|
||||
| type SYM ';' decls {
|
||||
if ($2->class != SYM_VOID) cf_error("Symbol already defined, can not use as variable\n" );
|
||||
$2->class = SYM_VARIABLE | $1;
|
||||
printf( "New variable %s type %x\n", $2->name, $1 );
|
||||
}
|
||||
;
|
||||
|
||||
filter_body:
|
||||
'{' cmds '}' {
|
||||
function_body {
|
||||
struct filter *f = cfg_alloc(sizeof(struct filter));
|
||||
f->name = NULL;
|
||||
f->root = $2;
|
||||
f->root = $1;
|
||||
$$ = f;
|
||||
}
|
||||
;
|
||||
|
@ -69,25 +84,42 @@ filter:
|
|||
| filter_body
|
||||
;
|
||||
|
||||
function_params:
|
||||
'(' decls ')' { printf( "Have function parameters\n" ); }
|
||||
;
|
||||
|
||||
function_body:
|
||||
decls '{' cmds '}' {
|
||||
$$ = $3;
|
||||
}
|
||||
;
|
||||
|
||||
CF_ADDTO(conf, function_def)
|
||||
function_def:
|
||||
FUNCTION SYM function_params function_body {
|
||||
extern struct f_inst *startup_func;
|
||||
if ($2->class != SYM_VOID) cf_error("Symbol already defined" );
|
||||
$2->class = SYM_FUNCTION;
|
||||
$2->def = $4;
|
||||
if (!strcasecmp($2->name, "startup"))
|
||||
startup_func = $4;
|
||||
printf("Hmm, we've got one function here - %s\n", $2->name);
|
||||
}
|
||||
;
|
||||
|
||||
/* Programs */
|
||||
|
||||
cmds:
|
||||
term {
|
||||
cmds: /* EMPTY */ { $$ = NULL; }
|
||||
| cmd cmds {
|
||||
if ($1) {
|
||||
$1->next = NULL;
|
||||
$1->next = $2;
|
||||
$$ = $1;
|
||||
} else $$ = NULL;
|
||||
}
|
||||
| term ';' cmds {
|
||||
if ($1) {
|
||||
$1->next = $3;
|
||||
$$ = $1;
|
||||
} else $$ = $3;
|
||||
} else $$ = $2;
|
||||
}
|
||||
;
|
||||
|
||||
block:
|
||||
term ';' {
|
||||
cmd {
|
||||
$$=$1;
|
||||
}
|
||||
| '{' cmds '}' {
|
||||
|
@ -96,31 +128,16 @@ block:
|
|||
;
|
||||
|
||||
term:
|
||||
/* EMPTY */ {
|
||||
$$ = NULL;
|
||||
}
|
||||
| term '+' term {
|
||||
term '+' term {
|
||||
$$ = f_new_inst();
|
||||
$$->code = '+';
|
||||
$$->arg1 = $1;
|
||||
$$->arg2 = $3;
|
||||
}
|
||||
| IF '(' term ')' block {
|
||||
$$ = f_new_inst();
|
||||
$$->code = '?';
|
||||
$$->arg1 = $3;
|
||||
$$->arg2 = $5;
|
||||
}
|
||||
| INT SYM {
|
||||
if ($2->class != SYM_VOID) cf_error("Symbol already defined, can not use as variable\n" );
|
||||
$2->class = SYM_VARIABLE_INT;
|
||||
printf( "New variable\n" );
|
||||
$$ = NULL;
|
||||
}
|
||||
| SYM {
|
||||
$$ = f_new_inst();
|
||||
switch ($1->class) {
|
||||
case SYM_VARIABLE_INT:
|
||||
case SYM_VARIABLE | T_INT:
|
||||
$$->code = 'i';
|
||||
$$->arg1 = &($1->aux);
|
||||
break;
|
||||
|
@ -128,73 +145,63 @@ term:
|
|||
cf_error("Can not use this class of symbol as variable" );
|
||||
}
|
||||
}
|
||||
| VAR '(' SYM ')' {
|
||||
| CONST '(' expr ')' {
|
||||
$$ = f_new_inst();
|
||||
switch ($3->class) {
|
||||
case SYM_VARIABLE_INT:
|
||||
$$->code = 'i';
|
||||
$$->arg1 = &($3->aux);
|
||||
break;
|
||||
default:
|
||||
cf_error("Can not use this class of symbol as variable" );
|
||||
}
|
||||
$$->code = 'c';
|
||||
$$->arg1 = $3;
|
||||
}
|
||||
| NUM {
|
||||
$$ = f_new_inst();
|
||||
$$->code = 'c';
|
||||
$$->arg1 = $1
|
||||
}
|
||||
| CONST '(' expr ')' {
|
||||
;
|
||||
|
||||
break_command:
|
||||
QUITBIRD { $$ = F_QUITBIRD }
|
||||
| ACCEPT { $$ = F_ACCEPT }
|
||||
| REJECT { $$ = F_REJECT }
|
||||
| ERROR { $$ = F_ERROR }
|
||||
;
|
||||
|
||||
cmd:
|
||||
IF term THEN block {
|
||||
$$ = f_new_inst();
|
||||
$$->code = 'c';
|
||||
$$->arg1 = $3;
|
||||
$$->code = '?';
|
||||
$$->arg1 = $2;
|
||||
$$->arg2 = $4;
|
||||
}
|
||||
| SYM '=' term {
|
||||
| SYM '=' term ';' {
|
||||
$$ = f_new_inst();
|
||||
printf( "Ook, we'll set value\n" );
|
||||
if ($1->class != SYM_VARIABLE_INT)
|
||||
cf_error( "You may only set variables\n" );
|
||||
if (($1->class & ~T_MASK) != SYM_VARIABLE)
|
||||
cf_error( "You may only set variables, and this is %x.\n", $1->class );
|
||||
$$->code = '=';
|
||||
$$->arg1 = $1;
|
||||
$$->arg2 = $3;
|
||||
}
|
||||
| PRINT '(' term ')' {
|
||||
| PRINT '(' term ')' ';' {
|
||||
$$ = f_new_inst();
|
||||
printf( "Ook, we'll print something\n" );
|
||||
$$->code = 'p';
|
||||
$$->arg1 = $3;
|
||||
$$->arg2 = NULL;
|
||||
}
|
||||
| PUTS '(' TEXT ')' {
|
||||
| PUTS '(' TEXT ')' ';' {
|
||||
$$ = f_new_inst();
|
||||
$$->code = 'd';
|
||||
$$->arg1 = $3;
|
||||
}
|
||||
| QUITBIRD {
|
||||
$$ = f_new_inst();
|
||||
$$->code = '!';
|
||||
(int) $$->arg1 = F_QUITBIRD;
|
||||
}
|
||||
| ACCEPT {
|
||||
$$ = f_new_inst();
|
||||
$$->code = '!';
|
||||
(int) $$->arg1 = F_ACCEPT;
|
||||
}
|
||||
| REJECT {
|
||||
$$ = f_new_inst();
|
||||
$$->code = '!';
|
||||
(int) $$->arg1 = F_REJECT;
|
||||
}
|
||||
| ERROR {
|
||||
$$ = f_new_inst();
|
||||
$$->code = '!';
|
||||
(int) $$->arg1 = F_ERROR;
|
||||
}
|
||||
| PRINTDEBUG {
|
||||
| PRINTDEBUG ';' {
|
||||
$$ = f_new_inst();
|
||||
$$->code = 'D';
|
||||
$$->arg1 = $$->arg2 = NULL;
|
||||
}
|
||||
}
|
||||
| break_command ';' {
|
||||
$$ = f_new_inst();
|
||||
$$->code = '!';
|
||||
(int) $$->arg1 = $1;
|
||||
}
|
||||
;
|
||||
|
||||
CF_END
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "conf/conf.h"
|
||||
#include "filter/filter.h"
|
||||
|
||||
struct f_inst *autoexec_func = NULL;
|
||||
struct f_inst *startup_func = NULL;
|
||||
|
||||
#define runtime(x) do { \
|
||||
log( L_ERR, x ); \
|
||||
|
@ -71,7 +71,7 @@ interpret(struct f_inst *what)
|
|||
switch (res.type = v2.type) {
|
||||
case T_VOID: runtime( "Can not assign void values" );
|
||||
case T_INT:
|
||||
if (sym->class != SYM_VARIABLE_INT)
|
||||
if (sym->class != (SYM_VARIABLE | T_INT))
|
||||
runtime( "Variable of bad type" );
|
||||
sym->aux = v2.val.i;
|
||||
break;
|
||||
|
@ -163,6 +163,9 @@ f_run(struct filter *filter, struct rte *rtein, struct rte **rteout)
|
|||
void
|
||||
filters_postconfig(void)
|
||||
{
|
||||
if (autoexec_func)
|
||||
interpret(autoexec_func);
|
||||
printf( "Launching startup function..." );
|
||||
if (startup_func)
|
||||
interpret(startup_func);
|
||||
printf( "done\n" );
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
@ -40,10 +40,24 @@ int f_run(struct filter *filter, struct rte *rtein, struct rte **rteout);
|
|||
#define F_ERROR 4
|
||||
#define F_QUITBIRD 5
|
||||
|
||||
/* Type numbers must be in 0..0xff range */
|
||||
#define T_MASK 0xff
|
||||
|
||||
/* Internal types */
|
||||
#define T_VOID 0
|
||||
#define T_RETURN 1
|
||||
#define T_INT 10
|
||||
#define T_PX 11 /* prefix */
|
||||
#define T_INTLIST 12
|
||||
|
||||
/* User visible types, which fit in int */
|
||||
#define T_INT 0x10
|
||||
#define T_BOOL 0x11
|
||||
#define T_PAIR 0x12
|
||||
#define T_ENUM 0x13
|
||||
|
||||
/* Bigger ones */
|
||||
#define T_IP 0x20
|
||||
#define T_PREFIX 0x21
|
||||
#define T_STRING 0x22
|
||||
|
||||
#define T_SET 0x80
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue