summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Machek <pavel@ucw.cz>1999-07-01 09:11:21 +0000
committerPavel Machek <pavel@ucw.cz>1999-07-01 09:11:21 +0000
commit6542ece91a783e999f61cc51cbe18c8b4c96a36c (patch)
tree061fd97a1a3ae1c45e22a2609a454ed69e14df19
parent39369d6fbe4b3f73c8110b14623f367c8ffded50 (diff)
Function calling in filters works - somehow. Calling syntax is
currently very ugly, beware. Variables are not really local - that needs to be fixed.
-rw-r--r--bird.conf10
-rw-r--r--conf/conf.h1
-rw-r--r--filter/config.Y45
-rw-r--r--filter/filter.c4
4 files changed, 53 insertions, 7 deletions
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 <x> term block cmds cmd function_body ifthen constant print_one print_list
+%type <x> term block cmds cmd function_body ifthen constant print_one print_list var_list
%type <f> filter filter_body
%type <i> type break_command
%type <e> set_item set_items
%type <v> set_atom
+%type <s> 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);
}