Engine Builder

Engine is the entry point for running Dogma scripts. Build one with Engine::builder().

use dogma_vm::{Engine, MethodSpec, NativeSpec, TypeSpec, Value};

let engine = Engine::builder()
    .with_capability_functions("dogma:core", dogma_vm::stdlib::core_natives())
    .with_capability_functions("myapp", my_app_functions())
    .with_native_type(my_type_spec())
    .with_max_operations(100_000)
    .with_async()
    .build();

Methods🔗

.with_capability_functions(name, fns)🔗

Registers a named set of functions that scripts can import.

.with_capability_functions("myapp", vec![
    NativeSpec::new("greet", 1, |args| match &args[0] {
        Value::String(name) => Ok(Value::String(format!("Hello, {name}!"))),
        _ => Err("greet: expected String".into()),
    })
    .returns("String"),
])

The name is the import path used in scripts: import { greet } from "myapp".

.with_native_type(spec)🔗

Registers a native Rust type that scripts can receive and call methods on. See Native Types.

.with_max_operations(n)🔗

Caps the number of VM operations a script may execute. Prevents infinite loops. Typical values: 100_000 for simple scripts, 1_000_000 for complex ones.

.with_max_memory(bytes)🔗

Caps the heap memory the script may allocate. Example: .with_max_memory(4 * 1024 * 1024) for 4 MB.

.with_async()🔗

Enables coroutine-based concurrency (dogma:async). Scripts must still import { await_all } from "dogma:async" to use it. Off by default.

.build()🔗

Produces the Engine. An Engine is immutable once built — create a new one to change configuration.

Running scripts🔗

use std::path::Path;

// Run a file
engine.run_file(Path::new("script.dg"))?;

// Run source string (second arg is used in error messages)
engine.run_source(r#"fn main() { println("hi") }"#, Path::new("script.dg"))?;