# `Dsqlex`
[🔗](https://github.com/nicolasalmini/DSQLEX/blob/main/lib/dsqlex.ex#L1)

DSQLEX - A SQL-like DSL for evaluating calculations in Elixir.

## Usage

    # Define a calculation expression (SELECT is optional)
    expression = "CASE WHEN category = 'A' THEN x ELSE (y / z) END"

    # Create a context with your data
    context = %{
      "x" => Decimal.new("100.00"),
      "y" => Decimal.new("500.00"),
      "category" => "B",
      "z" => Decimal.new("5.00")
    }

    # Evaluate!
    {:ok, result} = Dsqlex.eval(expression, context)
    # => {:ok, Decimal.new("100")}

## Supported Features

- **Arithmetic:** `+`, `-`, `*`, `/`
- **Comparison:** `=`, `!=`, `<`, `>`, `<=`, `>=`
- **Logical:** `AND`, `OR` (same-operator chaining allowed)
- **Control flow:** `CASE WHEN ... THEN ... ELSE ... END`
- **Functions:** `ROUND()`, `COALESCE()`, `UPPER()`, `LOWER()`, `ABS()`, `CONCAT()`
- **Literals:** Numbers, strings, booleans, NULL

## Parentheses Rule

To avoid ambiguity, expressions that mix operator groups require parentheses:

    # Valid
    "1 + 2"
    "1 + 2 + 3"
    "(1 + 2) * 3"
    "a = 1 AND b = 2 AND c = 3"

    # Invalid (ambiguous)
    "1 + 2 * 3"
    "a = 1 AND b = 2 OR c = 3"

# `eval`

Evaluates an expression against a context.

The `SELECT` keyword is optional.

## Parameters

- `expression` - A string containing the expression
- `context` - A map of field names (strings) to values

## Returns

- `{:ok, result}` - The computed result
- `{:error, reason}` - If lexing, parsing, or evaluation fails

## Examples

    iex> Dsqlex.eval("1 + 2", %{})
    {:ok, Decimal.new("3")}

    iex> Dsqlex.eval("x * 2", %{"x" => Decimal.new("50")})
    {:ok, Decimal.new("100")}

# `parse`

Parses an expression and returns the AST without evaluating.

Useful for validating expressions before storing them.
The `SELECT` keyword is optional.

## Examples

    iex> Dsqlex.parse("x / y")
    {:ok, {:select, {:binary_op, :divide, {:identifier, "x"}, {:identifier, "y"}}}}

# `tokenize`

Tokenizes an expression without parsing.

Useful for debugging or inspecting the lexer output.

---

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