logicaffeine-base
Foundational infrastructure for the Logicaffeine ecosystem. This crate provides the low-level building blocks—arena allocation, string interning, source spans, and error handling—that all other logicaffeine crates depend on.
Overview
| Module | Purpose |
|---|---|
Arena<T> |
Bump allocation for AST nodes with stable references |
Interner/Symbol |
String interning with O(1) equality comparison |
Span |
Source location tracking (byte offsets) |
SpannedError/Result<T> |
Error handling with source positions |
Installation
[]
= "0.6"
Quick Start
use ;
// Arena for bump allocation
let arena: = new;
let value = arena.alloc;
assert_eq!;
// Interner for string deduplication
let mut interner = new;
let sym1 = interner.intern;
let sym2 = interner.intern;
assert_eq!; // O(1) comparison
// Span for source tracking
let span = new;
assert_eq!;
// Error with location
let err = new;
assert_eq!;
Module Reference
Arena
Bump allocation for stable AST references. All values live until the arena is dropped or reset.
use Arena;
let arena: = new;
// Allocate single value
let s = arena.alloc;
// Allocate slice from iterator
let nums = arena.alloc_slice;
| Method | Description |
|---|---|
Arena::new() |
Create empty arena |
arena.alloc(value) |
Allocate value, return stable reference |
arena.alloc_slice(iter) |
Allocate slice from ExactSizeIterator |
arena.reset() |
Clear arena, reuse capacity (REPL-friendly) |
Interner / Symbol
String interning for O(1) equality. Each unique string is stored once; comparing symbols is just comparing integers.
use ;
let mut interner = new;
let hello = interner.intern;
let world = interner.intern;
// O(1) equality
assert_ne!;
// Resolve back to string
assert_eq!;
// SymbolEq trait for convenience
assert!;
| Method | Description |
|---|---|
Interner::new() |
Create interner (empty string pre-interned) |
interner.intern(s) |
Get or create symbol for string |
interner.resolve(sym) |
Get original string from symbol |
interner.lookup(s) |
Non-interning lookup, returns Option<Symbol> |
interner.len() |
Count of interned strings |
Symbol::EMPTY |
Pre-interned empty string constant |
symbol.index() |
Internal index for dense storage |
Span
Byte-offset range in source text. Matches Rust's string slicing: &source[span.start..span.end].
use Span;
let source = "hello world";
let hello = new;
let world = new;
assert_eq!;
// Merge spans for compound expressions
let full = hello.merge;
assert_eq!;
assert_eq!;
| Method | Description |
|---|---|
Span::new(start, end) |
Create from byte offsets |
span.merge(other) |
Combine two spans (min start, max end) |
span.len() |
Length in bytes |
span.is_empty() |
True if zero-length |
span.start / span.end |
Public fields for direct access |
SpannedError / Result
Errors annotated with source location. Implements std::error::Error.
use ;
let err = parse_number.unwrap_err;
// Display: "invalid number: 'abc' at 0..3"
| Type | Description |
|---|---|
SpannedError |
Error with message: String and span: Span |
Result<T> |
Alias for std::result::Result<T, SpannedError> |
Design Principles
- No vocabulary knowledge: This crate knows nothing about English or natural language
- No I/O: Pure data structures only
- Minimal dependencies: Only
bumpalofor arena allocation - Foundation layer: All other logicaffeine crates build on these types
Dependencies
= "3.19"
License
Business Source License 1.1 (BUSL-1.1)
- Free for individuals and organizations with <25 employees
- Commercial license required for organizations with 25+ employees offering Logic Services
- Converts to MIT on December 24, 2029
See LICENSE for full terms.