# `Monty.Config.Expression`
[🔗](https://github.com/d-led/ex.tbp.monty/blob/v0.1.0/packages/ex_tbp_monty_core/lib/monty/config/expression.ex#L1)

Evaluates the tiny arithmetic dialect Monty's configs use.

Monty has an OmegaConf resolver, `np.list_eval`, that runs Python's `eval` over
each item of a list, and its configs rely on it for things like
`${np.list_eval:[np.pi / 8, np.pi * 2, np.pi * 2]}`. Running Python is not an
option, so this module parses exactly the language those entries use:

  * number literals (`8`, `0.7`, `1e-3`)
  * `np.pi`
  * `+`, `-`, `*`, `/` with the usual precedence, and parentheses
  * a list of expressions in brackets

Anything outside that grammar is an error, which is the point: an evaluator
that quietly accepts more would be an evaluator we cannot reason about.

# `value`

```elixir
@type value() :: number() | [value()]
```

# `evaluate`

```elixir
@spec evaluate(String.t()) :: {:ok, value()} | {:error, term()}
```

Evaluates a bare expression.

    iex> Monty.Config.Expression.evaluate("np.pi / 8")
    0.39269908169872414

    iex> Monty.Config.Expression.evaluate("[1, 2 * 3]")
    [1.0, 6.0]

---

*Consult [api-reference.md](api-reference.md) for complete listing*
