Skip to main content

grift_core/
lib.rs

1#![no_std]
2#![forbid(unsafe_code)]
3#![allow(non_camel_case_types)]
4
5//! # Grift Core Types
6//!
7//! Core types and Lisp context for the Grift R7RS-compliant Scheme implementation.
8//!
9//! This crate contains the fundamental types shared between the parser and evaluator:
10//!
11//! - [`Value`] — The core value enum representing all Lisp types
12//! - [`Builtin`] — Enum of built-in functions  
13//! - [`StdLib`] — Enum of standard library functions
14//! - [`Lisp`] — The Lisp execution context wrapping an arena
15//!
16//! ## Design
17//!
18//! - Symbols use contiguous string storage for memory efficiency
19//! - Symbol interning ensures the same symbol name returns the same index
20//! - All values are stored in a `grift_arena` arena
21//! - Supports garbage collection via the `Trace` trait
22//! - Explicit boolean values (#t, #f) separate from nil/empty list
23//! - **Strict evaluation** - All arguments are evaluated before function application (call-by-value)
24//! - **Pluggable I/O** - The [`io`] module defines the [`IoProvider`] trait so the
25//!   evaluator stays `no_std` while real I/O can be supplied on hosted platforms
26//!   (see `grift_std::StdIoProvider`). A [`NullIoProvider`] is provided for
27//!   environments without I/O.
28//!
29//! ## Value Representation
30//!
31//! - `Nil` - The empty list (NOT false!)
32//! - `True` - Boolean true (#t)
33//! - `False` - Boolean false (#f)
34//! - `Number(isize)` - Integer numbers
35//! - `Char(char)` - Single character
36//! - `Cons { car, cdr }` - Pair/list cell with inline indices
37//! - `Symbol(ArenaIndex)` - Symbol pointing to interned string
38//! - `Lambda { params, body_env }` - Closure with inline indices
39//! - `Builtin(Builtin)` - Optimized built-in function
40//! - `StdLib(StdLib)` - Standard library function (static code, parsed on-demand)
41//! - `Array { len, data }` - Vector with inline length
42//! - `String { len, data }` - String with inline length
43//! - `Native { id }` - Native Rust function reference
44//!
45//! ## Reserved Slots
46//!
47//! The Lisp singleton values (nil, true, false) are pre-allocated in reserved
48//! slots at initialization time.
49//!
50//! The first 4 slots of the arena are reserved:
51//! - Slot 0: `Value::Nil` - empty list singleton
52//! - Slot 1: `Value::True` - boolean true singleton
53//! - Slot 2: `Value::False` - boolean false singleton
54//! - Slot 3: `Value::Cons` - intern table reference cell
55//!
56//! ## Pitfalls and Gotchas
57//!
58//! ### Truthiness
59//! - **Only `#f` is false!** Everything else is truthy, including:
60//!   - `nil` / `'()` (the empty list)
61//!   - `0` (the number zero)
62//!   - Empty strings
63//!
64//! ### Garbage Collection
65//! - The intern table is always a GC root - interned symbols are never collected
66//! - Reserved slots (nil, true, false) are implicitly preserved
67//! - Run `gc()` with appropriate roots to reclaim memory
68//!
69//! ### StdLib Functions
70//! - Body is parsed on each call (minor overhead, but keeps code out of arena)
71//! - Recursive stdlib functions work via the global environment
72//! - Errors in static source strings are only caught at runtime
73
74pub use grift_arena::{Arena, ArenaIndex, ArenaError, ArenaResult, Trace, GcStats};
75
76/// Platform-dependent floating-point type, matching the width of `isize`/`usize`.
77///
78/// On 64-bit platforms this is `f64`; on 32-bit platforms it is `f32`.
79/// This provides a consistent numeric tower where the float type has the same
80/// bit-width as the native integer types.
81#[cfg(target_pointer_width = "64")]
82pub type fsize = f64;
83
84/// Platform-dependent floating-point type (32-bit variant).
85#[cfg(target_pointer_width = "32")]
86pub type fsize = f32;
87
88/// The combined prelude source containing all macro and function definitions.
89///
90/// This is the raw content of `prelude.scm`, embedded at compile time.
91/// The evaluator uses this to load standard macros at startup.
92pub const PRELUDE_SOURCE: &str = include_str!("prelude.scm");
93
94// Macros module (must be declared before other modules that use the macros)
95#[macro_use]
96mod macros;
97
98mod value;
99mod lisp;
100mod display;
101pub mod io;
102pub mod libraries;
103
104pub use value::{Value, Builtin, StdLib};
105// Note: define_builtins and define_stdlib macros are exported at crate root via #[macro_export]
106
107pub use lisp::{Lisp, RESERVED_SLOTS};
108pub use display::DisplayValue;
109pub use io::{IoProvider, NullIoProvider, PortId, IoErrorKind, IoResult, DisplayPort};