mynewt-newt icon indicating copy to clipboard operation
mynewt-newt copied to clipboard

Add support for expressions in syscfg values

Open andrzej-kaczmarek opened this issue 3 years ago • 2 comments

This adds support for evaluating syscfg values as expressions. This is done for all values by default so some existing configurations may need to be changed.

Following tokens are allowed in expressions:

  • literals (integers and strings)
  • identifiers (references to other syscfg values)
  • parentheses
  • binary operators (arithmetic, relational and boolean)
  • unary operator (boolean negation)
  • built-in function calls

Most operators support only integer values. Strings are supported by == and != only.

Conversions between integer and boolean are done implicitly:

  • true -> 1
  • false -> 0
  • ==0 -> false
  • !=0 -> true

Arguments to all built-in function shall be integer, unless explicitly mentioned otherwise.

Available built-in functions are:

  • min(a,b) - returns lesser of a and b
  • max(a,b) - returns greater of a and b
  • in_range(v,a,b) - returns if v is inside [a,b] range
  • clamp(v,a,b) - clamps v to be inside [a,b] range
  • ite(v,a,b) - if-then-else, returns a if v, otherwise returns b (note: a and b can be of any type)
  • in_set(v,...) - returns if v is one of remaining arguments (note: all argument can be of any type)
  • raw(v) - returns raw value, i.e. value that can be any arbitrary string but will not be double-quoted in syscfg.h (equivalent of default behavior for "old" evaluator)

andrzej-kaczmarek avatar Mar 23 '22 22:03 andrzej-kaczmarek

This adds support for evaluating syscfg values as expressions. To make it compatible with existing code, syscfg value is only evaluated as expression if its type is explicitly set to expr, i.e.:

syscfg.defs:
  FOO:
    description: ...
    type: expr
    value: 1 + 2 + 3

Is limiting expression evaluation to definition that explicitly allow this necessary? It really limits its potential in my opinion. I guess it is possible to have expressions in syscfg.vals and not only syscfg.defs, and limitation seems to be to harsh.

I would rather think of syntax similar to what is used in make/cmake where identifiers that should be evaluated are marked as $VAL or ${VAL}. Or at least allow expression to be placed in anywhere with syntax like $(expression to be evaluated by newt) instead of forcing definition to have type:expr.

kasjer avatar Mar 24 '22 06:03 kasjer

@kasjer I changed as discussed offline, i.e. all values are now always evaluated and it's possible to explicitly state that value should not be evaluated by using raw() function. and that means effectively it's still evaluated but returns raw string so it should return meaningful errors if referenced in another syscfg. this obviously breaks backwards compatibility but it's far more flexible and thus useful and seems like necessary changes to existing configuration should be pretty straightforward to do (examples referenced in other PRs)

andrzej-kaczmarek avatar Mar 24 '22 17:03 andrzej-kaczmarek