GitHub Viewer
//! This example show cases a very simple REPL.
//! While a much better REPL can be found in ../src/shell,
//! This much smaller REPL is still a useful example because it showcases inserting
//! values and functions into the Python runtime's scope, and showcases use
//! of the compilation mode "Single".
use rustpython_vm as vm;
// these are needed for special memory shenanigans to let us share a variable with Python and Rust
use core::sync::atomic::{AtomicBool, Ordering};
// This has to be a macro because it uses the py_compile macro,
// which compiles python source to optimized bytecode at compile time, so that
// the program you're embedding this into doesn't take longer to start up.
macro_rules! add_python_function {
( $scope:ident, $vm:ident, $src:literal $(,)? ) => {{
// compile the code to bytecode
let code = vm::py_compile!(source = $src);
// convert the rustpython_compiler_core::CodeObject to a PyRef
let code = $vm.new_code(code);
// run the python code in the scope to store the function
$vm.run_code_obj(code, $scope.clone())
}};
}
static ON: AtomicBool = AtomicBool::new(true);
fn on(b: bool) {
ON.store(b, Ordering::Relaxed);
}
fn main() -> vm::PyResult {
vm::Interpreter::without_stdlib(Default::default()).enter(run)
}
fn run(vm: &vm::VirtualMachine) -> vm::PyResult {
let mut input = String::with_capacity(50);
let stdin = std::io::stdin();
let scope: vm::scope::Scope = vm.new_scope_with_builtins();
// typing `quit()` is too long, let's make `on(False)` work instead.
scope
.globals
.set_item("on", vm.new_function("on", on).into(), vm)?;
// let's include a fibonacci function, but let's be lazy and write it in Python
add_python_function!(
scope,
vm,
// a fun line to test this with is
// ''.join( l * fib(i) for i, l in enumerate('supercalifragilistic') )
r#"\
def fib(n):
return n if n