Skip to main content

sim_codec_lisp/
lib.rs

1//! General-purpose Lisp codec for the SIM runtime: the s-expression surface
2//! that round-trips every expression through the shared `Expr` graph.
3//!
4//! A decoder lexes and reads parenthesized s-expression text into checked
5//! `Expr` forms; an encoder serializes any `Expr` back to Lisp text aware of
6//! its output position (eval, quote, data, pattern). Because the codec covers
7//! the full expression graph rather than a single domain, it can faithfully
8//! represent any value the kernel can hold.
9//!
10//! # Module map
11//!
12//! The crate's behavior lives behind the private `implementation` module, whose
13//! public items are re-exported at the crate root. Internally that module
14//! aggregates: `lex` (tokenizing Lisp source into tokens and trivia), `tree`
15//! (reading a token stream into a located expression tree), `decode`
16//! (the `Decoder`/`TreeDecoder`/`LocatedDecoder` entry points and surface
17//! lowering), `forms` (parsing individual atoms, literals, symbols, logic
18//! variables, and quote forms), `encode` (the `Encoder`/`TreeEncoder` rendering
19//! of `Expr` back to text), and `runtime` (the `Lib` registration wiring the
20//! codec into the runtime). `RECIPES` exposes the embedded cookbook recipes.
21//!
22//! # Examples
23//!
24//! Register the codec, decode s-expression text into an [`Expr`], then encode an
25//! `Expr` back to Lisp text:
26//!
27//! ```
28//! use std::sync::Arc;
29//! use sim_codec::{Input, decode_with_codec, encode_with_codec};
30//! use sim_codec_lisp::LispCodecLib;
31//! use sim_kernel::{
32//!     Cx, DefaultFactory, EagerPolicy, Expr, ReadPolicy, Symbol,
33//! };
34//!
35//! let mut cx = Cx::new(Arc::new(EagerPolicy), Arc::new(DefaultFactory));
36//! sim_test_support::register_core_classes(&mut cx);
37//! sim_test_support::register_f64_number_domain(&mut cx);
38//!
39//! let lib = LispCodecLib::new(cx.registry_mut().fresh_codec_id())?;
40//! cx.load_lib(&lib)?;
41//! let lisp = Symbol::qualified("codec", "lisp");
42//!
43//! // Decode text into a checked `Expr` form.
44//! let expr = decode_with_codec(
45//!     &mut cx,
46//!     &lisp,
47//!     Input::Text("(quote [1 2])".to_owned()),
48//!     ReadPolicy::default(),
49//! )?;
50//! assert!(matches!(expr, Expr::Quote { .. }));
51//!
52//! // Encode the `Expr` back to Lisp text (a semantic round-trip).
53//! let text = encode_with_codec(&mut cx, &lisp, &expr, Default::default())?
54//!     .into_text()
55//!     .unwrap();
56//! assert_eq!(text, "(quote [1 2])");
57//! # Ok::<(), sim_kernel::Error>(())
58//! ```
59//!
60//! The loadable codec lib also exports `cli/main/codec-lisp`. That entrypoint
61//! accepts the standard CLI envelope table, evaluates exactly one source from
62//! `eval`, `script`, or `stdin` through the active context eval policy, and
63//! returns a `cli/repl` marker for a bare handoff.
64//!
65//! [`Expr`]: sim_kernel::Expr
66#![deny(unsafe_code)]
67#![deny(missing_docs)]
68
69mod implementation;
70#[cfg(feature = "native-export")]
71mod loaders;
72#[cfg(feature = "native-export")]
73mod native;
74#[cfg(feature = "native-export")]
75extern crate self as sim;
76
77#[cfg(feature = "native-export")]
78use sim_codec as codec;
79#[cfg(feature = "native-export")]
80use sim_codec_binary as codec_binary;
81#[cfg(feature = "native-export")]
82use sim_kernel as kernel;
83#[cfg(feature = "native-export")]
84use sim_macros::{sim_codec, sim_lib};
85
86/// Cookbook recipes for the Lisp codec, embedded at build time from the crate's
87/// `recipes/` directory and exposed for help and browse surfaces.
88pub static RECIPES: sim_cookbook::EmbeddedDir =
89    include!(concat!(env!("OUT_DIR"), "/cookbook_recipes.rs"));
90
91pub use implementation::*;