@@ -8,11 +8,13 @@ extern crate futures;
88extern crate js_sys;
99#[ macro_use]
1010extern crate rustpython_vm;
11+ extern crate rustpython_compiler;
1112extern crate wasm_bindgen;
1213extern crate wasm_bindgen_futures;
1314extern crate web_sys;
1415
1516use js_sys:: { Object , Reflect , TypeError } ;
17+ use rustpython_compiler:: compile:: Mode ;
1618use std:: panic;
1719use wasm_bindgen:: prelude:: * ;
1820
@@ -47,14 +49,39 @@ pub fn setup_console_error() {
4749#[ wasm_bindgen( typescript_custom_section) ]
4850const TS_CMT_START : & ' static str = "/*" ;
4951
52+ fn run_py ( source : & str , options : Option < Object > , mode : Mode ) -> Result < JsValue , JsValue > {
53+ let vm = VMStore :: init ( PY_EVAL_VM_ID . into ( ) , Some ( true ) ) ;
54+ let options = options. unwrap_or_else ( Object :: new) ;
55+ let js_vars = {
56+ let prop = Reflect :: get ( & options, & "vars" . into ( ) ) ?;
57+ if prop. is_undefined ( ) {
58+ None
59+ } else if prop. is_object ( ) {
60+ Some ( Object :: from ( prop) )
61+ } else {
62+ return Err ( TypeError :: new ( "vars must be an object" ) . into ( ) ) ;
63+ }
64+ } ;
65+
66+ vm. set_stdout ( Reflect :: get ( & options, & "stdout" . into ( ) ) ?) ?;
67+
68+ if let Some ( js_vars) = js_vars {
69+ vm. add_to_scope ( "js_vars" . into ( ) , js_vars. into ( ) ) ?;
70+ }
71+ match mode {
72+ Mode :: Eval => vm. eval ( source) ,
73+ Mode :: Exec => vm. exec ( source) ,
74+ Mode :: Single => vm. exec_single ( source) ,
75+ }
76+ }
5077#[ wasm_bindgen( js_name = pyEval) ]
5178/// Evaluate Python code
5279///
5380/// ```js
54- /// pyEval(code, options?);
81+ /// var result = pyEval(code, options?);
5582/// ```
5683///
57- /// `code`: `string`: The Python code to run
84+ /// `code`: `string`: The Python code to run in eval mode
5885///
5986/// `options`:
6087///
@@ -66,26 +93,35 @@ const TS_CMT_START: &'static str = "/*";
6693/// `undefined` or "console", and it will be a dumb function when giving null.
6794
6895pub fn eval_py ( source : & str , options : Option < Object > ) -> Result < JsValue , JsValue > {
69- let options = options. unwrap_or_else ( Object :: new) ;
70- let js_vars = {
71- let prop = Reflect :: get ( & options, & "vars" . into ( ) ) ?;
72- if prop. is_undefined ( ) {
73- None
74- } else if prop. is_object ( ) {
75- Some ( Object :: from ( prop) )
76- } else {
77- return Err ( TypeError :: new ( "vars must be an object" ) . into ( ) ) ;
78- }
79- } ;
80- let vm = VMStore :: init ( PY_EVAL_VM_ID . into ( ) , Some ( true ) ) ;
81-
82- vm. set_stdout ( Reflect :: get ( & options, & "stdout" . into ( ) ) ?) ?;
96+ run_py ( source, options, Mode :: Eval )
97+ }
8398
84- if let Some ( js_vars) = js_vars {
85- vm. add_to_scope ( "js_vars" . into ( ) , js_vars. into ( ) ) ?;
86- }
99+ #[ wasm_bindgen( js_name = pyExec) ]
100+ /// Evaluate Python code
101+ ///
102+ /// ```js
103+ /// pyExec(code, options?);
104+ /// ```
105+ ///
106+ /// `code`: `string`: The Python code to run in exec mode
107+ ///
108+ /// `options`: The options are the same as eval mode
109+ pub fn exec_py ( source : & str , options : Option < Object > ) {
110+ let _ = run_py ( source, options, Mode :: Exec ) ;
111+ }
87112
88- vm. exec ( source)
113+ #[ wasm_bindgen( js_name = pyExecSingle) ]
114+ /// Evaluate Python code
115+ ///
116+ /// ```js
117+ /// var result = pyExecSingle(code, options?);
118+ /// ```
119+ ///
120+ /// `code`: `string`: The Python code to run in exec single mode
121+ ///
122+ /// `options`: The options are the same as eval mode
123+ pub fn exec_single_py ( source : & str , options : Option < Object > ) -> Result < JsValue , JsValue > {
124+ run_py ( source, options, Mode :: Single )
89125}
90126
91127#[ wasm_bindgen( typescript_custom_section) ]
0 commit comments