Expand description
cel-rs provides a stack-based runtime for developing domain specific languages, including concatenative languages to describe concurrent processes. A sequence is a list of operations (the machine instructions). Each operation is a closure that takes it’s arguments from the stack and the result is pushed back onto the stack.
Segments can be created in two ways.
- Using the
DynSegmentstruct which validates the type safety of the operations at runtime as the segment is built. - Using the
Segmentstruct, which validates the type safety of the operations at compile time.
The two types of segments can be converted to each other [not yet implemented from Segment to
DynSegment].
Operations are added using the form op#[r] where # is the arity of the operation and the
optional r signifies that the operation returns a std::result::Result type and may fail.
§Composable canonical values
Array<T> owns actual contiguous T values. Array::into_vec and
Array::from_vec transfer allocations in O(1); Array::as_slice borrows
them. A nested array uses Array<Array<T>>: its vector view is
Vec<Array<T>>, not Vec<Vec<T>>. Deep native conversion builds a new outer
vector. Tuples use source-ordered CStackList values ending in CNil<()>,
bridged to native tuples by IntoCStackList and IntoRustTuple.
Source unit uses Nil, not an opaque host Leaf<()>.
ValueType records complete recursive identity/layout and optional
capabilities; ArrayOf, Cons, Nil, Leaf, and FnOf witness
concrete representations. Moving storage requires no clone/equality/debug
bounds. OwnedValue checks arbitrary erased external values, whereas
DynSegment::prepare binds a PreparedSegment once. Repeated prepared
calls borrow arguments and return independent owners without comparing
descriptors or downcasting. Runtime-bound hosts can instead prepare a
prepared_segment::PreparedRawSegment and uphold its unsafe pointer contract.
Callable binds native or prepared bodies to the same typed interface.
This is interoperability with native Rust, not a macro-compiled CEL backend.
use cel_runtime::{ArrayOf, Cons, IntoCStackList, IntoRustTuple, Leaf, Nil, DynSegment};
type Row = Cons<Leaf<i32>, Cons<Leaf<bool>, Nil>>;
let mut body = DynSegment::new::<()>();
body.just(7i32); body.just(true); body.make_tuple(2, 0).unwrap();
body.make_array(1, 0).unwrap();
let mut prepared = body.prepare::<Nil, ArrayOf<Row>>().unwrap();
let row = prepared.call(&().into_c_stack_list()).unwrap().into_vec().pop().unwrap();
assert_eq!(row.into_rust_tuple(), (7, true));§Examples
use cel_runtime::*;
// Create a segment that takes a u32 and &str as arguments
let segment = Segment::<(u32, &str)>::new()
.op1r(|s| {
let r = s.parse::<u32>()?;
Ok(r)
})
.op2(|a, b| a + b)
.op1(|r| r.to_string());
assert_eq!(segment.call((1u32, "2")).unwrap(), "3");Re-exports§
pub use array::Array;pub use callable::Callable;pub use dyn_closure::CallDynFn;pub use dyn_closure::DynClosure;pub use owned_value::OwnedValue;pub use prepared_segment::PreparedSegment;pub use value_type::ArgumentList;pub use value_type::ArrayOf;pub use value_type::AssociatedType;pub use value_type::Cons;pub use value_type::FnOf;pub use value_type::Leaf;pub use value_type::Nil;pub use value_type::ValueKind;pub use value_type::ValueRepr;pub use value_type::ValueType;pub use c_stack_list::*;pub use dyn_segment::*;pub use list_traits::*;pub use memory::*;pub use raw_segment::*;pub use raw_sequence::*;pub use raw_stack::*;pub use raw_vec::*;pub use segment::*;pub use tuple_list::*;
Modules§
- array
- Concrete typed ownership for homogeneous, contiguous arrays. Concrete, contiguous ownership for homogeneous CEL arrays.
- c_
stack_ list - Compile-time stack list implementation for type-safe stack operations.
A
CStackListis aListwith guaranteed memory layout (repr(C)). The tail is stored first, so appending items does not change the memory layout of prior items (though the required alignment may increase).CNil<T>represents the empty list whereTis used to hide the tail forstd::ops::RangeToandstd::ops::RangeToInclusiveindexing. - callable
- Signature-typed callable facade over the canonical shared carrier. Calls native and prepared bodies through one statically fixed signature.
- dyn_
closure - First-class callable CEL values with declared signatures. A first-class, callable CEL value: a compiled body plus its declared signature.
- dyn_
segment - Dynamic segment implementation with runtime type checking. Builds checked instructions for the canonical raw interpreter.
- list_
traits - Traits for working with type lists and type information. A collection of traits for homegenous lists (cons cells), similar to tuples.
- memory
- Memory management and alignment utilities for the runtime.
- owned_
value - Whole-value ownership with complete checked representation witnesses. Owns an erased whole value together with its frozen ownership descriptor.
- prepared_
segment - Prepared typed execution over the existing raw interpreter. Executes one construction-validated canonical borrowed frame.
- raw_
segment - Raw segment implementation without type safety.
- raw_
sequence - Raw sequence implementation for operation sequences.
- raw_
stack - Raw stack implementation for low-level stack operations.
- raw_vec
- Raw vector implementation for dynamic memory allocation.
- segment
- Type-safe segment implementation with compile-time validation.
- tuple_
list - Tuple list implementation for type-safe tuple operations.
Implements
Listfor tuples where()is an empty list and(H, T)is a list with a head and tail. - value_
type - Complete recursive canonical metadata and sealed concrete representation witnesses. Describes complete recursive identities independently of interpreter descriptors.