# `Puck.Sandbox.Eval`
[🔗](https://github.com/bradleygolden/puck/blob/v0.2.25/lib/puck/sandbox/eval.ex#L1)

In-process code evaluation in sandboxed interpreters.

Puck.Sandbox.Eval provides a unified API for evaluating code snippets in
sandboxed interpreter environments. Unlike `Puck.Sandbox.Runtime` which
runs containers, Eval runs code in-process with memory and CPU limits.

## Supported Engines

- `:lua` - Lua 5.3 via Luerl (pure Erlang, requires `{:lua, "~> 0.4.0"}`)

## Usage

    # Simple eval
    {:ok, result} = Puck.Sandbox.Eval.eval(:lua, "return 1 + 2")

    # With callbacks to host functions
    {:ok, result} = Puck.Sandbox.Eval.eval(:lua, """
      local products = search("laptop")
      local cheap = {}
      for _, p in ipairs(products) do
        if p.price < 1000 then table.insert(cheap, p) end
      end
      return cheap
    """, callbacks: %{
      "search" => &MyApp.Products.search/1
    })

    # With resource limits
    {:ok, result} = Puck.Sandbox.Eval.eval(:lua, code,
      timeout_ms: 5_000,
      max_heap_words: 1_000_000
    )

## Safety

Code runs in a separate BEAM process with:
- CPU limits via timeout
- Memory limits via process heap limits
- No filesystem or network access (interpreter sandboxed)
- Crash isolation (pure Erlang, no NIF)

The only risk is user-provided callbacks.

# `code`

```elixir
@type code() :: String.t()
```

# `engine`

```elixir
@type engine() :: :lua
```

# `eval_opts`

```elixir
@type eval_opts() :: [
  callbacks: %{required(String.t()) =&gt; function()},
  timeout_ms: pos_integer(),
  max_heap_words: pos_integer()
]
```

# `engine_available?`

Checks if an engine is available.

## Examples

    true = Puck.Sandbox.Eval.engine_available?(:lua)
    false = Puck.Sandbox.Eval.engine_available?(:python)

# `engines`

Returns the list of available eval engines.

## Examples

    [:lua] = Puck.Sandbox.Eval.engines()

# `eval`

Evaluates code in the specified sandboxed interpreter.

## Engines

- `:lua` - Lua 5.3 (requires `{:lua, "~> 0.4.0"}`)

## Options

- `:callbacks` - Map of callback names to functions
- `:timeout_ms` - Execution timeout in ms (default: 5_000)
- `:max_heap_words` - Memory limit in words (default: 1_000_000, ~8MB)

## Examples

    {:ok, 3} = Puck.Sandbox.Eval.eval(:lua, "return 1 + 2")

    {:ok, result} = Puck.Sandbox.Eval.eval(:lua, """
      return double(21)
    """, callbacks: %{"double" => fn x -> x * 2 end})

    {:error, :timeout} = Puck.Sandbox.Eval.eval(:lua, "while true do end", timeout_ms: 100)

# `eval!`

Like `eval/3` but raises on error.

## Examples

    42 = Puck.Sandbox.Eval.eval!(:lua, "return 42")

---

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