fix "weird" behavior with globalinfo not updating

This commit is contained in:
Mark 2024-10-14 01:52:19 +02:00
parent 8868746e17
commit f979100bfb
17 changed files with 147 additions and 86 deletions

View File

@ -15,7 +15,7 @@ default = ["colored-output"]
colored-output = ["mers_lib/ecolor-term", "mers_lib/pretty-print", "dep:colored"] colored-output = ["mers_lib/ecolor-term", "mers_lib/pretty-print", "dep:colored"]
[dependencies] [dependencies]
mers_lib = "0.9.10" mers_lib = "0.9.12"
# mers_lib = { path = "../mers_lib" } # mers_lib = { path = "../mers_lib" }
clap = { version = "4.3.19", features = ["derive"] } clap = { version = "4.3.19", features = ["derive"] }
colored = { version = "2.1.0", optional = true } colored = { version = "2.1.0", optional = true }

View File

@ -1,6 +1,6 @@
[package] [package]
name = "mers_lib" name = "mers_lib"
version = "0.9.12" version = "0.9.13"
edition = "2021" edition = "2021"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
description = "library to use the mers language in other projects" description = "library to use the mers language in other projects"

View File

@ -8,7 +8,7 @@ use mers_lib::{
}; };
fn main() -> Result<(), CheckError> { 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. // The `[(String -> String)]` type annotation ensures that decorate.mers returns a `String -> String` function.
"[(String -> String)] #include \"examples/decorate.mers\"".to_owned(), "[(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 // use the function to decorate these 3 test strings
for input in ["my test string", "Main Menu", "O.o"] { 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.get();
let result = &result let result = &result
.as_any() .as_any()
@ -37,7 +40,9 @@ fn main() -> Result<(), CheckError> {
} }
/// example 00 /// 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 mut source = Source::new_from_string(src);
let srca = Arc::new(source.clone()); let srca = Arc::new(source.clone());
let parsed = parse(&mut source, &srca)?; 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 compiled = parsed.compile(&mut i1, CompInfo::default())?;
let output_type = compiled.check(&mut i3, None)?; let output_type = compiled.check(&mut i3, None)?;
let output_value = compiled.run(&mut i2)?; let output_value = compiled.run(&mut i2)?;
Ok((output_type, output_value)) Ok((output_type, output_value, i2))
} }

View File

@ -80,11 +80,25 @@ impl Function {
pub fn check(&self, arg: &Type) -> Result<Type, CheckError> { pub fn check(&self, arg: &Type) -> Result<Type, CheckError> {
self.get_as_type().o(arg) self.get_as_type().o(arg)
} }
pub fn run_mut(&mut self, arg: Data) -> Result<Data, CheckError> { pub fn run_mut(
&mut self,
arg: Data,
gi: crate::program::run::RunLocalGlobalInfo,
) -> Result<Data, CheckError> {
self.info.global = gi;
self.run_mut_with_prev_gi(arg)
}
pub fn run_mut_with_prev_gi(&mut self, arg: Data) -> Result<Data, CheckError> {
(self.run)(arg, &mut self.info) (self.run)(arg, &mut self.info)
} }
pub fn run_immut(&self, arg: Data) -> Result<Data, CheckError> { pub fn run_immut(
(self.run)(arg, &mut self.info.duplicate()) &self,
arg: Data,
gi: crate::program::run::RunLocalGlobalInfo,
) -> Result<Data, CheckError> {
let mut i = self.info.duplicate();
i.global = gi;
(self.run)(arg, &mut i)
} }
pub fn get_as_type(&self) -> FunctionT { pub fn get_as_type(&self) -> FunctionT {
let info = self.info_check.lock().unwrap().clone(); let info = self.info_check.lock().unwrap().clone();
@ -114,13 +128,25 @@ impl MersData for Function {
fn executable(&self) -> Option<crate::data::function::FunctionT> { fn executable(&self) -> Option<crate::data::function::FunctionT> {
Some(self.get_as_type()) Some(self.get_as_type())
} }
fn execute(&self, arg: Data) -> Option<Result<Data, CheckError>> { fn execute(
Some(self.run_immut(arg)) &self,
arg: Data,
gi: &crate::program::run::RunLocalGlobalInfo,
) -> Option<Result<Data, CheckError>> {
Some(self.run_immut(arg, gi.clone()))
} }
fn iterable(&self) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> { fn iterable(
&self,
gi: &crate::program::run::RunLocalGlobalInfo,
) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
let mut s = Clone::clone(self); let mut s = Clone::clone(self);
let mut gi = Some(gi.clone());
Some(Box::new(std::iter::from_fn(move || { 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)), Err(e) => Some(Err(e)),
Ok(v) => { Ok(v) => {
if let Some(v) = v.one_tuple_content() { if let Some(v) = v.one_tuple_content() {

View File

@ -30,16 +30,28 @@ pub trait MersData: Any + Debug + Send + Sync {
None None
} }
#[allow(unused_variables)] #[allow(unused_variables)]
fn execute(&self, arg: Data) -> Option<Result<Data, CheckError>> { fn execute(
&self,
arg: Data,
gi: &crate::program::run::RunLocalGlobalInfo,
) -> Option<Result<Data, CheckError>> {
None None
} }
fn iterable(&self) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> { #[allow(unused_variables)]
fn iterable(
&self,
gi: &crate::program::run::RunLocalGlobalInfo,
) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
None None
} }
/// By default, uses `iterable` to get an iterator and `nth` to retrieve the nth element. /// 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 /// Should have a custom implementation for better performance on most types
fn get(&self, i: usize) -> Option<Result<Data, CheckError>> { fn get(
self.iterable()?.nth(i) &self,
i: usize,
gi: &crate::program::run::RunLocalGlobalInfo,
) -> Option<Result<Data, CheckError>> {
self.iterable(gi)?.nth(i)
} }
/// If self and other are different types (`other.as_any().downcast_ref::<Self>().is_none()`), /// If self and other are different types (`other.as_any().downcast_ref::<Self>().is_none()`),
/// this *must* return false. /// this *must* return false.

View File

@ -27,7 +27,11 @@ impl MersData for Reference {
None None
} }
} }
fn execute(&self, arg: Data) -> Option<Result<Data, CheckError>> { fn execute(
&self,
arg: Data,
gi: &crate::program::run::RunLocalGlobalInfo,
) -> Option<Result<Data, CheckError>> {
let mut inner = self.0.write().unwrap(); let mut inner = self.0.write().unwrap();
let mut inner = inner.get_mut(); let mut inner = inner.get_mut();
if let Some(func) = inner if let Some(func) = inner
@ -35,13 +39,17 @@ impl MersData for Reference {
.mut_any() .mut_any()
.downcast_mut::<crate::data::function::Function>() .downcast_mut::<crate::data::function::Function>()
{ {
Some(func.run_mut(arg)) Some(func.run_mut(arg, gi.clone()))
} else { } else {
None None
} }
} }
fn iterable(&self) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> { fn iterable(
&self,
gi: &crate::program::run::RunLocalGlobalInfo,
) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
let inner = Arc::clone(&self.0); let inner = Arc::clone(&self.0);
let gi = gi.clone();
Some(Box::new(std::iter::from_fn(move || { Some(Box::new(std::iter::from_fn(move || {
match inner match inner
.write() .write()
@ -50,7 +58,7 @@ impl MersData for Reference {
.mut_any() .mut_any()
.downcast_mut::<crate::data::function::Function>() .downcast_mut::<crate::data::function::Function>()
.unwrap() .unwrap()
.run_mut(Data::empty_tuple()) .run_mut(Data::empty_tuple(), gi.clone())
{ {
Err(e) => Some(Err(e)), Err(e) => Some(Err(e)),
Ok(v) => { Ok(v) => {

View File

@ -35,7 +35,10 @@ impl MersData for Tuple {
false false
} }
} }
fn iterable(&self) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> { fn iterable(
&self,
_gi: &crate::program::run::RunLocalGlobalInfo,
) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
Some(Box::new(self.0.clone().into_iter().map(Ok))) Some(Box::new(self.0.clone().into_iter().map(Ok)))
} }
fn clone(&self) -> Box<dyn MersData> { fn clone(&self) -> Box<dyn MersData> {

View File

@ -63,14 +63,14 @@ impl Config {
} }
Ok(Type::empty_tuple()) Ok(Type::empty_tuple())
})), })),
run: Arc::new(|a, _i| { run: Arc::new(|a, i| {
let a = a.get(); let a = a.get();
let a = a.as_any().downcast_ref::<data::tuple::Tuple>().unwrap(); let a = a.as_any().downcast_ref::<data::tuple::Tuple>().unwrap();
let arg_ref = a.0[0].get(); let arg_ref = a.0[0].get();
let arg_ref = arg_ref.as_any().downcast_ref::<data::reference::Reference>().unwrap(); let arg_ref = arg_ref.as_any().downcast_ref::<data::reference::Reference>().unwrap();
let mut arg = arg_ref.0.write().unwrap(); let mut arg = arg_ref.0.write().unwrap();
let func = a.0[1].get(); let func = a.0[1].get();
*arg = func.execute(arg.clone()).unwrap()?; *arg = func.execute(arg.clone(), &i.global).unwrap()?;
Ok(Data::empty_tuple()) Ok(Data::empty_tuple())
}), }),
inner_statements: None, inner_statements: None,
@ -103,12 +103,12 @@ impl Config {
} }
Ok(Type::new(data::int::IntT(0, INT_MAX))) 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::<data::tuple::Tuple>() { Ok(Data::new(data::int::Int(if let Some(t) = a.get().as_any().downcast_ref::<data::tuple::Tuple>() {
t.0.len().try_into().unwrap_or(INT_MAX) t.0.len().try_into().unwrap_or(INT_MAX)
} else if let Some(s) = a.get().as_any().downcast_ref::<data::string::String>() { } else if let Some(s) = a.get().as_any().downcast_ref::<data::string::String>() {
s.0.len().try_into().unwrap_or(INT_MAX) 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) i.count().try_into().unwrap_or(INT_MAX)
} else { } else {
return Err("called len on {a:?}, which isn't a tuple, a string, or something iterable.".into()); 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()) Ok(bool_type())
})), })),
run: Arc::new(|a, _i| { run: Arc::new(|a, i| {
Ok(Data::new(data::bool::Bool(if let Some(mut i) = a.get().iterable() { Ok(Data::new(data::bool::Bool(if let Some(mut i) = a.get().iterable(&i.global) {
if let Some(f) = i.next() { if let Some(f) = i.next() {
let f = f?; let f = f?;
let mut o = true; let mut o = true;

View File

@ -12,7 +12,6 @@ use crate::{
object::ObjectFieldsMap, object::ObjectFieldsMap,
Data, MersData, MersDataWInfo, MersType, Type, Data, MersData, MersDataWInfo, MersType, Type,
}, },
errors::CheckError,
info::DisplayInfo, info::DisplayInfo,
program::{self, run::CheckInfo}, program::{self, run::CheckInfo},
}; };
@ -56,7 +55,7 @@ impl Config {
let cmd = cmd.get(); let cmd = cmd.get();
let (cmd, args) = ( let (cmd, args) = (
cmd.as_any().downcast_ref::<data::string::String>().unwrap(), cmd.as_any().downcast_ref::<data::string::String>().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::<Result<Vec<_>, _>>()?; let args = args.map(|v| v.map(|v| v.get().with_info(i).to_string())).collect::<Result<Vec<_>, _>>()?;
match Command::new(&cmd.0) match Command::new(&cmd.0)
@ -107,7 +106,7 @@ impl Config {
let cmd = cmd.get(); let cmd = cmd.get();
let (cmd, args) = ( let (cmd, args) = (
cmd.as_any().downcast_ref::<data::string::String>().unwrap(), cmd.as_any().downcast_ref::<data::string::String>().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::<Result<Vec<_>, _>>()?; let args = args.map(|v| v.map(|v| v.get().with_info(i).to_string())).collect::<Result<Vec<_>, _>>()?;
match Command::new(&cmd.0) match Command::new(&cmd.0)
@ -203,14 +202,14 @@ impl Config {
return Err(format!("childproc_write_bytes called on non-`(ChildProcess, Iter<Byte>)` type {}", a.with_info(i)).into()); return Err(format!("childproc_write_bytes called on non-`(ChildProcess, Iter<Byte>)` type {}", a.with_info(i)).into());
} }
})), })),
run: Arc::new(|a, _i| { run: Arc::new(|a, i| {
let a = a.get(); let a = a.get();
let tuple = a.as_any().downcast_ref::<data::tuple::Tuple>().unwrap(); let tuple = a.as_any().downcast_ref::<data::tuple::Tuple>().unwrap();
let child = tuple.0[0].get(); let child = tuple.0[0].get();
let bytes = tuple.0[1].get(); let bytes = tuple.0[1].get();
let child = child.as_any().downcast_ref::<ChildProcess>().unwrap(); let child = child.as_any().downcast_ref::<ChildProcess>().unwrap();
let mut child = child.0.lock().unwrap(); let mut child = child.0.lock().unwrap();
let buf = bytes.iterable().unwrap().map(|v| v.map(|v| v.get().as_any().downcast_ref::<data::byte::Byte>().unwrap().0)).collect::<Result<Vec<_>, _>>()?; let buf = bytes.iterable(&i.global).unwrap().map(|v| v.map(|v| v.get().as_any().downcast_ref::<data::byte::Byte>().unwrap().0)).collect::<Result<Vec<_>, _>>()?;
Ok(if child.1.as_mut().is_some_and(|v| v.write_all(&buf).is_ok() && v.flush().is_ok()) { 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)) Data::new(data::bool::Bool(true))
} else { } else {
@ -385,12 +384,6 @@ impl MersData for ChildProcess {
fn display(&self, _info: &DisplayInfo<'_>, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn display(&self, _info: &DisplayInfo<'_>, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{self}") write!(f, "{self}")
} }
fn iterable(&self) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
None
}
fn get(&self, _i: usize) -> Option<Result<Data, CheckError>> {
None
}
fn is_eq(&self, other: &dyn MersData) -> bool { fn is_eq(&self, other: &dyn MersData) -> bool {
other other
.as_any() .as_any()

View File

@ -50,14 +50,14 @@ impl Config {
Arc::new(data::tuple::TupleT(vec![])), Arc::new(data::tuple::TupleT(vec![])),
])) ]))
})), })),
run: Arc::new(|a, _i| { run: Arc::new(|a, i| {
let a = a.get(); let a = a.get();
if let (Some(v), Some(i)) = (a.get(0), a.get(1)) { if let (Some(v), Some(x)) = (a.get(0, &i.global), a.get(1, &i.global)) {
let (v, i2) = (v?, i?); let (v, x2) = (v?, x?);
let o = if let Some(i3) = i2.get().as_any().downcast_ref::<data::int::Int>() let o = if let Some(x3) = x2.get().as_any().downcast_ref::<data::int::Int>()
{ {
if let Ok(i) = i3.0.try_into() { if let Ok(x) = x3.0.try_into() {
if let Some(v) = v.get().get(i) { if let Some(v) = v.get().get(x, &i.global) {
Ok(Data::one_tuple(v?)) Ok(Data::one_tuple(v?))
} else { } else {
Ok(Data::empty_tuple()) Ok(Data::empty_tuple())

View File

@ -30,16 +30,16 @@ impl Config {
/// `all: fn` returns true if all elements of the iterator are true /// `all: fn` returns true if all elements of the iterator are true
pub fn with_iters(self) -> Self { pub fn with_iters(self) -> Self {
self self
.add_var("any", genfunc_iter_in_val_out("all".to_string(), data::bool::bool_type(), data::bool::bool_type(), |a, _i| { .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::<data::bool::Bool>().is_some_and(|v| v.0))) { for v in a.get().iterable(&i.global).unwrap().map(|v| v.map(|v| v.get().as_any().downcast_ref::<data::bool::Bool>().is_some_and(|v| v.0))) {
if v? { if v? {
return Ok(Data::new(data::bool::Bool(true))); return Ok(Data::new(data::bool::Bool(true)));
} }
} }
Ok(Data::new(data::bool::Bool(false))) 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| { .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::<data::bool::Bool>().is_some_and(|v| v.0))) { for v in a.get().iterable(&i.global).unwrap().map(|v| v.map(|v| v.get().as_any().downcast_ref::<data::bool::Bool>().is_some_and(|v| v.0))) {
if !v? { if !v? {
return Ok(Data::new(data::bool::Bool(false))); return Ok(Data::new(data::bool::Bool(false)));
} }
@ -88,13 +88,13 @@ impl Config {
} }
Ok(Type::empty_tuple()) Ok(Type::empty_tuple())
})), })),
run: Arc::new(|a, _i| { run: Arc::new(|a, i| {
if let Some(tuple) = a.get().as_any().downcast_ref::<data::tuple::Tuple>() { if let Some(tuple) = a.get().as_any().downcast_ref::<data::tuple::Tuple>() {
if let (Some(v), Some(f)) = (tuple.get(0), tuple.get(1)) { 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(); let f = f.get();
for v in iter { for v in iter {
f.execute(v?).unwrap()?; f.execute(v?, &i.global).unwrap()?;
} }
Ok(Data::empty_tuple()) Ok(Data::empty_tuple())
} else { } else {
@ -319,21 +319,25 @@ impl MersData for Iter {
fn is_eq(&self, _other: &dyn MersData) -> bool { fn is_eq(&self, _other: &dyn MersData) -> bool {
false false
} }
fn iterable(&self) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> { fn iterable(
&self,
gi: &crate::program::run::RunLocalGlobalInfo,
) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
let gi = gi.clone();
Some(match &self.0 { Some(match &self.0 {
Iters::Map(f) => { Iters::Map(f) => {
let f = Clone::clone(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() f.get()
.execute(v?) .execute(v?, &gi)
.ok_or_else(|| CheckError::from("called map with non-function argument"))? .ok_or_else(|| CheckError::from("called map with non-function argument"))?
})) }))
} }
Iters::Filter(f) => { Iters::Filter(f) => {
let f = Clone::clone(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 { match v {
Ok(v) => match f.get().execute(v.clone()) { Ok(v) => match f.get().execute(v.clone(), &gi) {
Some(Ok(f)) => { Some(Ok(f)) => {
if f.get() if f.get()
.as_any() .as_any()
@ -356,8 +360,8 @@ impl MersData for Iter {
} }
Iters::FilterMap(f) => { Iters::FilterMap(f) => {
let f = Clone::clone(f); let f = Clone::clone(f);
Box::new(self.1.get().iterable()?.filter_map(move |v| match v { Box::new(self.1.get().iterable(&gi)?.filter_map(move |v| match v {
Ok(v) => match f.get().execute(v) { Ok(v) => match f.get().execute(v, &gi) {
Some(Ok(r)) => Some(Ok(r.one_tuple_content()?)), Some(Ok(r)) => Some(Ok(r.one_tuple_content()?)),
Some(Err(e)) => Some(Err(e)), Some(Err(e)) => Some(Err(e)),
None => Some(Err(CheckError::from( None => Some(Err(CheckError::from(
@ -369,8 +373,8 @@ impl MersData for Iter {
} }
Iters::MapWhile(f) => { Iters::MapWhile(f) => {
let f = Clone::clone(f); let f = Clone::clone(f);
Box::new(self.1.get().iterable()?.map_while(move |v| match v { Box::new(self.1.get().iterable(&gi)?.map_while(move |v| match v {
Ok(v) => match f.get().execute(v) { Ok(v) => match f.get().execute(v, &gi) {
Some(Ok(r)) => Some(Ok(r.one_tuple_content()?)), Some(Ok(r)) => Some(Ok(r.one_tuple_content()?)),
Some(Err(e)) => Some(Err(e)), Some(Err(e)) => Some(Err(e)),
None => Some(Err(CheckError::from( None => Some(Err(CheckError::from(
@ -380,22 +384,28 @@ impl MersData for Iter {
Err(e) => Some(Err(e)), 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 => { Iters::Enumerate => {
Box::new(self.1.get().iterable()?.enumerate().map(|(i, v)| match v { Box::new(
self.1
.get()
.iterable(&gi)?
.enumerate()
.map(|(i, v)| match v {
Ok(v) => Ok(Data::new(data::tuple::Tuple(vec![ Ok(v) => Ok(Data::new(data::tuple::Tuple(vec![
Data::new(data::int::Int(i as _)), Data::new(data::int::Int(i as _)),
v, v,
]))), ]))),
Err(e) => Err(e), Err(e) => Err(e),
})) }),
)
} }
Iters::Chained => { Iters::Chained => {
match self match self
.1 .1
.get() .get()
.iterable()? .iterable(&gi)?
.map(|v| Ok(v?.get().iterable())) .map(move |v| Ok(v?.get().iterable(&gi)))
.collect::<Result<Option<Vec<_>>, CheckError>>() .collect::<Result<Option<Vec<_>>, CheckError>>()
{ {
Ok(Some(iters)) => Box::new(iters.into_iter().flatten()), Ok(Some(iters)) => Box::new(iters.into_iter().flatten()),

View File

@ -221,9 +221,9 @@ impl Config {
).into()) ).into())
} }
})), })),
run: Arc::new(|a, _i| { run: Arc::new(|a, i| {
if let Some(i) = a.get().iterable() { if let Some(iter) = a.get().iterable(&i.global) {
Ok(Data::new(List(i.map(|v| Ok::<_, CheckError>(Arc::new(RwLock::new(v?)))).collect::<Result<_, _>>()?))) Ok(Data::new(List(iter.map(|v| Ok::<_, CheckError>(Arc::new(RwLock::new(v?)))).collect::<Result<_, _>>()?)))
} else { } else {
Err("as_list called on non-iterable".into()) Err("as_list called on non-iterable".into())
} }
@ -272,7 +272,10 @@ impl MersData for List {
false false
} }
} }
fn iterable(&self) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> { fn iterable(
&self,
_gi: &crate::program::run::RunLocalGlobalInfo,
) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
Some(Box::new( Some(Box::new(
self.0 self.0
.clone() .clone()

View File

@ -501,10 +501,10 @@ impl Config {
} }
Ok(o) Ok(o)
}, },
|a, _| { |a, i| {
let mut min_int = None; let mut min_int = None;
let mut min_float = 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?;
let a = a.get(); let a = a.get();
let a = a.as_any().downcast_ref::<data::int::Int>().map(|v| Ok(v.0)).or_else(|| a.as_any().downcast_ref::<data::float::Float>().map(|v| Err(v.0))).expect("found non-Int/Float element in argument to `min`"); let a = a.as_any().downcast_ref::<data::int::Int>().map(|v| Ok(v.0)).or_else(|| a.as_any().downcast_ref::<data::float::Float>().map(|v| Err(v.0))).expect("found non-Int/Float element in argument to `min`");
@ -581,10 +581,10 @@ impl Config {
} }
Ok(o) Ok(o)
}, },
|a, _| { |a, i| {
let mut min_int = None; let mut min_int = None;
let mut min_float = 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?;
let a = a.get(); let a = a.get();
let a = a.as_any().downcast_ref::<data::int::Int>().map(|v| Ok(v.0)).or_else(|| a.as_any().downcast_ref::<data::float::Float>().map(|v| Err(v.0))).expect("found non-Int/Float element in argument to `min`"); let a = a.as_any().downcast_ref::<data::int::Int>().map(|v| Ok(v.0)).or_else(|| a.as_any().downcast_ref::<data::float::Float>().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) Ok(o)
}, },
move |a, _| { move |a, i| {
let a = a.get(); let a = a.get();
Ok( Ok(
if let Some(a) = &a if let Some(a) = &a
@ -839,7 +839,7 @@ fn func_math_op(
let (mut acc, _) = iter_version let (mut acc, _) = iter_version
.expect("no iter version for this math op, but argument not a 2-tuple..."); .expect("no iter version for this math op, but argument not a 2-tuple...");
for a in a for a in a
.iterable() .iterable(&i.global)
.expect("math op with iter version called on non-iterable") .expect("math op with iter version called on non-iterable")
{ {
let a = a?; let a = a?;

View File

@ -47,9 +47,10 @@ impl Config {
} }
Ok(Type::new(ThreadT(out))) 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( 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, inner_statements: None,

View File

@ -81,7 +81,7 @@ impl Config {
|a, i| { |a, i| {
Ok(Data::new(data::string::String( Ok(Data::new(data::string::String(
a.get() a.get()
.iterable() .iterable(&i.global)
.unwrap() .unwrap()
.map(|v| v.map(|v| v.get().with_info(i).to_string())) .map(|v| v.map(|v| v.get().with_info(i).to_string()))
.collect::<Result<_, _>>()?, .collect::<Result<_, _>>()?,

View File

@ -92,7 +92,7 @@ impl MersStatement for Chain {
let f = self.first.run(info)?; let f = self.first.run(info)?;
let c = self.chained.run(info)?; let c = self.chained.run(info)?;
let c = c.get(); let c = c.get();
match c.execute(f) { match c.execute(f, &info.global) {
Some(Ok(v)) => Ok(v), Some(Ok(v)) => Ok(v),
Some(Err(e)) => Err(if let Some(_) = &self.as_part_of_include { Some(Err(e)) => Err(if let Some(_) = &self.as_part_of_include {
CheckError::new().err_with_diff_src(e).src(vec![( CheckError::new().err_with_diff_src(e).src(vec![(

View File

@ -116,7 +116,7 @@ impl MersStatement for Try {
match func.executable().map(|func| func.o(&arg_type)) { match func.executable().map(|func| func.o(&arg_type)) {
Some(Ok(_)) => { Some(Ok(_)) => {
drop(ar); drop(ar);
return func.execute(arg).unwrap(); return func.execute(arg, &info.global).unwrap();
} }
None | Some(Err(_)) => (), None | Some(Err(_)) => (),
} }