Embed the Scarp interpreter in Rust
Experimental API, v0.0.5-alpha.1. The scarp crate can be used as a local path dependency in a Rust host. It is not a Scarp standard-library module and does not imply a published crate-registry package or native .srp compilation.
Choose the API for your task
| API | Purpose | Runs selected arithmetic? | Writes output? |
|---|---|---|---|
scarp::parse(source) |
Construct syntax AST | No | No |
scarp::compile(source) |
Resolve names/types to an immutable plan | No | No |
scarp::check(source) |
Validate and evaluate the selected path | Yes | No |
scarp::run(source, writer) |
Execute with explicit output | Yes | stdout writer |
scarp::run_with_io(source, out, err) |
Execute with two writers | Yes | Both writers |
modules::compile_file(path, limits) |
Compile an entry and its relative imports | No | No |
modules::compile_with_loader(path, loader, limits) |
Compile a virtual source graph | No | No |
Source-string APIs do not load imports implicitly. For multi-file source, use a module API. The Rust host owns the output writers and is responsible for their final flush policy.
Single-file execution without global output redirection
fn main() -> Result<(), Box<dyn std::error::Error>> {
let source = r#"print("Hello from Scarp!");"#;
let mut output = Vec::new();
scarp::run(source, &mut output)?;
assert_eq!(output, b"Hello from Scarp!\n");
Ok(())
}
The compiler builds a plan and validates the selected execution before replaying output. Source errors and runtime-budget failures produce no program output. A writer I/O error may still leave previously written bytes.
File-based modules
use scarp::{modules, ExecutionOptions};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let limits = modules::ModuleLimits::default();
let program = modules::compile_file("main.srp", limits)?;
program.check(ExecutionOptions::default())?;
let (mut out, mut err) = (Vec::new(), Vec::new());
program.execute(&mut out, &mut err, ExecutionOptions::default())?;
Ok(())
}
The host chooses ModuleLimits and execution options independently. For untrusted virtual sources, supply a custom or in-memory SourceLoader rather than assuming the default filesystem loader is a secure sandbox.
Lifecycle and compatibility
Compiled plans are immutable. Every execution starts fresh storage and budget counters, so a previous run's mutations do not persist. Return values, captured output and numerical windows can retain immutable shared backing storage even after a local binding retires.
Exact Rust types and signatures may change in later prereleases. If you need to embed Scarp, pin your path checkout to a specific commit or release and run the compiler's Rust tests. Refer to the official embedding guide, module loader docs, and module source code.