rush_interpreter_vm/
lib.rs

1#![warn(rust_2018_idioms)]
2
3mod compiler;
4mod instruction;
5mod value;
6mod vm;
7
8pub use compiler::Compiler;
9pub use instruction::Instruction;
10use instruction::Program;
11use rush_analyzer::ast::AnalyzedProgram;
12pub use rush_analyzer::Diagnostic;
13pub use value::Value;
14pub use vm::{RuntimeError, RuntimeErrorKind, Vm};
15
16/// Compiles rush source code to VM instructions.
17/// The `Ok(_)` variant is a [`CompilationResult`] which also includes any non-error diagnostics.
18/// The `Err(_)` variant returns a `Vec<Diagnostic>` which contains at least one error.
19pub fn compile(ast: AnalyzedProgram<'_>) -> Program {
20    Compiler::new().compile(ast)
21}
22
23/// Executes the given program using the VM.
24/// The `Ok(_)` variant also returns non-error diagnostics.
25/// The `Err(_)` variant returns a `Vec<Diagnostic>` which contains at least one error.
26pub fn run(ast: AnalyzedProgram<'_>) -> Result<i64, RuntimeError> {
27    let program = Compiler::new().compile(ast);
28    let mut vm = Vm::new();
29    let exit_code = vm.run(program)?;
30    Ok(exit_code)
31}
32
33/// Executes the given program using the VM on debug mode.
34/// The `Ok(_)` variant also returns non-error diagnostics.
35/// The `Err(_)` variant returns a `Vec<Diagnostic>` which contains at least one error.
36pub fn debug_run(ast: AnalyzedProgram<'_>, clock_hz: u64) -> Result<i64, RuntimeError> {
37    let program = Compiler::new().compile(ast);
38    let mut vm = Vm::new();
39    let exit_code = vm.debug_run(program, clock_hz)?;
40    Ok(exit_code)
41}