This merge was particularly difficult. I finally resorted to delete the
symbol scope active flag altogether and replace its usage by other
means.
Also I had to update custom route attribute registration to fit
both the scope updates in v2 and the data model in v3.
- Extend method descriptors with type signature
- Daisy chain method descriptors for the same symbol
- Dispatch methods for same symbol based on type signature
- Split add/delete/filter operations to multiple methods
- Replace ad-hoc dispatch of old-style syntax with scope-based dispatch
- Also change method->arg_num to count initial arg
It still needs some improvements, like better handling of untyped
expressions and better error reporting when no dispatch can be done.
The multiple dispatch could also be extended to dispatch regular
function-like expressions in a uniform way.
Methods can now be called as x.m(y), as long as x can have its type
inferred in config time. If used as a command, it modifies the object,
if used as a value, it keeps the original object intact.
Also functions add(x,y), delete(x,y), filter(x,y) and prepend(x,y) now
spit a warning and are considered deprecated.
It's also possible to call a method on a constant, see filter/test.conf
for examples like bgp_path = +empty+.prepend(1).
Inside instruction definitions (filter/f-inst.c), a METHOD_CONSTRUCTOR()
call is added, which registers the instruction as a method for the type
of its first argument. Each type has its own method symbol table and
filter parser switches between them based on the inferred type of the
object calling the method.
Also FI_CLIST_(ADD|DELETE|FILTER) instructions have been split to allow
for this method dispatch. With type inference, it's now possible.
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.
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.
All instructions with a return value (i.e. expressions, ones with
non-zero outval, third argument in INST()) should declare their return
type. Check that automatically by M4 macros.
Set outval of FI_RETURN to 0. The instruction adds one value to stack,
but syntactically it is a statement, not an expression.
Add fake return type declaration to FI_CALL, otherwise the automatic
check would fail builds.
Changes in internal API:
* Every route attribute must be defined as struct ea_class somewhere.
* Registration of route attributes known at startup must be done by
ea_register_init() from protocol build functions.
* Every attribute has now its symbol registered in a global symbol table
defined as SYM_ATTRIBUTE
* All attribute ID's are dynamically allocated.
* Attribute value custom formatting hook is defined in the ea_class.
* Attribute names are the same for display and filters, always prefixed
by protocol name.
Also added some unit testing code for filters with route attributes.
This commit removes the EAF_TYPE_* namespace completely and also for
route attributes, filter-based types T_* are used. This simplifies
fetching and setting route attributes from filters.
Also, there is now union bval which serves as an universal value holder
instead of private unions held separately by eattr and filter code.
Do not apply dynamic type check for second argument of AND/OR, as it is
not evaluated immediately like regular argument would be.
Thanks to Mikael for the bugreport.
We use constant promotion from IPv4 to Router-ID values, as they have
same literals. Instead of ad-hoc code in filter instructions, add
constant promotion code to parse-time typecheck code.
Most expressions can be type-validated in parse time. It is not
strong enough to eliminate runtime checks, but at least one gets
errors immediately during reconfigure.