pub struct ShapeEngine {
pub runtime: Runtime,
pub default_data: DataFrame,
/* private fields */
}Expand description
The unified Shape execution engine
Fields§
§runtime: RuntimeThe runtime environment
default_data: DataFrameDefault data for expressions/assignments
Implementations§
Source§impl ShapeEngine
impl ShapeEngine
Sourcepub fn execute(
&mut self,
executor: &impl ProgramExecutor,
source: &str,
) -> Result<ExecutionResult>
pub fn execute( &mut self, executor: &impl ProgramExecutor, source: &str, ) -> Result<ExecutionResult>
Execute a Shape program from source code (sync mode)
This method allows blocking data loads (REPL mode). For scripts/backtests, use execute_async() instead.
Sourcepub async fn execute_async(
&mut self,
executor: &impl ProgramExecutor,
source: &str,
) -> Result<ExecutionResult>
pub async fn execute_async( &mut self, executor: &impl ProgramExecutor, source: &str, ) -> Result<ExecutionResult>
Execute a Shape program with async prefetching (Phase 6/8)
This method:
- Sets Async data mode (runtime data requests use cache, not blocking)
- Parses and analyzes the program
- Determines required data (symbols/timeframes)
- Prefetches data concurrently
- Executes synchronously using cached data
§Example
let provider = DataFrameAdapter::new(...);
let mut engine = ShapeEngine::with_async_provider(provider)?;
let result = engine.execute_async(&interpreter, "let sma = close.sma(20)").await?;Sourcepub async fn execute_repl(
&mut self,
executor: &impl ProgramExecutor,
source: &str,
) -> Result<ExecutionResult>
pub async fn execute_repl( &mut self, executor: &impl ProgramExecutor, source: &str, ) -> Result<ExecutionResult>
Execute a REPL command with persistent state
Unlike execute_async, this uses incremental analysis where variables
and functions persist across commands. Call init_repl() once before
the first call to this method.
Sourcepub fn parse_and_analyze(&mut self, source: &str) -> Result<Program>
pub fn parse_and_analyze(&mut self, source: &str) -> Result<Program>
Parse and analyze source code without executing it.
Returns the analyzed AST Program, ready for compilation.
Used by the recompile-and-resume flow.
Sourcepub fn execute_repl_command(
&mut self,
executor: &impl ProgramExecutor,
command: &str,
) -> Result<ExecutionResult>
pub fn execute_repl_command( &mut self, executor: &impl ProgramExecutor, command: &str, ) -> Result<ExecutionResult>
Execute a REPL command
Source§impl ShapeEngine
impl ShapeEngine
Sourcepub fn load_stdlib(&mut self) -> Result<()>
pub fn load_stdlib(&mut self) -> Result<()>
Load stdlib core modules only. Domain-specific modules (finance, iot, etc.) require explicit import.
Source§impl ShapeEngine
impl ShapeEngine
Sourcepub fn with_async_provider(provider: SharedAsyncProvider) -> Result<Self>
pub fn with_async_provider(provider: SharedAsyncProvider) -> Result<Self>
Create engine with async data provider (Phase 6)
This constructor sets up the engine with an async data provider.
Call execute_async() instead of execute() to use async prefetching.
Sourcepub fn init_repl(&mut self)
pub fn init_repl(&mut self)
Initialize REPL mode
Call this once after creating the engine and loading stdlib, but before executing any REPL commands. This sets up persistent state for the semantic analyzer and configures output adapters.
Sourcepub fn capture_bootstrap_state(&self) -> Result<EngineBootstrapState>
pub fn capture_bootstrap_state(&self) -> Result<EngineBootstrapState>
Capture semantic/runtime state after stdlib bootstrap.
Call this on an engine that has already loaded stdlib.
Sourcepub fn apply_bootstrap_state(&mut self, state: &EngineBootstrapState)
pub fn apply_bootstrap_state(&mut self, state: &EngineBootstrapState)
Apply a previously captured stdlib bootstrap state.
Sourcepub fn set_script_path(&mut self, path: impl Into<String>)
pub fn set_script_path(&mut self, path: impl Into<String>)
Set the script path for snapshot metadata.
Sourcepub fn script_path(&self) -> Option<&str>
pub fn script_path(&self) -> Option<&str>
Get the current script path, if set.
Sourcepub fn enable_snapshot_store(&mut self, store: SnapshotStore)
pub fn enable_snapshot_store(&mut self, store: SnapshotStore)
Enable snapshotting with a content-addressed store.
Sourcepub fn last_snapshot(&self) -> Option<&HashDigest>
pub fn last_snapshot(&self) -> Option<&HashDigest>
Get last snapshot ID, if any.
Sourcepub fn snapshot_store(&self) -> Option<&SnapshotStore>
pub fn snapshot_store(&self) -> Option<&SnapshotStore>
Access the snapshot store (if configured).
Sourcepub fn store_snapshot_blob<T: Serialize>(&self, value: &T) -> Result<HashDigest>
pub fn store_snapshot_blob<T: Serialize>(&self, value: &T) -> Result<HashDigest>
Store a serializable blob in the snapshot store and return its hash.
Sourcepub fn snapshot_with_hashes(
&mut self,
vm_hash: Option<HashDigest>,
bytecode_hash: Option<HashDigest>,
) -> Result<HashDigest>
pub fn snapshot_with_hashes( &mut self, vm_hash: Option<HashDigest>, bytecode_hash: Option<HashDigest>, ) -> Result<HashDigest>
Create a snapshot of semantic/runtime state, with optional VM/bytecode hashes supplied by the executor.
Sourcepub fn load_snapshot(
&self,
snapshot_id: &HashDigest,
) -> Result<(SemanticSnapshot, ContextSnapshot, Option<HashDigest>, Option<HashDigest>)>
pub fn load_snapshot( &self, snapshot_id: &HashDigest, ) -> Result<(SemanticSnapshot, ContextSnapshot, Option<HashDigest>, Option<HashDigest>)>
Load a snapshot and return its components (semantic/context + optional vm/bytecode hashes).
Sourcepub fn apply_snapshot(
&mut self,
semantic: SemanticSnapshot,
context: ContextSnapshot,
) -> Result<()>
pub fn apply_snapshot( &mut self, semantic: SemanticSnapshot, context: ContextSnapshot, ) -> Result<()>
Apply a semantic/context snapshot to the current engine.
Sourcepub fn register_extension_modules(&mut self, modules: &[ParsedModuleSchema])
pub fn register_extension_modules(&mut self, modules: &[ParsedModuleSchema])
Register extension module namespaces with the semantic analyzer.
Must be called before execute() so the type system recognizes modules like duckdb.
Sourcepub fn set_source(&mut self, source: &str)
pub fn set_source(&mut self, source: &str)
Set the current source text for error messages
Call this before execute() to enable source-contextualized error messages. The source is used during bytecode compilation to populate debug info.
Sourcepub fn current_source(&self) -> Option<&str>
pub fn current_source(&self) -> Option<&str>
Get the current source text (if set)
Sourcepub fn analyze_incremental(
&mut self,
program: &Program,
source: &str,
) -> Result<()>
pub fn analyze_incremental( &mut self, program: &Program, source: &str, ) -> Result<()>
Analyze a program incrementally (for REPL usage)
This maintains semantic state across calls, allowing variables
and functions defined in previous commands to be visible.
Call init_repl() first.
Sourcepub fn register_provider(&mut self, name: &str, provider: SharedAsyncProvider)
pub fn register_provider(&mut self, name: &str, provider: SharedAsyncProvider)
Sourcepub fn set_default_provider(&mut self, name: &str) -> Result<()>
pub fn set_default_provider(&mut self, name: &str) -> Result<()>
Set default data provider (Phase 8)
Sets which provider to use for runtime data access when no provider is specified.
Sourcepub fn register_type_mapping(&mut self, type_name: &str, mapping: TypeMapping)
pub fn register_type_mapping(&mut self, type_name: &str, mapping: TypeMapping)
Register a type mapping (Phase 8)
Registers a type mapping that defines the expected DataFrame structure for a given type name. Type mappings enable validation and JIT optimization.
§Example
use shape_core::runtime::type_mapping::TypeMapping;
// Register the Candle type (from stdlib)
let candle_mapping = TypeMapping::new("Candle".to_string())
.add_field("timestamp", "timestamp")
.add_field("open", "open")
.add_field("high", "high")
.add_field("low", "low")
.add_field("close", "close")
.add_field("volume", "volume")
.add_required("timestamp")
.add_required("open")
.add_required("high")
.add_required("low")
.add_required("close");
engine.register_type_mapping("Candle", candle_mapping);Sourcepub fn get_runtime(&self) -> &Runtime
pub fn get_runtime(&self) -> &Runtime
Get the current runtime state (for REPL)
Sourcepub fn get_runtime_mut(&mut self) -> &mut Runtime
pub fn get_runtime_mut(&mut self) -> &mut Runtime
Get mutable runtime (for REPL state updates)
Sourcepub fn get_variable_format_hint(&self, name: &str) -> Option<String>
pub fn get_variable_format_hint(&self, name: &str) -> Option<String>
Get the format hint for a variable (if any)
Returns the format hint specified in the variable’s type annotation.
Example: let rate: Number @ Percent = 0.05 → Some(“Percent”)
Sourcepub fn format_value_string(
&mut self,
value: f64,
type_name: &str,
format_name: Option<&str>,
params: &HashMap<String, Value>,
) -> Result<String>
pub fn format_value_string( &mut self, value: f64, type_name: &str, format_name: Option<&str>, params: &HashMap<String, Value>, ) -> Result<String>
Format a value using Shape runtime format evaluation
This uses the format definitions from stdlib (e.g., stdlib/core/formats.shape) instead of Rust fallback formatters.
§Arguments
value- The value to format (as f64 for numbers)type_name- The Shape type name (“Number”, “String”, etc.)format_name- Optional format name (e.g., “Percent”, “Currency”). Uses default if None.params- Format parameters as JSON (e.g., {“decimals”: 1})
§Returns
Formatted string on success
§Example
let formatted = engine.format_value_string(
0.1234,
"Number",
Some("Percent"),
&HashMap::new()
)?;
assert_eq!(formatted, "12.34%");Sourcepub fn load_extension(
&mut self,
path: &Path,
config: &Value,
) -> Result<LoadedExtension>
pub fn load_extension( &mut self, path: &Path, config: &Value, ) -> Result<LoadedExtension>
Load a data source extension from a shared library
§Arguments
path- Path to the extension shared library (.so, .dll, .dylib)config- Configuration value for the extension
§Returns
Information about the loaded extension
§Safety
Loading extensions executes arbitrary code. Only load from trusted sources.
§Example
let info = engine.load_extension(Path::new("./libshape_ext_csv.so"), &json!({}))?;
println!("Loaded: {} v{}", info.name, info.version);Sourcepub fn unload_extension(&mut self, name: &str) -> bool
pub fn unload_extension(&mut self, name: &str) -> bool
Sourcepub fn list_extensions(&self) -> Vec<String>
pub fn list_extensions(&self) -> Vec<String>
List all loaded extension names
Sourcepub fn get_extension_query_schema(
&self,
name: &str,
) -> Option<ParsedQuerySchema>
pub fn get_extension_query_schema( &self, name: &str, ) -> Option<ParsedQuerySchema>
Sourcepub fn get_extension_output_schema(
&self,
name: &str,
) -> Option<ParsedOutputSchema>
pub fn get_extension_output_schema( &self, name: &str, ) -> Option<ParsedOutputSchema>
Sourcepub fn get_extension(&self, name: &str) -> Option<Arc<ExtensionDataSource>>
pub fn get_extension(&self, name: &str) -> Option<Arc<ExtensionDataSource>>
Get an extension data source by name
Sourcepub fn get_extension_module_schema(
&self,
module_name: &str,
) -> Option<ParsedModuleSchema>
pub fn get_extension_module_schema( &self, module_name: &str, ) -> Option<ParsedModuleSchema>
Get extension module schema by module namespace.
Sourcepub fn module_exports_from_extensions(&self) -> Vec<ModuleExports>
pub fn module_exports_from_extensions(&self) -> Vec<ModuleExports>
Build VM extension modules from loaded extension module capabilities.
Sourcepub fn invoke_extension_module_nb(
&self,
module_name: &str,
function: &str,
args: &[ValueWord],
) -> Result<ValueWord>
pub fn invoke_extension_module_nb( &self, module_name: &str, function: &str, args: &[ValueWord], ) -> Result<ValueWord>
Invoke one loaded module export via module namespace.
Sourcepub fn invoke_extension_module_wire(
&self,
module_name: &str,
function: &str,
args: &[WireValue],
) -> Result<WireValue>
pub fn invoke_extension_module_wire( &self, module_name: &str, function: &str, args: &[WireValue], ) -> Result<WireValue>
Invoke one loaded module export via module namespace.
Sourcepub fn enable_progress_tracking(&mut self) -> Arc<ProgressRegistry>
pub fn enable_progress_tracking(&mut self) -> Arc<ProgressRegistry>
Enable progress tracking and return the registry for subscriptions
Call this before executing code that may report progress. The returned registry can be used to subscribe to progress events.
§Example
let registry = engine.enable_progress_tracking();
let mut receiver = registry.subscribe();
// In a separate task
while let Ok(event) = receiver.recv().await {
println!("Progress: {:?}", event);
}Sourcepub fn progress_registry(&self) -> Option<Arc<ProgressRegistry>>
pub fn progress_registry(&self) -> Option<Arc<ProgressRegistry>>
Get the current progress registry if enabled
Sourcepub fn has_pending_progress(&self) -> bool
pub fn has_pending_progress(&self) -> bool
Check if there are pending progress events
Sourcepub fn poll_progress(&self) -> Option<ProgressEvent>
pub fn poll_progress(&self) -> Option<ProgressEvent>
Poll for progress events (non-blocking)
Returns the next progress event if available, or None if queue is empty.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for ShapeEngine
impl !RefUnwindSafe for ShapeEngine
impl Send for ShapeEngine
impl Sync for ShapeEngine
impl Unpin for ShapeEngine
impl UnsafeUnpin for ShapeEngine
impl !UnwindSafe for ShapeEngine
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more