tatara_lisp_script/lib.rs
1//! tatara-lisp-script — scripting surface for tatara-lisp.
2//!
3//! Wraps `tatara-lisp-eval::Interpreter<ScriptCtx>` with a batteries-included
4//! stdlib (http, json, yaml, sops, file I/O, env, sha256, string ops) so a
5//! `.tlisp` file can replace a bash script. The binary (`tatara-script`)
6//! parses a .tlisp file, expands macros via tatara-lisp, and evaluates each
7//! form against this stdlib.
8//!
9//! # Usage from nix-run
10//!
11//! ```nix
12//! apps.tatara-script = {
13//! type = "app";
14//! program = "${tataraScript}/bin/tatara-script path/to/script.tlisp";
15//! };
16//! ```
17//!
18//! # Library surface
19//!
20//! Embedders that want to add domain-specific FFI on top of the stdlib can:
21//!
22//! ```rust,ignore
23//! use tatara_lisp_script::{Interpreter, ScriptCtx, install_stdlib};
24//!
25//! let mut interp: Interpreter<ScriptCtx> = Interpreter::new();
26//! let mut ctx = ScriptCtx::default();
27//! install_stdlib(&mut interp, &mut ctx);
28//! // Register more fns before eval_program.
29//! ```
30
31pub mod script_ctx;
32pub mod stdlib;
33
34pub use script_ctx::ScriptCtx;
35pub use stdlib::install_stdlib;
36
37// Re-export the evaluator so embedders don't have to depend on tatara-lisp-eval
38// directly.
39pub use tatara_lisp::{read_spanned, Spanned};
40pub use tatara_lisp_eval::{Arity, EvalError, Interpreter, Value};
41
42/// Convenience: read + evaluate a tatara-lisp source string against a fresh
43/// interpreter with the full stdlib installed.
44///
45/// Primarily for tests and one-liner invocations. Binary entry points
46/// should construct the `Interpreter` directly to keep the host context
47/// available across calls.
48pub fn eval_str(src: &str) -> Result<Value, anyhow::Error> {
49 let forms = read_spanned(src).map_err(|e| anyhow::anyhow!("parse error: {e}"))?;
50 let mut interp: Interpreter<ScriptCtx> = Interpreter::new();
51 let mut ctx = ScriptCtx::default();
52 install_stdlib(&mut interp, &mut ctx);
53 interp
54 .eval_program(&forms, &mut ctx)
55 .map_err(|e| anyhow::anyhow!("eval error: {e:?}"))
56}