# `PtcRunner.Lisp.ClojureValidator`
[🔗](https://github.com/andreasronge/ptc_runner/blob/main/lib/ptc_runner/lisp/clojure_validator.ex#L1)

Validates PTC-Lisp programs against Babashka/Clojure.

Provides validation to ensure:
1. PTC-Lisp programs are valid Clojure syntax
2. Runtime functions behave identically to Clojure equivalents

## Usage

    # Check if Babashka is available
    PtcRunner.Lisp.ClojureValidator.available?()

    # Validate syntax only (fast)
    PtcRunner.Lisp.ClojureValidator.validate_syntax("(+ 1 2)")

    # Execute and get result
    PtcRunner.Lisp.ClojureValidator.execute("(+ 1 2)")

## Installation

Install Babashka with: `mix ptc.install_babashka`

# `available?`

```elixir
@spec available?() :: boolean()
```

Check if Babashka is available.

Looks for `bb` at `_build/tools/bb` first, then in system PATH.

# `bb_path`

```elixir
@spec bb_path() :: String.t() | nil
```

Get the path to the Babashka binary.

Returns `nil` if not found.

# `compare_results`

```elixir
@spec compare_results(any(), any()) :: :match | {:mismatch, String.t()}
```

Compare a PTC-Lisp result with a Clojure result.

Handles normalization of types that differ between systems:
- Elixir atoms vs Clojure keywords
- Map key type differences

Returns `:match` if equivalent, `{:mismatch, details}` otherwise.

# `execute`

```elixir
@spec execute(
  String.t(),
  keyword()
) :: {:ok, any()} | {:error, String.t()}
```

Execute source in Babashka and return the result.

## Options

  * `:timeout` - Timeout in milliseconds (default: 5000)
  * `:context` - Context map to inject as `ctx` binding
  * `:memory` - Memory map to inject as `memory` binding

## Examples

    iex> PtcRunner.Lisp.ClojureValidator.execute("(+ 1 2 3)")
    {:ok, 6}

    iex> PtcRunner.Lisp.ClojureValidator.execute("(filter even? [1 2 3 4])")
    {:ok, [2, 4]}

# `validate_syntax`

```elixir
@spec validate_syntax(String.t()) :: :ok | {:error, String.t()}
```

Validate that source is valid Clojure syntax.

Returns `:ok` if valid, `{:error, reason}` if invalid.

## Examples

    iex> PtcRunner.Lisp.ClojureValidator.validate_syntax("(+ 1 2)")
    :ok

    iex> PtcRunner.Lisp.ClojureValidator.validate_syntax("(+ 1 2")
    {:error, "Syntax error: ..."}

# `wrap_with_stubs`

```elixir
@spec wrap_with_stubs(String.t(), map(), map()) :: String.t()
```

Wrap PTC-Lisp source with Clojure stubs for PTC-specific features.

Adds definitions for:
- `ctx` - Context data as a map
- `memory` - Memory data as a map
- PTC-specific aggregator/tool stubs (`sum-by`, `avg-by`, `min-by`, `max-by`,
  `pmap`, `pcalls`, `call`, …)

---

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