diff --git a/bird.conf b/bird.conf index d315f0c9..466b45cc 100644 --- a/bird.conf +++ b/bird.conf @@ -8,6 +8,11 @@ router id 62.168.0.1; define xyzzy = 120+10; +function callme (int arg1; int arg2;) +{ + print "Function callme called arguments " arg1 " and " arg2; +} + function startup () int i; { @@ -30,9 +35,10 @@ int i; print " false = " 5 ~ [ 2, 3, 4, 7..11 ]; print "IPsets: true = " 1.2.3.4 ~ [ 1.2.3.3..1.2.3.5 ]; print " false = " 1.2.3.4 ~ [ 1.2.3.3, 1.2.3.5 ]; - + + callme ( 1, 2, ); print "done"; -# quitbird; + quitbird; print "*** FAIL: this is unreachable"; } diff --git a/conf/conf.h b/conf/conf.h index 86043245..4f6f030c 100644 --- a/conf/conf.h +++ b/conf/conf.h @@ -52,6 +52,7 @@ struct symbol { struct symbol *next; int class; int aux; + void *aux2; void *def; char name[1]; }; diff --git a/filter/config.Y b/filter/config.Y index c7f20148..6aa1285f 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -1,7 +1,7 @@ /* * BIRD - filters * - * Copyright 1998 Pavel Machek + * Copyright 1998,1999 Pavel Machek * * Can be freely distributed and used under the terms of the GNU GPL. */ @@ -29,11 +29,12 @@ CF_KEYWORDS(FUNCTION, PRINT, CONST, FILTER ) -%type term block cmds cmd function_body ifthen constant print_one print_list +%type term block cmds cmd function_body ifthen constant print_one print_list var_list %type filter filter_body %type type break_command %type set_item set_items %type set_atom +%type decls function_params CF_GRAMMAR @@ -63,10 +64,12 @@ type: } ; -decls: /* EMPTY */ +decls: /* EMPTY */ { $$ = NULL; } | type SYM ';' decls { cf_define_symbol($2, SYM_VARIABLE | $1, NULL); printf( "New variable %s type %x\n", $2->name, $1 ); + $2->aux = $4; + $$=$2; } ; @@ -88,7 +91,7 @@ filter: ; function_params: - '(' decls ')' { printf( "Have function parameters\n" ); } + '(' decls ')' { printf( "Have function parameters\n" ); $$=$2; } ; function_body: @@ -104,6 +107,8 @@ function_def: cf_define_symbol($2, SYM_FUNCTION, $4); if (!strcasecmp($2->name, "startup")) startup_func = $4; + $2->aux = $3; + $2->aux2 = $4; printf("Hmm, we've got one function here - %s\n", $2->name); } ; @@ -173,7 +178,7 @@ term: $$->a2.p = &($1->aux); break; default: - cf_error("Can not use this class of symbol as variable" ); + cf_error("Can not use this class of symbol as variable." ); } } | constant { $$ = $1; } @@ -216,6 +221,16 @@ print_list: /* EMPTY */ { $$ = NULL; } } ; +var_list: /* EMPTY */ { $$ = NULL; } + | term ',' var_list { + $$ = f_new_inst(); + $$->code = 's'; + $$->a1.p = NULL; + $$->a2.p = $1; + $$->next = $3; + } + ; + cmd: ifthen { $$ = $1; @@ -237,6 +252,26 @@ cmd: $$->a2.p = $3; } | break_command print_list ';' { $$ = f_new_inst(); $$->code = 'p,'; $$->a1.p = $2; $$->a2.i = $1; } + | SYM '(' var_list ')' ';' { + struct symbol *sym; + struct f_inst *inst = $3; + if ($1->class != SYM_FUNCTION) + cf_error("You can not call something which is not function. Really."); + printf("You are calling function %s\n", $1->name); + $$ = f_new_inst(); + $$->code = 'ca'; + $$->a1.p = inst; + $$->a2.p = $1->aux2; + sym = $1->aux; + while (sym || inst) { + if (!sym || !inst) + cf_error("wrong number of arguments for function %s.", $1->name); + printf( "You should pass parameter called %s\n", sym->name); + inst->a1.p = sym; + sym = sym->aux; + inst = inst->next; + } + } ; CF_END diff --git a/filter/filter.c b/filter/filter.c index 7afae437..c98440cd 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -250,6 +250,10 @@ interpret(struct f_inst *what) default: bug( "Unknown prefix to conversion\n" ); } break; + case 'ca': /* CALL */ + ONEARG; + res = interpret(what->a2.p); + break; default: bug( "Unknown instruction %d (%c)", what->code, what->code & 0xff); }