summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--conf/cf-lex.l1
-rw-r--r--conf/confbase.Y4
-rw-r--r--doc/bird.sgml16
-rw-r--r--filter/config.Y30
-rw-r--r--filter/f-inst.c2
-rw-r--r--filter/test.conf26
6 files changed, 39 insertions, 40 deletions
diff --git a/conf/cf-lex.l b/conf/cf-lex.l
index dcd54b81..cee0e63e 100644
--- a/conf/cf-lex.l
+++ b/conf/cf-lex.l
@@ -380,6 +380,7 @@ else: {
\>\= return GEQ;
\&\& return AND;
\|\| return OR;
+\-\> return IMP;
\[\= return PO;
\=\] return PC;
diff --git a/conf/confbase.Y b/conf/confbase.Y
index 2efeb29f..7b368fc6 100644
--- a/conf/confbase.Y
+++ b/conf/confbase.Y
@@ -98,7 +98,7 @@ CF_DECLS
}
%token END CLI_MARKER INVALID_TOKEN ELSECOL DDOT
-%token GEQ LEQ NEQ AND OR
+%token GEQ LEQ NEQ AND OR IMP
%token PO PC
%token <i> NUM ENUM
%token <ip4> IP4
@@ -125,7 +125,7 @@ CF_DECLS
%nonassoc PREFIX_DUMMY
%left AND OR
-%nonassoc '=' '<' '>' '~' GEQ LEQ NEQ NMA PO PC
+%nonassoc '=' '<' '>' '~' GEQ LEQ NEQ NMA IMP PO PC
%left '+' '-'
%left '*' '/' '%'
%left '!'
diff --git a/doc/bird.sgml b/doc/bird.sgml
index 3fcf0025..3be266cb 100644
--- a/doc/bird.sgml
+++ b/doc/bird.sgml
@@ -539,7 +539,7 @@ include "tablename.conf";;
Define a filter. You can learn more about filters in the following
chapter.
- <tag><label id="opt-function">function <m/type/ <m/name/ (<m/parameters/) <m/local variables/ { <m/commands/ }</tag>
+ <tag><label id="opt-function">function <m/name/ (<m/parameters/) [ -&gt; <m/return type/ ] <m/local variables/ { <m/commands/ }</tag>
Define a function. You can learn more about functions in the following chapter.
<tag><label id="opt-protocol">protocol rip|ospf|bgp|<m/.../ [<m/name/ [from <m/name2/]] { <m>protocol options</m> }</tag>
@@ -1294,21 +1294,21 @@ can group several statements to a single compound statement by using braces
(<cf>{ <M>statements</M> }</cf>) which is useful if you want to make a bigger
block of code conditional.
-<p>BIRD supports functions, so that you don't have to repeat the same blocks of
-code over and over. Functions can have zero or more parameters and they can have
-local variables. You should always specify the function return type and always
-return it. No-return functions and multiple-type returning functions are deprecated.
-Direct recursion is possible. Function definitions look like this:
+<p>BIRD supports functions, so that you don not have to repeat the same blocks
+of code over and over. Functions can have zero or more parameters and they can
+have local variables. If the function returns value, then you should always
+specify its return type. Direct recursion is possible. Function definitions look
+like this:
<code>
-function int name ()
+function name() -> int
{
int local_variable;
int another_variable = 5;
return 42;
}
-function pair with_parameters (int parameter)
+function with_parameters(int parameter) -> pair
{
print parameter;
return (1, 2);
diff --git a/filter/config.Y b/filter/config.Y
index 7cc6f882..f856924c 100644
--- a/filter/config.Y
+++ b/filter/config.Y
@@ -380,7 +380,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
%type <f> filter where_filter
%type <fl> filter_body function_body
%type <flv> lvalue
-%type <i> type maybe_type function_vars
+%type <i> type function_vars function_type
%type <fa> function_argsn function_args
%type <ecs> ec_kind
%type <fret> break_command
@@ -513,6 +513,11 @@ function_vars:
}
;
+function_type:
+ /* EMPTY */ { $$ = T_VOID; }
+ | IMP type { $$ = $2; }
+ ;
+
filter_body: function_body ;
filter:
@@ -547,28 +552,23 @@ function_body:
;
conf: function_def ;
-maybe_type:
- /* EMPTY */ { $$ = T_VOID; }
- | type { $$ = $1; }
- ;
function_def:
- FUNCTION maybe_type symbol {
- DBG( "Beginning of function %s\n", $3->name );
- this_function = cf_define_symbol(new_config, $3, SYM_FUNCTION, function, NULL);
-/* if ($2 == T_VOID) cf_warn("Support for functions without explicit return type will be removed soon" ); */
+ FUNCTION symbol {
+ DBG( "Beginning of function %s\n", $2->name );
+ this_function = cf_define_symbol(new_config, $2, SYM_FUNCTION, function, NULL);
cf_push_scope(new_config, this_function);
- } function_args {
+ } function_args function_type {
/* Make dummy f_line for storing function prototype */
struct f_line *dummy = cfg_allocz(sizeof(struct f_line));
this_function->function = dummy;
- dummy->return_type = $2;
+ dummy->return_type = $5;
/* Revert the args */
- while ($5) {
- struct f_arg *tmp = $5;
- $5 = $5->next;
+ while ($4) {
+ struct f_arg *tmp = $4;
+ $4 = $4->next;
tmp->next = dummy->arg_list;
dummy->arg_list = tmp;
@@ -578,7 +578,7 @@ function_def:
$7->args = this_function->function->args;
$7->arg_list = this_function->function->arg_list;
$7->return_type = this_function->function->return_type;
- $3->function = $7;
+ $2->function = $7;
cf_pop_scope(new_config);
}
;
diff --git a/filter/f-inst.c b/filter/f-inst.c
index a9de0960..be22accc 100644
--- a/filter/f-inst.c
+++ b/filter/f-inst.c
@@ -1127,8 +1127,6 @@
NEVER_CONSTANT;
VARARG;
SYMBOL;
-
- /* Fake result type declaration */
RESULT_TYPE(sym->function->return_type);
FID_NEW_BODY()
diff --git a/filter/test.conf b/filter/test.conf
index 90f5e694..62993898 100644
--- a/filter/test.conf
+++ b/filter/test.conf
@@ -21,17 +21,17 @@ attribute lclist mylclist;
define one = 1;
define ten = 10;
-function int onef(int a)
+function onef(int a) -> int
{
return 1;
}
-function int twof(int a)
+function twof(int a) -> int
{
return 2;
}
-function int oneg(int a)
+function oneg(int a) -> int
{
return 1;
}
@@ -274,7 +274,7 @@ bt_test_suite(t_bytestring, "Testing bytestrings");
* -------------
*/
-function pair 'mkpair-a'(int a)
+function 'mkpair-a'(int a) -> pair
{
return (1, a);
}
@@ -749,7 +749,7 @@ bt_test_suite(t_flowspec, "Testing flowspec routes");
* -------------
*/
-function bgpmask mkpath(int a; int b)
+function mkpath(int a; int b) -> bgpmask
{
return [= a b 3 2 1 =];
}
@@ -1432,7 +1432,7 @@ bt_test_suite(t_ec_set, "Testing sets of extended communities");
* -------------------------
*/
-function lc mktrip(int a)
+function mktrip(int a) -> lc
{
return (a, 2*a, 3*a);
}
@@ -1747,7 +1747,7 @@ bt_test_suite(t_define, "Testing defined() function");
* -------------------------
*/
-function int callme(int arg1; int arg2)
+function callme(int arg1; int arg2) -> int
int i;
{
case arg1 {
@@ -1758,12 +1758,12 @@ int i;
return 0;
}
-function int callmeagain(int a; int b; int c)
+function callmeagain(int a; int b; int c) -> int
{
return a + b + c;
}
-function int fifteen()
+function fifteen() -> int
{
return 15;
}
@@ -1796,28 +1796,28 @@ function local_vars(int j)
bt_assert(j = 35 && k = 20 && m = 100);
}
-function int factorial(int x)
+function factorial(int x) -> int
{
if x = 0 then return 0;
if x = 1 then return 1;
else return x * factorial(x - 1);
}
-function int fibonacci(int x)
+function fibonacci(int x) -> int
{
if x = 0 then return 0;
if x = 1 then return 1;
else return fibonacci(x - 1) + fibonacci(x - 2);
}
-function bgppath hanoi_init(int a; int b)
+function hanoi_init(int a; int b) -> bgppath
{
if b = 0
then return +empty+;
else return prepend(hanoi_init(a + 1, b - 1), a);
}
-function bgppath hanoi_solve(int n; bgppath h_src; bgppath h_dst; bgppath h_aux; bool x; bool y)
+function hanoi_solve(int n; bgppath h_src; bgppath h_dst; bgppath h_aux; bool x; bool y) -> bgppath
{
# x -> return src or dst
# y -> print state