# cljrs-eval
IR-accelerated evaluation for clojurust. Wraps the tree-walking interpreter
(`cljrs-interp`) with IR lowering and interpretation for faster function
execution.
**Phase:** IR tier-1 interpreter — implemented.
---
## Purpose
When a Clojure function has been lowered to IR (eagerly at definition time via
the `on_fn_defined` hook, or from a pre-built cache), calls are dispatched to
the tier-1 IR interpreter. Otherwise they fall back to the tree-walking
interpreter in `cljrs-interp`.
The crate also manages the Clojure compiler namespaces (`cljrs.compiler.anf`,
`cljrs.compiler.ir`, `cljrs.compiler.known`) that perform ANF lowering of
Clojure source to the IR representation defined in `cljrs-ir`.
---
## File layout
```
src/
lib.rs — module declarations, re-exports, standard_env_minimal/standard_env/standard_env_with_paths,
register_compiler_sources, ensure_compiler_loaded
apply.rs — IR-aware function dispatch: tries IR cache, falls back to cljrs_interp::apply
ir_interp.rs — tier-1 IR interpreter: executes IrFunction over a VarId→Value register file
ir_cache.rs — thread-safe cache of lowered IR keyed by arity ID (NotAttempted/Cached/Unsupported)
ir_convert.rs — converts Clojure Value data structures (maps/vectors/keywords) → Rust IR types
lower.rs — bridges the Clojure compiler front-end (cljrs.compiler.anf/lower-fn-body) to produce IrFunction
```
---
## Public API
```rust
/// Re-exports from cljrs-interp and cljrs-env:
pub use cljrs_interp::eval::eval;
pub use cljrs_env::env::{Env, GlobalEnv};
pub use cljrs_env::error::{EvalError, EvalResult};
pub use cljrs_env::callback::invoke;
pub use cljrs_env::loader::load_ns;
/// Create a minimal GlobalEnv with IR-accelerated eval/call dispatch.
/// Passes cljrs-eval's apply::call_cljrs_fn (IR + tree-walk fallback)
/// and eager_lower_fn hook to cljrs-interp's standard_env_minimal.
pub fn standard_env_minimal() -> Arc<GlobalEnv>;
/// Like standard_env_minimal() but also registers compiler sources.
pub fn standard_env() -> Arc<GlobalEnv>;
/// Like standard_env() but also sets user source paths.
pub fn standard_env_with_paths(source_paths: Vec<PathBuf>) -> Arc<GlobalEnv>;
/// Register the Clojure compiler namespace sources into the GlobalEnv.
pub fn register_compiler_sources(globals: &Arc<GlobalEnv>);
/// Load the Clojure compiler namespaces and mark the compiler as ready
/// for IR lowering. Thread-safe; idempotent.
pub fn ensure_compiler_loaded(globals: &Arc<GlobalEnv>, env: &mut Env) -> bool;
/// Load pre-built IR from a serialized bundle into the IR cache.
/// Walks all namespaces, matches bundle keys to runtime arity IDs.
/// Returns the number of arities loaded.
pub fn load_prebuilt_ir(globals: &Arc<GlobalEnv>, bundle: &IrBundle) -> usize;
```
---
## IR dispatch flow
1. `apply::call_cljrs_fn` is registered as the `call_cljrs_fn` function pointer in `GlobalEnv`
2. On each call, it checks `ir_cache::get_cached(arity_id)` for a pre-lowered IR function
3. If cached: executes via `ir_interp::interpret_ir` (register-file interpreter)
4. If not cached: falls back to `cljrs_interp::apply::call_cljrs_fn` (tree-walking)
5. Eager lowering: `ir_interp::eager_lower_fn` is registered as the `on_fn_defined` hook;
when `compiler_ready` is true, new `fn*` definitions are lowered immediately
---
## Dependencies
| `cljrs-interp` | Tree-walking interpreter (fallback) |
| `cljrs-env` | `Env`, `GlobalEnv`, `EvalError`, callbacks, loader |
| `cljrs-builtins` | `form_to_value` (used by `lower.rs`) |
| `cljrs-ir` | IR types (`IrFunction`, `Block`, `Inst`, etc.) and compiler source strings |
| `cljrs-types` | `Span` |
| `cljrs-gc` | `GcPtr<T>` |
| `cljrs-reader` | `Form` AST (for compiler loading) |
| `cljrs-value` | `Value`, `CljxFn`, collections |