For loops allow to iterate over elements in compound data like BGP paths
or community lists. The syntax is:
for [ <type> ] <variable> in <expr> do <command-body>
Allow variable declarations mixed with code, also in nested blocks with
proper scoping, and with variable initializers. E.g:
function fn(int a)
{
int b;
int c = 10;
if a > 20 then
{
b = 30;
int d = c * 2;
print a, b, c, d;
}
string s = "Hello";
}
When f_line is done, we have to pop the stack frame. The old code just
removed nominal number of args/vars. Change it to use stored ventry value
modified by number of returned values. This allows to allocate variables
on a stack frame during execution of f_lines instead of just at start.
But we need to know the number of returned values for a f_line. It is 1
for term, 0 for cmd. Store that to f_line during linearization.
When a new variable used the same name as an existing symbol in an outer
scope, then offset number was defined based on a scope of the existing
symbol ($3) instead of a scope of the new symbol (sym_). That can lead
to two variables sharing the same memory slot.
Direct recursion almost worked, just crashed on function signature check.
Split function parsing such that function signature is saved before
function body is processed. Recursive calls are marked so they can be
avoided during f_same() and similar code walking.
Also, include tower of hanoi solver as a test case.
Add literal for empty set [], which works both for tree-based sets
and prefix sets by using existing constant promotion mechanism.
Minor changes by committer.
Pass instructions of function call arguments as vararg arguments to
FI_CALL instruction constructor and move necessary magic from parser
code to interpreter / instruction code.
Add operators .min and .max to find minumum or maximum element in sets
of types: clist, eclist, lclist. Example usage:
bgp_community.min
bgp_ext_community.max
filter(bgp_large_community, [(as1, as2, *)]).min
Signed-off-by: Alexander Zubkov <green@qrator.net>
Add support to set or read outgoing MPLS labels using filters. Currently
this supports the addition of one label per route for the first next hop.
Minor changes by committer.
Add 'weight' route attribute that allows to get and set ECMP weight of
nexthops. Similar to 'gw' attribute, it is limited to the first nexthop,
but it is useful for handling BGP multipath, where an ECMP route is
merged from multiple regular routes.
Implement regex-like '+' operator in BGP path masks to match previous
path mask item multiple times. This is useful as ASNs may appear
multiple times in paths due to path prepending for traffic engineering
purposes.
This is a major change of how the filters are interpreted. If everything
works how it should, it should not affect you unless you are hacking the
filters themselves.
Anyway, this change should make a huge improvement in the filter performance
as previous benchmarks showed that our major problem lies in the
recursion itself.
There are also some changes in nest and protocols, related mostly to
spreading const declarations throughout the whole BIRD and also to
refactored dynamic attribute definitions. The need of these came up
during the whole work and it is too difficult to split out these
not-so-related changes.
With 32 bits, size of the args is 12 bytes, the f_val is 20 bytes.
With 64 bits, size of the args is 24 bytes, the f_val the same.
This is not so nice on 32 bits, anyway the f_inst itself is
24 vs. 32 bytes and the overall size of filters must be 32k of
instructions to get to one megabyte of RAM eaten by f_inst.
Therefore it seems to be improbable for common user to get into
problems with this change.