# `Expression.Eval`

Expression.Eval is responsible for taking an abstract syntax
tree (AST) as generated by Expression.Parser and evaluating it.

At a high level, an AST consists of a Keyword list with two top-level
keys, either `:text` or `:expression`.

`Expression.Eval.eval!/3` will return the output for each entry in the Keyword
list. `:text` entries are returned as regular strings. `:expression` entries
are returned as typed values.

The returned value is a list containing each.

# Example

    iex(1)> Expression.Eval.eval!([text: "hello"], %{})
    ["hello"]
    iex(2)> Expression.Eval.eval!([text: "hello", expression: [literal: 1]], %{})
    ["hello", 1]
    iex(3)> Expression.Eval.eval!([
    ...(3)>   text: "hello",
    ...(3)>   expression: [literal: 1],
    ...(3)>   text: "ok",
    ...(3)>   expression: [literal: true]
    ...(3)> ], %{})
    ["hello", 1, "ok", true]

# `case_insensitive_get`

Case-insensitive map lookup. Tries exact match first (fast path),
then falls back to case-insensitive key scan.

This enables `lowercase_keys: false` in Context — the parser lowercases
variable names in the AST, so `@Contact.Name` becomes a lookup for
`"contact"` which should match a key `"Contact"` in the context.

# `default_value`

Return the default value for a potentially complex value.

Complex values can be Maps that have a `__value__` key, if that's
returned then we can to use the `__value__` value when eval'ing against
operators or functions.

# `eval!`

# `handle_not_found`

# `not_founds_as_nil`

# `op`

# `parse_number`

Parses a given value into a number, being an integer or a float.
If the given value is not able to be parsed, then it returns the raw value.

---

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