Skip to content

Instantly share code, notes, and snippets.

@coolreader18

coolreader18/embedding.rs Secret

Last active Apr 12, 2021
Embed
What would you like to do?
use rustpython_vm as vm;
use vm::pyobject::ItemProtocol;
// See: https://github.com/RustPython/RustPython/blob/d6c8247886ff504f77e8995b08d9a15c22dfa8a0/examples/mini_repl.rs
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_bytecode::CodeObject to a PyCodeRef
let code = $vm.new_code_object(code);
// run the python code in the scope to store the function
$vm.run_code_obj(code, $scope.clone())
}};
}
fn main() {
let res = execute(r#"print(sum(map(int,input().split(" "))))"#, "1 2 3 4 5");
println!("{}", res.expect("Failed executing"));
}
fn execute(code: &str, input: &str) -> Result<String, ()> {
vm::Interpreter::default().enter(|vm| {
let scope = vm.new_scope_with_builtins();
add_python_function!(
scope,
vm,
r#"
import _io, sys
def run(code, input):
stdout = _io.StringIO()
sys.stdin = _io.StringIO(input)
sys.stdout = stdout
try:
exec(code, {}, {}) # maybe you'll want to do something with the locals+globals
finally:
sys.stdout = sys.__stdout__
sys.stdin = sys.__stdin__
return stdout.getvalue()
"#
);
let run = scope.globals.get_item("run").unwrap();
let compiled_code = vm
.compile(code, vm::compile::Mode::Exec, "<embedded>".to_owned())
.map_err(|e| {
eprintln!("syntax error:\n{}", e);
()
})?;
match vm.invoke(&run, (compiled_code, input)) {
Ok(output) => {
if !vm.is_none(&output) {
match vm.to_str(&output) {
Ok(s) => Ok(s.as_ref().to_owned()),
Err(e) => Err(()), // TODO
}
} else {
Err(()) // TODO
}
}
Err(e) => {
vm::exceptions::print_exception(vm, e);
Err(()) // TODO
}
}
})
}
@jhoobergs

This comment has been minimized.

Copy link

@jhoobergs jhoobergs commented Apr 12, 2021

On line 44, I need to use globals instead of dict ?

@coolreader18

This comment has been minimized.

Copy link
Owner Author

@coolreader18 coolreader18 commented Apr 12, 2021

Oh, whoops, yes @jhoobergs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment