diff options
author | Ondrej Zajicek <santiago@crfreenet.org> | 2023-07-04 19:07:30 +0200 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2023-09-12 16:31:52 +0200 |
commit | fc4398b4e1d18142a5c428a7c90484071a81ab9c (patch) | |
tree | b304a94e2b40454ac3dc8398a71f964387e6692d | |
parent | cc1099a04169b768cb4803686ee20423a6d3fede (diff) |
Filter: Better syntax for function return types
The C-style syntax does not really fit into rest of our syntax.
-rw-r--r-- | conf/cf-lex.l | 1 | ||||
-rw-r--r-- | conf/confbase.Y | 4 | ||||
-rw-r--r-- | doc/bird.sgml | 16 | ||||
-rw-r--r-- | filter/config.Y | 30 | ||||
-rw-r--r-- | filter/f-inst.c | 2 | ||||
-rw-r--r-- | filter/test.conf | 26 |
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/) [ -> <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 |