grift/lib.rs
1//! # Grift
2//!
3//! A minimal `no_std`, `no_alloc` R7RS-compliant Scheme implementation built on
4//! arena-based garbage collection. Perfect for embedded systems, WebAssembly, or any
5//! environment where heap allocation is unavailable or undesirable.
6//!
7//! ## Features
8//!
9//! - **`no_std`, `no_alloc` by default** — Runs on bare metal
10//! - **Arena-based allocation** — Fixed memory footprint, no heap
11//! - **Mark-and-sweep GC** — Controllable from Scheme code
12//! - **Proper tail-call optimization** — Via trampolining
13//! - **Lexical closures** — First-class functions with captured environments
14//! - **R7RS-compliant** — Scheme semantics following the Revised⁷ Report
15//! - **Pluggable I/O** — Trait-based I/O boundary (`IoProvider`) keeps the
16//! evaluator `no_std` while allowing real I/O on hosted platforms
17//! - **Native FFI** — Register Rust functions callable from Scheme
18//! - **Embedded support** — Optional hardware natives for GPIO, memory
19//! peek/poke, and bit manipulation
20//!
21//! ## Quick Start
22//!
23//! ```rust
24//! use grift::{Lisp, Evaluator, Value};
25//!
26//! // Create a Lisp interpreter with a 20,000-cell arena
27//! let lisp: Lisp<20000> = Lisp::new();
28//! let mut eval = Evaluator::new(&lisp).unwrap();
29//!
30//! // Evaluate expressions
31//! let result = eval.eval_str("(+ 1 2 3)").unwrap();
32//! assert!(matches!(lisp.get(result), Ok(Value::Number(6))));
33//! ```
34//!
35//! ## Optional `std` Feature
36//!
37//! Enable the `std` feature for an interactive REPL and real I/O:
38//!
39//! ```toml
40//! [dependencies]
41//! grift = { version = "1.3", features = ["std"] }
42//! ```
43//!
44//! The `std` feature brings in:
45//! - [`grift_repl`] — Interactive REPL with line editing, GC commands, and help
46//! - [`grift_std`] — `StdIoProvider`, an [`IoProvider`] implementation using
47//! `std::io` for stdin/stdout/stderr and dynamic string ports
48//!
49//! Then run:
50//!
51//! ```bash
52//! cargo install grift --features std
53//! grift
54//! ```
55//!
56//! ## I/O Architecture
57//!
58//! The evaluator is fully `no_std` and performs no I/O itself. Instead, an
59//! [`IoProvider`] trait (defined in `grift_core`) abstracts all port
60//! operations:
61//!
62//! - **[`NullIoProvider`]** — No-op implementation that silently discards
63//! output and rejects reads. Used in `no_std`/embedded contexts where
64//! there is no real I/O.
65//! - **`StdIoProvider`** (behind `std` feature) — Full implementation
66//! backed by `std::io`, providing stdin/stdout/stderr and dynamic string
67//! ports.
68//!
69//! Pass any `IoProvider` to the evaluator at runtime:
70//!
71//! ```rust,ignore
72//! use grift::{Lisp, Evaluator, NullIoProvider};
73//!
74//! let lisp: Lisp<20000> = Lisp::new();
75//! let mut eval = Evaluator::new(&lisp).unwrap();
76//! let mut io = NullIoProvider;
77//! eval.set_io_provider(&mut io);
78//! ```
79//!
80//! ## Crate Organization
81//!
82//! This crate re-exports the complete Grift stack:
83//!
84//! - [`grift_arena`] — Fixed-size arena allocator with mark-and-sweep GC
85//! - [`grift_core`] — Core types (`Value`, `Builtin`, `StdLib`, `Lisp`)
86//! and the `IoProvider` trait boundary
87//! - [`grift_parser`] — Lexer and parser
88//! - [`grift_eval`] — Fully-trampolined evaluator with native FFI
89//! - [`grift_repl`] — Interactive REPL (behind `std` feature)
90//! - [`grift_std`] — `StdIoProvider` for hosted I/O (behind `std` feature)
91//! - [`grift_macros`] — Procedural macros (`include_stdlib!`)
92//! - [`grift_util`] — Shared utilities (Scheme-name ↔ Rust-name conversion)
93//! - [`grift_arena_embedded`] — Embedded hardware natives (GPIO, peek/poke,
94//! bit manipulation)
95
96#![no_std]
97#![forbid(unsafe_code)]
98#![cfg_attr(docsrs, feature(doc_cfg))]
99
100// ============================================================================
101// Core Re-exports from grift_arena
102// ============================================================================
103
104/// Arena allocator and garbage collection primitives.
105pub mod arena {
106 pub use grift_arena::{
107 Arena, ArenaIndex, ArenaError, ArenaResult,
108 GcStats, Trace,
109 };
110}
111
112pub use arena::{Arena, ArenaIndex, ArenaError, ArenaResult, GcStats, Trace};
113
114// ============================================================================
115// Core Types Re-exports from grift_core
116// ============================================================================
117
118/// Core value types and Lisp context.
119pub mod core_types {
120 pub use grift_core::{
121 Value, Builtin, StdLib, Lisp, RESERVED_SLOTS,
122 DisplayValue,
123 define_builtins, define_stdlib,
124 // I/O trait boundary
125 IoProvider, NullIoProvider, PortId, IoErrorKind, IoResult, DisplayPort,
126 };
127}
128
129// ============================================================================
130// Parser Re-exports from grift_parser
131// ============================================================================
132
133/// Parser, lexer, value types, and built-in definitions.
134pub mod parser {
135 pub use grift_parser::{
136 // Core types (re-exported from grift_core)
137 Value, Builtin, StdLib, Lisp, DisplayValue,
138 // Lexer
139 Lexer, Token, SpannedToken, LexError, LexErrorKind,
140 // Parsing
141 parse, parse_all, Parser, ParseError, ParseErrorKind, SourceLoc,
142 // Macros
143 define_builtins, define_stdlib,
144 };
145}
146
147pub use parser::{
148 Value, Builtin, StdLib, Lisp, DisplayValue,
149 Lexer, Token, SpannedToken, LexError, LexErrorKind,
150 parse, parse_all, Parser, ParseError, ParseErrorKind, SourceLoc,
151 define_builtins, define_stdlib,
152};
153
154// ============================================================================
155// Evaluator Re-exports from grift_eval
156// ============================================================================
157
158/// Evaluator, error handling, and native function interop.
159pub mod eval {
160 pub use grift_eval::{
161 // Evaluator
162 Evaluator, EvalError, EvalResult, ErrorKind, StackFrame,
163 // Native FFI
164 FromLisp, ToLisp, NativeRegistry, NativeEntry, NativeFn,
165 extract_arg, args_empty, count_args, MAX_NATIVE_FUNCTIONS,
166 };
167}
168
169pub use eval::{
170 Evaluator, EvalError, EvalResult, ErrorKind, StackFrame,
171 FromLisp, ToLisp, NativeRegistry, NativeEntry, NativeFn,
172 extract_arg, args_empty, count_args, MAX_NATIVE_FUNCTIONS,
173};
174
175// ============================================================================
176// REPL Re-exports (std feature only)
177// ============================================================================
178
179/// REPL and formatting utilities (requires `std` feature).
180#[cfg(feature = "std")]
181#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
182pub mod repl {
183 pub use grift_repl::{
184 run_repl, Repl,
185 format_value, format_error, value_to_string, eval_to_string,
186 };
187}
188
189#[cfg(feature = "std")]
190#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
191pub use repl::{
192 run_repl, Repl,
193 format_value, format_error, value_to_string, eval_to_string,
194};
195
196// ============================================================================
197// I/O Trait Re-exports from grift_core (always available, no_std compatible)
198// ============================================================================
199
200pub use grift_core::{
201 IoProvider, NullIoProvider, PortId, IoErrorKind, IoResult, DisplayPort,
202};
203
204// ============================================================================
205// Standard I/O Re-exports from grift_std (std feature only)
206// ============================================================================
207
208/// Standard library I/O provider (requires `std` feature).
209#[cfg(feature = "std")]
210#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
211pub mod std_io {
212 pub use grift_std::{StdIoProvider};
213}
214
215#[cfg(feature = "std")]
216#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
217pub use std_io::StdIoProvider;