engawa-lisp 0.1.3

Tatara-lisp authoring layer for engawa render graphs. Operators write (defmaterial …) / (defgraph …) / (defeffect …) in a .tlisp file; this crate parses + lowers to engawa::RenderGraph. Pairs with shikumi's notify watcher for hot-reload.
Documentation
//! Tatara-lisp authoring layer for engawa render graphs.
//!
//! Operators write effect declarations in a `.tlisp` file:
//!
//! ```text
//! (defmaterial scanlines
//!   (shader (inline "..."))
//!   (bindings
//!     (binding 0 uniform "frame")
//!     (binding 1 texture "scene")
//!     (binding 2 sampler "scene-sampler")))
//!
//! (defresource swap external)
//! (defresource scene (texture 800 600))
//! (defresource post (texture 800 600))
//!
//! (defgraph mado-pipeline
//!   (input swap)
//!   (output post)
//!   (node clear-scene (kind clear) (output scene))
//!   (node scanlines-pass (kind fullscreen-effect)
//!     (material scanlines)
//!     (input scene)
//!     (output post)))
//! ```
//!
//! …and this crate parses + lowers to `engawa::RenderGraph`.
//! Pairs with shikumi's notify watcher for live hot-reload —
//! save the `.tlisp`, the graph rebuilds, the dispatcher picks
//! up the new topology without a restart.
//!
//! ## Why a custom lisp parser
//!
//! The full `tatara-lisp` macro engine is heavy. For engawa's
//! IR — which is intentionally small (8 types) — a minimal
//! sexpr parser + typed lowering does the job in ~600 LOC.
//! When the tatara-lisp ecosystem stabilises (caixa-author
//! lands, the macro engine becomes reusable across consumers),
//! engawa-lisp migrates to lean on it.
//!
//! Today: round-trip-tested sexpr parser, every parse error
//! carries operator-friendly context (line:col + the form being
//! parsed), 30+ unit tests.

#![forbid(unsafe_code)]
#![doc(html_root_url = "https://docs.rs/engawa-lisp/0.1.0")]

pub mod lower;
pub mod parse;
pub mod sexpr;

pub use lower::{lower_to_graph, LowerError};
pub use parse::{ParseError, Span};
pub use sexpr::{Sexpr, SexprKind};

/// One-call helper: parse a `.tlisp` source string, lower to an
/// `engawa::RenderGraph`. Returns the graph ready for compile;
/// the caller chains `.compile()` to get a `CompiledGraph` for
/// dispatch.
pub fn parse_and_lower(
    source: &str,
) -> Result<engawa::RenderGraph, EngawaLispError> {
    let forms = parse::parse(source)?;
    let graph = lower::lower_to_graph(&forms)?;
    Ok(graph)
}

#[derive(Debug, thiserror::Error)]
pub enum EngawaLispError {
    #[error("parse error: {0}")]
    Parse(#[from] ParseError),
    #[error("lower error: {0}")]
    Lower(#[from] LowerError),
}