/embedding.rs Secret
Last active
April 12, 2021 16:01
Star
You must be signed in to star a gist
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} | |
} | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
On line 44, I need to use
globals
instead ofdict
?