Skip to main content

josie_core/
engine.rs

1use crate::program::{
2    CompiledProgram, ExecutionOutput, Program, RuntimeError, ValidationError, compile_program,
3    execute_compiled_program, execute_program, parse_program,
4};
5use crate::{Operator, Operators, State};
6use serde_json::Value;
7
8/// Engine-scoped execution surface for JOSIE programs.
9///
10/// This keeps operator registration instance-local (no global singleton),
11/// so different runtimes/projects can have different `x.*` extensions safely.
12#[derive(Default)]
13pub struct Engine {
14    operators: Operators,
15}
16
17impl Engine {
18    /// Create a new engine with core + stdlib operators preloaded.
19    pub fn new() -> Self {
20        Self {
21            operators: Operators::new(),
22        }
23    }
24
25    /// Register or replace an operator, typically in `x.*`.
26    pub fn register(&mut self, name: impl Into<String>, operator: Operator) -> Option<Operator> {
27        self.operators.register(name, operator)
28    }
29
30    /// Validate and parse program document.
31    pub fn check(&self, input: &Value) -> Result<Program, ValidationError> {
32        parse_program(input)
33    }
34
35    /// Compile once.
36    pub fn compile(&self, program: &Program) -> Result<CompiledProgram, ValidationError> {
37        compile_program(program)
38    }
39
40    /// Run one-shot.
41    pub fn run(&self, program: &Program) -> Result<ExecutionOutput, RuntimeError> {
42        execute_program(program, &self.operators)
43    }
44
45    /// Run compiled program with caller-managed state.
46    pub fn run_compiled(
47        &self,
48        compiled: &CompiledProgram,
49        state: &mut State,
50    ) -> Result<Value, RuntimeError> {
51        execute_compiled_program(compiled, state, &self.operators)
52    }
53
54    /// Access the operator registry (read-only).
55    pub fn operators(&self) -> &Operators {
56        &self.operators
57    }
58}
59