The values an expression reads by name.
Feel.run/3 takes a map from name to value. A :var node of the IR is looked up
there by its canonical name (Feel.Name). It is a function of the runtime, and not
a private part of a backend, because generated code may call only Feel.Runtime
and both backends have to find the same value.
A binding whose key is the same name written differently ("a - b" for "a-b") is
found too, after the exact key. A name that has no binding is null, with a warning
(:unknown_name) that does not end a strict run.
Summary
Functions
@spec bind_input(Feel.bindings(), Feel.Value.t()) :: Feel.bindings()
Binds the input ? of unary tests to a value, in a copy of the bindings.
The tests of allowed values (D-138) run with the value that is verified as ?. It is a
function of the runtime for the same reason lookup/4 is: the interpreter and the generated
code of the BEAM backend have to bind it alike.
iex> Feel.Runtime.Bindings.bind_input(%{"x" => 1}, 2)
%{"x" => 1, "?" => 2}
@spec fetch(Feel.bindings(), Feel.Name.t()) :: {:ok, Feel.Value.t()} | :error
Looks a name up in the bindings, as lookup/4 does, but reports nothing when it has no
binding.
iex> Feel.Runtime.Bindings.fetch(%{"a - b" => 1}, "a-b")
{:ok, 1}
iex> Feel.Runtime.Bindings.fetch(%{}, "a")
:error
@spec lookup( Feel.Runtime.Env.t(), Feel.bindings(), Feel.Name.t(), Feel.Diagnostic.span() ) :: {Feel.Value.t(), Feel.Runtime.Env.t()}
Looks a name up in the bindings.
Returns the value and the environment. span is where the name is in the source;
it goes on the warning for a name that is not bound.
iex> env = Feel.Runtime.Env.new()
iex> {"x", ^env} = Feel.Runtime.Bindings.lookup(env, %{"x" => "x"}, "x", {0, 1})
iex> {nil, env} = Feel.Runtime.Bindings.lookup(env, %{}, "y", {4, 5})
iex> [warning] = Feel.Runtime.Env.diagnostics(env)
iex> {warning.severity, warning.code, warning.span}
{:warning, :unknown_name, {4, 5}}