Parses and evaluates FEEL expressions.
The public facade accepts FEEL source through parse/1 and evaluate/2, or
an already parsed syntax tree through evaluate_ast/2.
Summary
Types
@type ast() :: {:literal, term()} | {:identifier, String.t()} | {:unary, atom(), ast()} | {:binary, atom(), ast(), ast()} | {:list, [ast()]} | {:context, [{String.t(), ast()}]} | {:path, ast(), String.t()} | {:filter, ast(), ast()} | {:range, boolean(), boolean(), ast(), ast()} | {:in, ast(), ast()} | {:unary_test, atom(), ast()} | {:unary_tests, [ast()]} | {:sequence, ast(), ast()} | {:if, ast(), ast(), ast()} | {:for, String.t(), ast(), ast()} | {:for, [{String.t(), ast()}], ast()} | {:quantifier, :some | :every, String.t(), ast(), ast()} | {:between, ast(), ast(), ast()} | {:instance_of, ast(), String.t()} | {:function, [String.t()], ast()} | {:call, ast(), [ast()]}
Functions
@spec evaluate(String.t(), context()) :: {:ok, term()} | {:error, Boxic.FEEL.Error.t()}
Parses and evaluates a FEEL expression.
iex> Boxic.FEEL.evaluate("price * quantity", %{
...> "price" => Decimal.new("12.50"),
...> "quantity" => Decimal.new("2")
...> })
{:ok, Decimal.new("25.00")}
@spec evaluate_ast(ast(), context()) :: {:ok, term()} | {:error, Boxic.FEEL.Error.t()}
Evaluates an AST previously returned by parse/1.
@spec evaluate_unary_test(String.t(), term(), context()) :: {:ok, boolean()} | {:error, Boxic.FEEL.Error.t()}
Evaluates a FEEL unary test against value.
iex> Boxic.FEEL.evaluate_unary_test(">= 18", Decimal.new("21"))
{:ok, true}
@spec parse(String.t()) :: {:ok, ast()} | {:error, Boxic.FEEL.Error.t()}
Parses a FEEL expression into Boxic's public AST representation.
iex> Boxic.FEEL.parse("1 + 2")
{:ok, {:binary, :plus, {:literal, Decimal.new("1")}, {:literal, Decimal.new("2")}}}