diff options
author | Pavel Machek <pavel@ucw.cz> | 1999-03-29 22:21:28 +0200 |
---|---|---|
committer | Pavel Machek <pavel@ucw.cz> | 1999-03-29 22:21:28 +0200 |
commit | ba92164871f65bb9adcfa66b901d1a7b86697a86 (patch) | |
tree | ed1c8fea5b94ea0c2ef23eb0129c82a5be3f99ac /filter | |
parent | 5bc512aa3a0d3e4ca378fff3316b75c131f17637 (diff) | |
download | bird-ba92164871f65bb9adcfa66b901d1a7b86697a86.tar bird-ba92164871f65bb9adcfa66b901d1a7b86697a86.zip |
Update of filters towards new interface.
Diffstat (limited to 'filter')
-rw-r--r-- | filter/config.Y | 177 | ||||
-rw-r--r-- | filter/f-util.c | 11 | ||||
-rw-r--r-- | filter/filter.h | 20 |
3 files changed, 116 insertions, 92 deletions
diff --git a/filter/config.Y b/filter/config.Y index 6d51dc7..de178e7 100644 --- a/filter/config.Y +++ b/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 ; -/* Programs */ +function_params: + '(' decls ')' { printf( "Have function parameters\n" ); } + ; -cmds: - term { - if ($1) { - $1->next = NULL; - $$ = $1; - } else $$ = NULL; +function_body: + decls '{' cmds '}' { + $$ = $3; } - | term ';' cmds { + ; + +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: /* EMPTY */ { $$ = NULL; } + | cmd cmds { if ($1) { - $1->next = $3; + $1->next = $2; $$ = $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 { + | PRINTDEBUG ';' { $$ = f_new_inst(); - $$->code = '!'; - (int) $$->arg1 = F_REJECT; + $$->code = 'D'; + $$->arg1 = $$->arg2 = NULL; } - | ERROR { + | break_command ';' { $$ = f_new_inst(); $$->code = '!'; - (int) $$->arg1 = F_ERROR; + (int) $$->arg1 = $1; } - | PRINTDEBUG { - $$ = f_new_inst(); - $$->code = 'D'; - $$->arg1 = $$->arg2 = NULL; - } ; CF_END diff --git a/filter/f-util.c b/filter/f-util.c index 1f757ff..ee7ea2d 100644 --- a/filter/f-util.c +++ b/filter/f-util.c @@ -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); } diff --git a/filter/filter.h b/filter/filter.h index 379a4ac..ba8dc85 100644 --- a/filter/filter.h +++ b/filter/filter.h @@ -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 |