Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Rune can be run in a special mode called a “script” mode. This is the simplest way of using Rune.

This is intended to support what looks like inline execution of code, and is implemented to allow for evaluating expressions like value + 40.

In order to run a program in script mode Options::script has to be set, any implicit arguments passed into the script must then be specified through Prepare::with_args.

use rune::support::Result;
use rune::sync::Arc;
use rune::termcolor::{ColorChoice, StandardStream};
use rune::{Context, ContextError, Diagnostics, Hash, Module, Options, Source, Sources, Unit, Vm};

#[rune::function]
fn calculate(value: i64) -> i64 {
    value + 10
}

pub fn module() -> Result<Module, ContextError> {
    let mut module = Module::new();
    module.function_meta(calculate)?;
    Ok(module)
}

fn main() -> Result<()> {
    let context = context()?;
    let runtime = Arc::try_new(context.runtime()?)?;

    let unit = compile(&context, "calculate(value) / 2")?;
    let mut vm = Vm::new(runtime, unit);

    let output = vm.call(Hash::EMPTY, (5,))?;
    let output: i64 = rune::from_value(output)?;
    println!("{output:?}");
    assert_eq!(output, 7);
    Ok(())
}

fn context() -> Result<Arc<Context>, ContextError> {
    let m = module()?;
    let mut context = rune_modules::default_context()?;
    context.install(m)?;
    Ok(Arc::try_new(context)?)
}

fn compile(context: &Context, script: &str) -> Result<Arc<Unit>> {
    let mut sources = Sources::new();
    sources.insert(Source::memory(script)?)?;

    let mut diagnostics = Diagnostics::new();
    let mut options = Options::from_default_env()?;
    options.script(true);

    let result = rune::prepare(&mut sources)
        .with_args(["value"])?
        .with_options(&options)
        .with_context(context)
        .with_diagnostics(&mut diagnostics)
        .build();

    if !diagnostics.is_empty() {
        let mut writer = StandardStream::stderr(ColorChoice::Always);
        diagnostics.emit(&mut writer, &sources)?;
    }

    let unit = result?;
    let unit = Arc::try_new(unit)?;
    Ok(unit)
}

Behind the scenes script mode defines an unnamed function which can be addressed as Hash::EMPTY. The arguments that has to be passed into this function is defined through Prepare::with_args. These variables are not global variables. They are not addressible from other functions.