0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-22 17:51:53 +00:00

Filter: Better syntax for function return types

The C-style syntax does not really fit into rest of our syntax.
This commit is contained in:
Ondrej Zajicek 2023-07-04 19:07:30 +02:00
parent cc1099a041
commit fc4398b4e1
6 changed files with 39 additions and 40 deletions

View File

@ -380,6 +380,7 @@ else: {
\>\= return GEQ; \>\= return GEQ;
\&\& return AND; \&\& return AND;
\|\| return OR; \|\| return OR;
\-\> return IMP;
\[\= return PO; \[\= return PO;
\=\] return PC; \=\] return PC;

View File

@ -98,7 +98,7 @@ CF_DECLS
} }
%token END CLI_MARKER INVALID_TOKEN ELSECOL DDOT %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 PO PC
%token <i> NUM ENUM %token <i> NUM ENUM
%token <ip4> IP4 %token <ip4> IP4
@ -125,7 +125,7 @@ CF_DECLS
%nonassoc PREFIX_DUMMY %nonassoc PREFIX_DUMMY
%left AND OR %left AND OR
%nonassoc '=' '<' '>' '~' GEQ LEQ NEQ NMA PO PC %nonassoc '=' '<' '>' '~' GEQ LEQ NEQ NMA IMP PO PC
%left '+' '-' %left '+' '-'
%left '*' '/' '%' %left '*' '/' '%'
%left '!' %left '!'

View File

@ -539,7 +539,7 @@ include "tablename.conf";;
Define a filter. You can learn more about filters in the following Define a filter. You can learn more about filters in the following
chapter. 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. 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> <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 (<cf>{ <M>statements</M> }</cf>) which is useful if you want to make a bigger
block of code conditional. block of code conditional.
<p>BIRD supports functions, so that you don't have to repeat the same blocks of <p>BIRD supports functions, so that you don not have to repeat the same blocks
code over and over. Functions can have zero or more parameters and they can have of code over and over. Functions can have zero or more parameters and they can
local variables. You should always specify the function return type and always have local variables. If the function returns value, then you should always
return it. No-return functions and multiple-type returning functions are deprecated. specify its return type. Direct recursion is possible. Function definitions look
Direct recursion is possible. Function definitions look like this: like this:
<code> <code>
function int name () function name() -> int
{ {
int local_variable; int local_variable;
int another_variable = 5; int another_variable = 5;
return 42; return 42;
} }
function pair with_parameters (int parameter) function with_parameters(int parameter) -> pair
{ {
print parameter; print parameter;
return (1, 2); return (1, 2);

View File

@ -380,7 +380,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
%type <f> filter where_filter %type <f> filter where_filter
%type <fl> filter_body function_body %type <fl> filter_body function_body
%type <flv> lvalue %type <flv> lvalue
%type <i> type maybe_type function_vars %type <i> type function_vars function_type
%type <fa> function_argsn function_args %type <fa> function_argsn function_args
%type <ecs> ec_kind %type <ecs> ec_kind
%type <fret> break_command %type <fret> break_command
@ -513,6 +513,11 @@ function_vars:
} }
; ;
function_type:
/* EMPTY */ { $$ = T_VOID; }
| IMP type { $$ = $2; }
;
filter_body: function_body ; filter_body: function_body ;
filter: filter:
@ -547,28 +552,23 @@ function_body:
; ;
conf: function_def ; conf: function_def ;
maybe_type:
/* EMPTY */ { $$ = T_VOID; }
| type { $$ = $1; }
;
function_def: function_def:
FUNCTION maybe_type symbol { FUNCTION symbol {
DBG( "Beginning of function %s\n", $3->name ); DBG( "Beginning of function %s\n", $2->name );
this_function = cf_define_symbol(new_config, $3, SYM_FUNCTION, function, NULL); this_function = cf_define_symbol(new_config, $2, SYM_FUNCTION, function, NULL);
/* if ($2 == T_VOID) cf_warn("Support for functions without explicit return type will be removed soon" ); */
cf_push_scope(new_config, this_function); cf_push_scope(new_config, this_function);
} function_args { } function_args function_type {
/* Make dummy f_line for storing function prototype */ /* Make dummy f_line for storing function prototype */
struct f_line *dummy = cfg_allocz(sizeof(struct f_line)); struct f_line *dummy = cfg_allocz(sizeof(struct f_line));
this_function->function = dummy; this_function->function = dummy;
dummy->return_type = $2; dummy->return_type = $5;
/* Revert the args */ /* Revert the args */
while ($5) { while ($4) {
struct f_arg *tmp = $5; struct f_arg *tmp = $4;
$5 = $5->next; $4 = $4->next;
tmp->next = dummy->arg_list; tmp->next = dummy->arg_list;
dummy->arg_list = tmp; dummy->arg_list = tmp;
@ -578,7 +578,7 @@ function_def:
$7->args = this_function->function->args; $7->args = this_function->function->args;
$7->arg_list = this_function->function->arg_list; $7->arg_list = this_function->function->arg_list;
$7->return_type = this_function->function->return_type; $7->return_type = this_function->function->return_type;
$3->function = $7; $2->function = $7;
cf_pop_scope(new_config); cf_pop_scope(new_config);
} }
; ;

View File

@ -1127,8 +1127,6 @@
NEVER_CONSTANT; NEVER_CONSTANT;
VARARG; VARARG;
SYMBOL; SYMBOL;
/* Fake result type declaration */
RESULT_TYPE(sym->function->return_type); RESULT_TYPE(sym->function->return_type);
FID_NEW_BODY() FID_NEW_BODY()

View File

@ -21,17 +21,17 @@ attribute lclist mylclist;
define one = 1; define one = 1;
define ten = 10; define ten = 10;
function int onef(int a) function onef(int a) -> int
{ {
return 1; return 1;
} }
function int twof(int a) function twof(int a) -> int
{ {
return 2; return 2;
} }
function int oneg(int a) function oneg(int a) -> int
{ {
return 1; 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); 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 =]; 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); 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; int i;
{ {
case arg1 { case arg1 {
@ -1758,12 +1758,12 @@ int i;
return 0; return 0;
} }
function int callmeagain(int a; int b; int c) function callmeagain(int a; int b; int c) -> int
{ {
return a + b + c; return a + b + c;
} }
function int fifteen() function fifteen() -> int
{ {
return 15; return 15;
} }
@ -1796,28 +1796,28 @@ function local_vars(int j)
bt_assert(j = 35 && k = 20 && m = 100); 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 = 0 then return 0;
if x = 1 then return 1; if x = 1 then return 1;
else return x * factorial(x - 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 = 0 then return 0;
if x = 1 then return 1; if x = 1 then return 1;
else return fibonacci(x - 1) + fibonacci(x - 2); 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 if b = 0
then return +empty+; then return +empty+;
else return prepend(hanoi_init(a + 1, b - 1), a); 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 # x -> return src or dst
# y -> print state # y -> print state