diff --git a/mers/Cargo.toml b/mers/Cargo.toml index 3c30102..f0984db 100644 --- a/mers/Cargo.toml +++ b/mers/Cargo.toml @@ -15,7 +15,7 @@ default = ["colored-output"] colored-output = ["mers_lib/ecolor-term", "mers_lib/pretty-print", "dep:colored"] [dependencies] -mers_lib = "0.9.10" +mers_lib = "0.9.12" # mers_lib = { path = "../mers_lib" } clap = { version = "4.3.19", features = ["derive"] } colored = { version = "2.1.0", optional = true } diff --git a/mers_lib/Cargo.toml b/mers_lib/Cargo.toml index ece12c9..87cd981 100755 --- a/mers_lib/Cargo.toml +++ b/mers_lib/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mers_lib" -version = "0.9.12" +version = "0.9.13" edition = "2021" license = "MIT OR Apache-2.0" description = "library to use the mers language in other projects" diff --git a/mers_lib/examples/01_user_scripts.rs b/mers_lib/examples/01_user_scripts.rs index f06de81..2f4352e 100644 --- a/mers_lib/examples/01_user_scripts.rs +++ b/mers_lib/examples/01_user_scripts.rs @@ -8,7 +8,7 @@ use mers_lib::{ }; fn main() -> Result<(), CheckError> { - let (_, func) = parse_compile_check_run( + let (_, func, info) = parse_compile_check_run( // The `[(String -> String)]` type annotation ensures that decorate.mers returns a `String -> String` function. "[(String -> String)] #include \"examples/decorate.mers\"".to_owned(), )?; @@ -23,7 +23,10 @@ fn main() -> Result<(), CheckError> { // use the function to decorate these 3 test strings for input in ["my test string", "Main Menu", "O.o"] { - let result = func.run_immut(Data::new(data::string::String(input.to_owned())))?; + let result = func.run_immut( + Data::new(data::string::String(input.to_owned())), + info.global.clone(), + )?; let result = result.get(); let result = &result .as_any() @@ -37,7 +40,9 @@ fn main() -> Result<(), CheckError> { } /// example 00 -fn parse_compile_check_run(src: String) -> Result<(Type, Data), CheckError> { +fn parse_compile_check_run( + src: String, +) -> Result<(Type, Data, mers_lib::program::run::Info), CheckError> { let mut source = Source::new_from_string(src); let srca = Arc::new(source.clone()); let parsed = parse(&mut source, &srca)?; @@ -45,5 +50,5 @@ fn parse_compile_check_run(src: String) -> Result<(Type, Data), CheckError> { let compiled = parsed.compile(&mut i1, CompInfo::default())?; let output_type = compiled.check(&mut i3, None)?; let output_value = compiled.run(&mut i2)?; - Ok((output_type, output_value)) + Ok((output_type, output_value, i2)) } diff --git a/mers_lib/src/data/function.rs b/mers_lib/src/data/function.rs index b5621f5..882ca1a 100755 --- a/mers_lib/src/data/function.rs +++ b/mers_lib/src/data/function.rs @@ -80,11 +80,25 @@ impl Function { pub fn check(&self, arg: &Type) -> Result { self.get_as_type().o(arg) } - pub fn run_mut(&mut self, arg: Data) -> Result { + pub fn run_mut( + &mut self, + arg: Data, + gi: crate::program::run::RunLocalGlobalInfo, + ) -> Result { + self.info.global = gi; + self.run_mut_with_prev_gi(arg) + } + pub fn run_mut_with_prev_gi(&mut self, arg: Data) -> Result { (self.run)(arg, &mut self.info) } - pub fn run_immut(&self, arg: Data) -> Result { - (self.run)(arg, &mut self.info.duplicate()) + pub fn run_immut( + &self, + arg: Data, + gi: crate::program::run::RunLocalGlobalInfo, + ) -> Result { + let mut i = self.info.duplicate(); + i.global = gi; + (self.run)(arg, &mut i) } pub fn get_as_type(&self) -> FunctionT { let info = self.info_check.lock().unwrap().clone(); @@ -114,13 +128,25 @@ impl MersData for Function { fn executable(&self) -> Option { Some(self.get_as_type()) } - fn execute(&self, arg: Data) -> Option> { - Some(self.run_immut(arg)) + fn execute( + &self, + arg: Data, + gi: &crate::program::run::RunLocalGlobalInfo, + ) -> Option> { + Some(self.run_immut(arg, gi.clone())) } - fn iterable(&self) -> Option>>> { + fn iterable( + &self, + gi: &crate::program::run::RunLocalGlobalInfo, + ) -> Option>>> { let mut s = Clone::clone(self); + let mut gi = Some(gi.clone()); Some(Box::new(std::iter::from_fn(move || { - match s.run_mut(Data::empty_tuple()) { + match if let Some(gi) = gi.take() { + s.run_mut(Data::empty_tuple(), gi) + } else { + s.run_mut_with_prev_gi(Data::empty_tuple()) + } { Err(e) => Some(Err(e)), Ok(v) => { if let Some(v) = v.one_tuple_content() { diff --git a/mers_lib/src/data/mod.rs b/mers_lib/src/data/mod.rs index 7757e40..9420e32 100755 --- a/mers_lib/src/data/mod.rs +++ b/mers_lib/src/data/mod.rs @@ -30,16 +30,28 @@ pub trait MersData: Any + Debug + Send + Sync { None } #[allow(unused_variables)] - fn execute(&self, arg: Data) -> Option> { + fn execute( + &self, + arg: Data, + gi: &crate::program::run::RunLocalGlobalInfo, + ) -> Option> { None } - fn iterable(&self) -> Option>>> { + #[allow(unused_variables)] + fn iterable( + &self, + gi: &crate::program::run::RunLocalGlobalInfo, + ) -> Option>>> { None } /// By default, uses `iterable` to get an iterator and `nth` to retrieve the nth element. /// Should have a custom implementation for better performance on most types - fn get(&self, i: usize) -> Option> { - self.iterable()?.nth(i) + fn get( + &self, + i: usize, + gi: &crate::program::run::RunLocalGlobalInfo, + ) -> Option> { + self.iterable(gi)?.nth(i) } /// If self and other are different types (`other.as_any().downcast_ref::().is_none()`), /// this *must* return false. diff --git a/mers_lib/src/data/reference.rs b/mers_lib/src/data/reference.rs index 6d554b8..d56553a 100755 --- a/mers_lib/src/data/reference.rs +++ b/mers_lib/src/data/reference.rs @@ -27,7 +27,11 @@ impl MersData for Reference { None } } - fn execute(&self, arg: Data) -> Option> { + fn execute( + &self, + arg: Data, + gi: &crate::program::run::RunLocalGlobalInfo, + ) -> Option> { let mut inner = self.0.write().unwrap(); let mut inner = inner.get_mut(); if let Some(func) = inner @@ -35,13 +39,17 @@ impl MersData for Reference { .mut_any() .downcast_mut::() { - Some(func.run_mut(arg)) + Some(func.run_mut(arg, gi.clone())) } else { None } } - fn iterable(&self) -> Option>>> { + fn iterable( + &self, + gi: &crate::program::run::RunLocalGlobalInfo, + ) -> Option>>> { let inner = Arc::clone(&self.0); + let gi = gi.clone(); Some(Box::new(std::iter::from_fn(move || { match inner .write() @@ -50,7 +58,7 @@ impl MersData for Reference { .mut_any() .downcast_mut::() .unwrap() - .run_mut(Data::empty_tuple()) + .run_mut(Data::empty_tuple(), gi.clone()) { Err(e) => Some(Err(e)), Ok(v) => { diff --git a/mers_lib/src/data/tuple.rs b/mers_lib/src/data/tuple.rs index 348dd9b..cf70749 100755 --- a/mers_lib/src/data/tuple.rs +++ b/mers_lib/src/data/tuple.rs @@ -35,7 +35,10 @@ impl MersData for Tuple { false } } - fn iterable(&self) -> Option>>> { + fn iterable( + &self, + _gi: &crate::program::run::RunLocalGlobalInfo, + ) -> Option>>> { Some(Box::new(self.0.clone().into_iter().map(Ok))) } fn clone(&self) -> Box { diff --git a/mers_lib/src/program/configs/with_base.rs b/mers_lib/src/program/configs/with_base.rs index 8573f22..29b13e4 100755 --- a/mers_lib/src/program/configs/with_base.rs +++ b/mers_lib/src/program/configs/with_base.rs @@ -63,14 +63,14 @@ impl Config { } Ok(Type::empty_tuple()) })), - run: Arc::new(|a, _i| { + run: Arc::new(|a, i| { let a = a.get(); let a = a.as_any().downcast_ref::().unwrap(); let arg_ref = a.0[0].get(); let arg_ref = arg_ref.as_any().downcast_ref::().unwrap(); let mut arg = arg_ref.0.write().unwrap(); let func = a.0[1].get(); - *arg = func.execute(arg.clone()).unwrap()?; + *arg = func.execute(arg.clone(), &i.global).unwrap()?; Ok(Data::empty_tuple()) }), inner_statements: None, @@ -103,12 +103,12 @@ impl Config { } Ok(Type::new(data::int::IntT(0, INT_MAX))) })), - run: Arc::new(|a, _i| { + run: Arc::new(|a, i| { Ok(Data::new(data::int::Int(if let Some(t) = a.get().as_any().downcast_ref::() { t.0.len().try_into().unwrap_or(INT_MAX) } else if let Some(s) = a.get().as_any().downcast_ref::() { s.0.len().try_into().unwrap_or(INT_MAX) - } else if let Some(i) = a.get().iterable() { + } else if let Some(i) = a.get().iterable(&i.global) { i.count().try_into().unwrap_or(INT_MAX) } else { return Err("called len on {a:?}, which isn't a tuple, a string, or something iterable.".into()); @@ -130,8 +130,8 @@ impl Config { } Ok(bool_type()) })), - run: Arc::new(|a, _i| { - Ok(Data::new(data::bool::Bool(if let Some(mut i) = a.get().iterable() { + run: Arc::new(|a, i| { + Ok(Data::new(data::bool::Bool(if let Some(mut i) = a.get().iterable(&i.global) { if let Some(f) = i.next() { let f = f?; let mut o = true; diff --git a/mers_lib/src/program/configs/with_command_running.rs b/mers_lib/src/program/configs/with_command_running.rs index f779582..b6ffae4 100755 --- a/mers_lib/src/program/configs/with_command_running.rs +++ b/mers_lib/src/program/configs/with_command_running.rs @@ -12,7 +12,6 @@ use crate::{ object::ObjectFieldsMap, Data, MersData, MersDataWInfo, MersType, Type, }, - errors::CheckError, info::DisplayInfo, program::{self, run::CheckInfo}, }; @@ -56,7 +55,7 @@ impl Config { let cmd = cmd.get(); let (cmd, args) = ( cmd.as_any().downcast_ref::().unwrap(), - args.get().iterable().unwrap(), + args.get().iterable(&i.global).unwrap(), ); let args = args.map(|v| v.map(|v| v.get().with_info(i).to_string())).collect::, _>>()?; match Command::new(&cmd.0) @@ -107,7 +106,7 @@ impl Config { let cmd = cmd.get(); let (cmd, args) = ( cmd.as_any().downcast_ref::().unwrap(), - args.get().iterable().unwrap(), + args.get().iterable(&i.global).unwrap(), ); let args = args.map(|v| v.map(|v| v.get().with_info(i).to_string())).collect::, _>>()?; match Command::new(&cmd.0) @@ -203,14 +202,14 @@ impl Config { return Err(format!("childproc_write_bytes called on non-`(ChildProcess, Iter)` type {}", a.with_info(i)).into()); } })), - run: Arc::new(|a, _i| { + run: Arc::new(|a, i| { let a = a.get(); let tuple = a.as_any().downcast_ref::().unwrap(); let child = tuple.0[0].get(); let bytes = tuple.0[1].get(); let child = child.as_any().downcast_ref::().unwrap(); let mut child = child.0.lock().unwrap(); - let buf = bytes.iterable().unwrap().map(|v| v.map(|v| v.get().as_any().downcast_ref::().unwrap().0)).collect::, _>>()?; + let buf = bytes.iterable(&i.global).unwrap().map(|v| v.map(|v| v.get().as_any().downcast_ref::().unwrap().0)).collect::, _>>()?; Ok(if child.1.as_mut().is_some_and(|v| v.write_all(&buf).is_ok() && v.flush().is_ok()) { Data::new(data::bool::Bool(true)) } else { @@ -385,12 +384,6 @@ impl MersData for ChildProcess { fn display(&self, _info: &DisplayInfo<'_>, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{self}") } - fn iterable(&self) -> Option>>> { - None - } - fn get(&self, _i: usize) -> Option> { - None - } fn is_eq(&self, other: &dyn MersData) -> bool { other .as_any() diff --git a/mers_lib/src/program/configs/with_get.rs b/mers_lib/src/program/configs/with_get.rs index d091ce3..50624c0 100755 --- a/mers_lib/src/program/configs/with_get.rs +++ b/mers_lib/src/program/configs/with_get.rs @@ -50,14 +50,14 @@ impl Config { Arc::new(data::tuple::TupleT(vec![])), ])) })), - run: Arc::new(|a, _i| { + run: Arc::new(|a, i| { let a = a.get(); - if let (Some(v), Some(i)) = (a.get(0), a.get(1)) { - let (v, i2) = (v?, i?); - let o = if let Some(i3) = i2.get().as_any().downcast_ref::() + if let (Some(v), Some(x)) = (a.get(0, &i.global), a.get(1, &i.global)) { + let (v, x2) = (v?, x?); + let o = if let Some(x3) = x2.get().as_any().downcast_ref::() { - if let Ok(i) = i3.0.try_into() { - if let Some(v) = v.get().get(i) { + if let Ok(x) = x3.0.try_into() { + if let Some(v) = v.get().get(x, &i.global) { Ok(Data::one_tuple(v?)) } else { Ok(Data::empty_tuple()) diff --git a/mers_lib/src/program/configs/with_iters.rs b/mers_lib/src/program/configs/with_iters.rs index 895ecdf..565c7b2 100755 --- a/mers_lib/src/program/configs/with_iters.rs +++ b/mers_lib/src/program/configs/with_iters.rs @@ -30,16 +30,16 @@ impl Config { /// `all: fn` returns true if all elements of the iterator are true pub fn with_iters(self) -> Self { self - .add_var("any", genfunc_iter_in_val_out("all".to_string(), data::bool::bool_type(), data::bool::bool_type(), |a, _i| { - for v in a.get().iterable().unwrap().map(|v| v.map(|v| v.get().as_any().downcast_ref::().is_some_and(|v| v.0))) { + .add_var("any", genfunc_iter_in_val_out("all".to_string(), data::bool::bool_type(), data::bool::bool_type(), |a, i| { + for v in a.get().iterable(&i.global).unwrap().map(|v| v.map(|v| v.get().as_any().downcast_ref::().is_some_and(|v| v.0))) { if v? { return Ok(Data::new(data::bool::Bool(true))); } } Ok(Data::new(data::bool::Bool(false))) })) - .add_var("all", genfunc_iter_in_val_out("all".to_string(), data::bool::bool_type(), data::bool::bool_type(), |a, _i| { - for v in a.get().iterable().unwrap().map(|v| v.map(|v| v.get().as_any().downcast_ref::().is_some_and(|v| v.0))) { + .add_var("all", genfunc_iter_in_val_out("all".to_string(), data::bool::bool_type(), data::bool::bool_type(), |a, i| { + for v in a.get().iterable(&i.global).unwrap().map(|v| v.map(|v| v.get().as_any().downcast_ref::().is_some_and(|v| v.0))) { if !v? { return Ok(Data::new(data::bool::Bool(false))); } @@ -88,13 +88,13 @@ impl Config { } Ok(Type::empty_tuple()) })), - run: Arc::new(|a, _i| { + run: Arc::new(|a, i| { if let Some(tuple) = a.get().as_any().downcast_ref::() { if let (Some(v), Some(f)) = (tuple.get(0), tuple.get(1)) { - if let Some(iter) = v.get().iterable() { + if let Some(iter) = v.get().iterable(&i.global) { let f = f.get(); for v in iter { - f.execute(v?).unwrap()?; + f.execute(v?, &i.global).unwrap()?; } Ok(Data::empty_tuple()) } else { @@ -319,21 +319,25 @@ impl MersData for Iter { fn is_eq(&self, _other: &dyn MersData) -> bool { false } - fn iterable(&self) -> Option>>> { + fn iterable( + &self, + gi: &crate::program::run::RunLocalGlobalInfo, + ) -> Option>>> { + let gi = gi.clone(); Some(match &self.0 { Iters::Map(f) => { let f = Clone::clone(f); - Box::new(self.1.get().iterable()?.map(move |v| { + Box::new(self.1.get().iterable(&gi)?.map(move |v| { f.get() - .execute(v?) + .execute(v?, &gi) .ok_or_else(|| CheckError::from("called map with non-function argument"))? })) } Iters::Filter(f) => { let f = Clone::clone(f); - Box::new(self.1.get().iterable()?.filter_map(move |v| { + Box::new(self.1.get().iterable(&gi)?.filter_map(move |v| { match v { - Ok(v) => match f.get().execute(v.clone()) { + Ok(v) => match f.get().execute(v.clone(), &gi) { Some(Ok(f)) => { if f.get() .as_any() @@ -356,8 +360,8 @@ impl MersData for Iter { } Iters::FilterMap(f) => { let f = Clone::clone(f); - Box::new(self.1.get().iterable()?.filter_map(move |v| match v { - Ok(v) => match f.get().execute(v) { + Box::new(self.1.get().iterable(&gi)?.filter_map(move |v| match v { + Ok(v) => match f.get().execute(v, &gi) { Some(Ok(r)) => Some(Ok(r.one_tuple_content()?)), Some(Err(e)) => Some(Err(e)), None => Some(Err(CheckError::from( @@ -369,8 +373,8 @@ impl MersData for Iter { } Iters::MapWhile(f) => { let f = Clone::clone(f); - Box::new(self.1.get().iterable()?.map_while(move |v| match v { - Ok(v) => match f.get().execute(v) { + Box::new(self.1.get().iterable(&gi)?.map_while(move |v| match v { + Ok(v) => match f.get().execute(v, &gi) { Some(Ok(r)) => Some(Ok(r.one_tuple_content()?)), Some(Err(e)) => Some(Err(e)), None => Some(Err(CheckError::from( @@ -380,22 +384,28 @@ impl MersData for Iter { Err(e) => Some(Err(e)), })) } - Iters::Take(limit) => Box::new(self.1.get().iterable()?.take(*limit)), + Iters::Take(limit) => Box::new(self.1.get().iterable(&gi)?.take(*limit)), Iters::Enumerate => { - Box::new(self.1.get().iterable()?.enumerate().map(|(i, v)| match v { - Ok(v) => Ok(Data::new(data::tuple::Tuple(vec![ - Data::new(data::int::Int(i as _)), - v, - ]))), - Err(e) => Err(e), - })) + Box::new( + self.1 + .get() + .iterable(&gi)? + .enumerate() + .map(|(i, v)| match v { + Ok(v) => Ok(Data::new(data::tuple::Tuple(vec![ + Data::new(data::int::Int(i as _)), + v, + ]))), + Err(e) => Err(e), + }), + ) } Iters::Chained => { match self .1 .get() - .iterable()? - .map(|v| Ok(v?.get().iterable())) + .iterable(&gi)? + .map(move |v| Ok(v?.get().iterable(&gi))) .collect::>, CheckError>>() { Ok(Some(iters)) => Box::new(iters.into_iter().flatten()), diff --git a/mers_lib/src/program/configs/with_list.rs b/mers_lib/src/program/configs/with_list.rs index 57819a8..3bae9d8 100755 --- a/mers_lib/src/program/configs/with_list.rs +++ b/mers_lib/src/program/configs/with_list.rs @@ -221,9 +221,9 @@ impl Config { ).into()) } })), - run: Arc::new(|a, _i| { - if let Some(i) = a.get().iterable() { - Ok(Data::new(List(i.map(|v| Ok::<_, CheckError>(Arc::new(RwLock::new(v?)))).collect::>()?))) + run: Arc::new(|a, i| { + if let Some(iter) = a.get().iterable(&i.global) { + Ok(Data::new(List(iter.map(|v| Ok::<_, CheckError>(Arc::new(RwLock::new(v?)))).collect::>()?))) } else { Err("as_list called on non-iterable".into()) } @@ -272,7 +272,10 @@ impl MersData for List { false } } - fn iterable(&self) -> Option>>> { + fn iterable( + &self, + _gi: &crate::program::run::RunLocalGlobalInfo, + ) -> Option>>> { Some(Box::new( self.0 .clone() diff --git a/mers_lib/src/program/configs/with_math.rs b/mers_lib/src/program/configs/with_math.rs index 700d7f6..7ec8fae 100755 --- a/mers_lib/src/program/configs/with_math.rs +++ b/mers_lib/src/program/configs/with_math.rs @@ -501,10 +501,10 @@ impl Config { } Ok(o) }, - |a, _| { + |a, i| { let mut min_int = None; let mut min_float = None; - for a in a.get().iterable().expect("called `min` on non-itereable") { + for a in a.get().iterable(&i.global).expect("called `min` on non-itereable") { let a = a?; let a = a.get(); let a = a.as_any().downcast_ref::().map(|v| Ok(v.0)).or_else(|| a.as_any().downcast_ref::().map(|v| Err(v.0))).expect("found non-Int/Float element in argument to `min`"); @@ -581,10 +581,10 @@ impl Config { } Ok(o) }, - |a, _| { + |a, i| { let mut min_int = None; let mut min_float = None; - for a in a.get().iterable().expect("called `min` on non-itereable") { + for a in a.get().iterable(&i.global).expect("called `min` on non-itereable") { let a = a?; let a = a.get(); let a = a.as_any().downcast_ref::().map(|v| Ok(v.0)).or_else(|| a.as_any().downcast_ref::().map(|v| Err(v.0))).expect("found non-Int/Float element in argument to `min`"); @@ -796,7 +796,7 @@ fn func_math_op( } Ok(o) }, - move |a, _| { + move |a, i| { let a = a.get(); Ok( if let Some(a) = &a @@ -839,7 +839,7 @@ fn func_math_op( let (mut acc, _) = iter_version .expect("no iter version for this math op, but argument not a 2-tuple..."); for a in a - .iterable() + .iterable(&i.global) .expect("math op with iter version called on non-iterable") { let a = a?; diff --git a/mers_lib/src/program/configs/with_multithreading.rs b/mers_lib/src/program/configs/with_multithreading.rs index ef45270..6c13a51 100755 --- a/mers_lib/src/program/configs/with_multithreading.rs +++ b/mers_lib/src/program/configs/with_multithreading.rs @@ -47,9 +47,10 @@ impl Config { } Ok(Type::new(ThreadT(out))) })), - run: Arc::new(|a, _i| { + run: Arc::new(|a, i| { + let gi = i.global.clone(); Ok(Data::new(Thread(Arc::new(Mutex::new(Ok(std::thread::spawn( - move || a.get().execute(Data::empty_tuple()).unwrap(), + move || a.get().execute(Data::empty_tuple(), &gi).unwrap(), ))))))) }), inner_statements: None, diff --git a/mers_lib/src/program/configs/with_string.rs b/mers_lib/src/program/configs/with_string.rs index b236df9..cf41878 100755 --- a/mers_lib/src/program/configs/with_string.rs +++ b/mers_lib/src/program/configs/with_string.rs @@ -81,7 +81,7 @@ impl Config { |a, i| { Ok(Data::new(data::string::String( a.get() - .iterable() + .iterable(&i.global) .unwrap() .map(|v| v.map(|v| v.get().with_info(i).to_string())) .collect::>()?, diff --git a/mers_lib/src/program/run/chain.rs b/mers_lib/src/program/run/chain.rs index fbd18b6..7ebf745 100755 --- a/mers_lib/src/program/run/chain.rs +++ b/mers_lib/src/program/run/chain.rs @@ -92,7 +92,7 @@ impl MersStatement for Chain { let f = self.first.run(info)?; let c = self.chained.run(info)?; let c = c.get(); - match c.execute(f) { + match c.execute(f, &info.global) { Some(Ok(v)) => Ok(v), Some(Err(e)) => Err(if let Some(_) = &self.as_part_of_include { CheckError::new().err_with_diff_src(e).src(vec![( diff --git a/mers_lib/src/program/run/try.rs b/mers_lib/src/program/run/try.rs index 26a932a..8cc8202 100644 --- a/mers_lib/src/program/run/try.rs +++ b/mers_lib/src/program/run/try.rs @@ -116,7 +116,7 @@ impl MersStatement for Try { match func.executable().map(|func| func.o(&arg_type)) { Some(Ok(_)) => { drop(ar); - return func.execute(arg).unwrap(); + return func.execute(arg, &info.global).unwrap(); } None | Some(Err(_)) => (), }