0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-09-16 18:35:19 +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 AND;
\|\| return OR;
\-\> return IMP;
\[\= return PO;
\=\] return PC;

View File

@ -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 '!'

View File

@ -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);

View File

@ -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);
}
;

View File

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

View File

@ -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