The C-style syntax does not really fit into rest of our syntax.
\>\= return GEQ;
\&\& return AND;
\|\| return OR;
+\-\> return IMP;
\[\= return PO;
\=\] return PC;
}
%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
%nonassoc PREFIX_DUMMY
%left AND OR
-%nonassoc '=' '<' '>' '~' GEQ LEQ NEQ NMA PO PC
+%nonassoc '=' '<' '>' '~' GEQ LEQ NEQ NMA IMP PO PC
%left '+' '-'
%left '*' '/' '%'
%left '!'
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/) [ -> <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>
(<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);
%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
}
;
+function_type:
+ /* EMPTY */ { $$ = T_VOID; }
+ | IMP type { $$ = $2; }
+ ;
+
filter_body: function_body ;
filter:
;
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;
$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);
}
;
NEVER_CONSTANT;
VARARG;
SYMBOL;
-
- /* Fake result type declaration */
RESULT_TYPE(sym->function->return_type);
FID_NEW_BODY()
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;
}
* -------------
*/
-function pair 'mkpair-a'(int a)
+function 'mkpair-a'(int a) -> pair
{
return (1, a);
}
* -------------
*/
-function bgpmask mkpath(int a; int b)
+function mkpath(int a; int b) -> bgpmask
{
return [= a b 3 2 1 =];
}
* -------------------------
*/
-function lc mktrip(int a)
+function mktrip(int a) -> lc
{
return (a, 2*a, 3*a);
}
* -------------------------
*/
-function int callme(int arg1; int arg2)
+function callme(int arg1; int arg2) -> int
int i;
{
case arg1 {
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;
}
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