# `Feel.Runtime`
[🔗](https://github.com/FeeJai/BDM/blob/feel-v0.1.0/apps/feel/lib/feel/runtime.ex#L1)

The shared runtime and generated-code cache stamp.

FEEL's semantics live in the runtime: arithmetic with decimal128 rounding, the
three-valued logic, comparison across temporal types, filters, the built-in
functions. The interpreter calls it directly, and the code that the BEAM backend
generates calls nothing else. That makes it the contract between the compiler
and the code it produces.

## Generated code

`abi/0` is a cache-generation stamp used in generated module names. It changes
when compiler/runtime changes make existing generated code unsuitable for reuse.
Only code generated by the current compiler is supported. Regenerate prepared
expressions on upgrade; persisting generated `.beam` files is not supported.
There is no multi-version runtime or compatibility negotiation.

## The runtime functions

The runtime is a set of modules under `Feel.Runtime`, one per area of the
specification. They are pure functions on FEEL values (`Feel.Value`), each citing
the tables of DMN 1.6 it implements. A function that can fail returns an
`t:Feel.Runtime.Env.outcome/0` and the caller settles it with `Feel.Runtime.Env`,
so the operations themselves touch no state.

| Module                         | Area                                                                |
| ------------------------------ | ------------------------------------------------------------------- |
| `Feel.Runtime.Env`             | mode, dialect, extensions, clock, limits, and the diagnostics of one run |
| `Feel.Runtime.Bindings`        | the values an expression reads by name                              |
| `Feel.Runtime.Kind`            | the kind of a value, which the tables dispatch on                   |
| `Feel.Runtime.Number`          | decimal128 arithmetic, rounding, scale checks                       |
| `Feel.Runtime.Number.Power`    | `**`, `ln` and `exp`, correctly rounded to 34 digits                |
| `Feel.Runtime.Logic`           | three-valued `and`, `or`, `not` (Tables 51-52)                      |
| `Feel.Runtime.Compare`         | equality and ordering (Tables 50, 53-55)                            |
| `Feel.Runtime.Arithmetic`      | `+ - * / **` and negation (Tables 57-61, 63)                        |
| `Feel.Runtime.Temporal`        | date, time, and duration arithmetic and comparison (Tables 54, 55, 58) |
| `Feel.Runtime.Path`            | `e.name` and `e...name`: entries and properties (Tables 65-68, 71)  |
| `Feel.Runtime.Filter`          | filters and indexes (Table 69)                                      |
| `Feel.Runtime.TypeCheck`       | `instance of` (Table 62)                                            |
| `Feel.Runtime.Invoke`          | function values and calls, parameter conversion (Table 64)          |
| `Feel.Runtime.Iteration`       | `for`, `some` and `every`: the loops, `partial`, the domains (Table 50, 10.3.2.14) |
| `Feel.Runtime.Partial`         | the results of a `for` so far, for a body that only indexes `partial` (D-86) |
| `Feel.Runtime.Interpret`       | the interpreter's walk, for generated code that began a guarded fast path and cannot finish it (D-164) |
| `Feel.Runtime.UnaryTests`      | what it means for a value to satisfy unary tests, and `in`          |
| `Feel.Runtime.RangeLiteral`    | the value of a range literal such as `[1..10)` or `(< 10)`          |
| `Feel.Runtime.RangeText`       | reading the text of a range, for `range(from)`                      |
| `Feel.Runtime.TemporalText`    | reading the text of a time and a date and time, as the extensions spell it (D-81) |
| `Feel.Runtime.Regex`           | the regular expressions of XPath, for `matches`, `replace` and `split` |
| `Feel.Runtime.AllowedValues`, `BindingTypes`, `ResultType` | the run-time half of what a scope declares: allowed values, types of the names, type of the result |

A module says in its own documentation what it leaves out. A case that the specification
defines and that is not written raises `RuntimeError`; a call of a built-in function that is not
written is caught earlier, as an `:analysis` error of `Feel.prepare/2`.

The built-in functions are in the modules under `Feel.Builtin`, one per area of
section 10.3.4 (see `Feel.Builtin.areas/0`). Generated code calls them as well, so
they are part of that runtime contract too.

# `abi`

```elixir
@spec abi() :: pos_integer()
```

Returns the current generated-code cache stamp. It is part of the name of every generated module, so changing it when the
runtime functions that generated code calls change in arity or meaning keeps the code of the old runtime from being reused.

    iex> Feel.Runtime.abi()
    1

---

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