mirror of
				https://github.com/Dummi26/mers.git
				synced 2025-11-04 13:21:26 +01:00 
			
		
		
		
	improve panic function, add stacktrace
This commit is contained in:
		
							parent
							
								
									4770e3f939
								
							
						
					
					
						commit
						cd21c2171e
					
				@ -1,6 +1,6 @@
 | 
			
		||||
[package]
 | 
			
		||||
name = "mers"
 | 
			
		||||
version = "0.8.8"
 | 
			
		||||
version = "0.8.9"
 | 
			
		||||
edition = "2021"
 | 
			
		||||
license = "MIT OR Apache-2.0"
 | 
			
		||||
description = "dynamically typed but type-checked programming language"
 | 
			
		||||
@ -11,7 +11,7 @@ repository = "https://github.com/Dummi26/mers"
 | 
			
		||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
mers_lib = "0.8.8"
 | 
			
		||||
mers_lib = "0.8.9"
 | 
			
		||||
# mers_lib = { path = "../mers_lib" }
 | 
			
		||||
clap = { version = "4.3.19", features = ["derive"] }
 | 
			
		||||
colored = "2.1.0"
 | 
			
		||||
 | 
			
		||||
@ -122,7 +122,10 @@ fn main() {
 | 
			
		||||
                                exit(255);
 | 
			
		||||
                            }
 | 
			
		||||
                            Ok(_) => {
 | 
			
		||||
                                compiled.run(&mut i2);
 | 
			
		||||
                                if let Err(e) = compiled.run(&mut i2) {
 | 
			
		||||
                                    eprintln!("Error while running: {}", e);
 | 
			
		||||
                                    std::process::exit(1);
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        },
 | 
			
		||||
                    }
 | 
			
		||||
@ -145,7 +148,10 @@ fn main() {
 | 
			
		||||
                            exit(255);
 | 
			
		||||
                        }
 | 
			
		||||
                        Ok(compiled) => {
 | 
			
		||||
                            compiled.run(&mut i2);
 | 
			
		||||
                            if let Err(e) = compiled.run(&mut i2) {
 | 
			
		||||
                                eprintln!("Error while running: {}", e);
 | 
			
		||||
                                std::process::exit(1);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
[package]
 | 
			
		||||
name = "mers_lib"
 | 
			
		||||
version = "0.8.8"
 | 
			
		||||
version = "0.8.9"
 | 
			
		||||
edition = "2021"
 | 
			
		||||
license = "MIT OR Apache-2.0"
 | 
			
		||||
description = "library to use the mers language in other projects"
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ fn parse_compile_check_run(src: String) -> Result<(Type, Data), CheckError> {
 | 
			
		||||
    // check (this step is optional, but if it is skipped when it would have returned an error, `run` will likely panic)
 | 
			
		||||
    let output_type = compiled.check(&mut i3, None)?;
 | 
			
		||||
    // run
 | 
			
		||||
    let output_value = compiled.run(&mut i2);
 | 
			
		||||
    let output_value = compiled.run(&mut i2)?;
 | 
			
		||||
    // check that the predicted output type was correct
 | 
			
		||||
    assert!(output_value.get().as_type().is_included_in(&output_type));
 | 
			
		||||
    // return the produced value
 | 
			
		||||
 | 
			
		||||
@ -23,7 +23,7 @@ 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(Data::new(data::string::String(input.to_owned())));
 | 
			
		||||
        let result = func.run(Data::new(data::string::String(input.to_owned())))?;
 | 
			
		||||
        let result = result.get();
 | 
			
		||||
        let result = &result
 | 
			
		||||
            .as_any()
 | 
			
		||||
@ -44,6 +44,6 @@ fn parse_compile_check_run(src: String) -> Result<(Type, Data), CheckError> {
 | 
			
		||||
    let (mut i1, mut i2, mut i3) = Config::new().bundle_std().infos();
 | 
			
		||||
    let compiled = parsed.compile(&mut i1, CompInfo::default())?;
 | 
			
		||||
    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))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -48,7 +48,7 @@ fn run(src: String) -> Result<(), CheckError> {
 | 
			
		||||
                        .downcast_ref::<data::string::String>()
 | 
			
		||||
                        .unwrap()
 | 
			
		||||
                        .0;
 | 
			
		||||
                    Data::new(data::string::String(arg.chars().rev().collect()))
 | 
			
		||||
                    Ok(Data::new(data::string::String(arg.chars().rev().collect())))
 | 
			
		||||
                },
 | 
			
		||||
            )),
 | 
			
		||||
        )
 | 
			
		||||
@ -56,6 +56,6 @@ fn run(src: String) -> Result<(), CheckError> {
 | 
			
		||||
 | 
			
		||||
    let compiled = parsed.compile(&mut i1, CompInfo::default())?;
 | 
			
		||||
    compiled.check(&mut i3, None)?;
 | 
			
		||||
    compiled.run(&mut i2);
 | 
			
		||||
    compiled.run(&mut i2)?;
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,8 @@ pub struct Function {
 | 
			
		||||
    pub info: Arc<Info>,
 | 
			
		||||
    pub info_check: Arc<Mutex<CheckInfo>>,
 | 
			
		||||
    pub out: Arc<dyn Fn(&Type, &mut CheckInfo) -> Result<Type, CheckError> + Send + Sync>,
 | 
			
		||||
    pub run: Arc<dyn Fn(Data, &mut crate::program::run::Info) -> Data + Send + Sync>,
 | 
			
		||||
    pub run:
 | 
			
		||||
        Arc<dyn Fn(Data, &mut crate::program::run::Info) -> Result<Data, CheckError> + Send + Sync>,
 | 
			
		||||
    pub inner_statements: Option<(
 | 
			
		||||
        Arc<Box<dyn crate::program::run::MersStatement>>,
 | 
			
		||||
        Arc<Box<dyn crate::program::run::MersStatement>>,
 | 
			
		||||
@ -25,7 +26,7 @@ pub struct Function {
 | 
			
		||||
impl Function {
 | 
			
		||||
    pub fn new(
 | 
			
		||||
        out: impl Fn(&Type) -> Result<Type, CheckError> + Send + Sync + 'static,
 | 
			
		||||
        run: impl Fn(Data) -> Data + Send + Sync + 'static,
 | 
			
		||||
        run: impl Fn(Data) -> Result<Data, CheckError> + Send + Sync + 'static,
 | 
			
		||||
    ) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            info: Arc::new(crate::info::Info::neverused()),
 | 
			
		||||
@ -56,7 +57,7 @@ impl Function {
 | 
			
		||||
        drop(lock);
 | 
			
		||||
        (self.out)(arg, &mut info)
 | 
			
		||||
    }
 | 
			
		||||
    pub fn run(&self, arg: Data) -> Data {
 | 
			
		||||
    pub fn run(&self, arg: Data) -> Result<Data, CheckError> {
 | 
			
		||||
        (self.run)(arg, &mut self.info.as_ref().clone())
 | 
			
		||||
    }
 | 
			
		||||
    pub fn get_as_type(&self) -> FunctionT {
 | 
			
		||||
@ -72,10 +73,19 @@ impl Function {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl MersData for Function {
 | 
			
		||||
    fn iterable(&self) -> Option<Box<dyn Iterator<Item = Data>>> {
 | 
			
		||||
    fn iterable(&self) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
 | 
			
		||||
        let s = Clone::clone(self);
 | 
			
		||||
        Some(Box::new(std::iter::from_fn(move || {
 | 
			
		||||
            s.run(Data::empty_tuple()).one_tuple_content()
 | 
			
		||||
            match s.run(Data::empty_tuple()) {
 | 
			
		||||
                Err(e) => Some(Err(e)),
 | 
			
		||||
                Ok(v) => {
 | 
			
		||||
                    if let Some(v) = v.one_tuple_content() {
 | 
			
		||||
                        Some(Ok(v))
 | 
			
		||||
                    } else {
 | 
			
		||||
                        None
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        })))
 | 
			
		||||
    }
 | 
			
		||||
    fn is_eq(&self, _other: &dyn MersData) -> bool {
 | 
			
		||||
 | 
			
		||||
@ -4,6 +4,8 @@ use std::{
 | 
			
		||||
    sync::{atomic::AtomicUsize, Arc, RwLock, RwLockReadGuard, RwLockWriteGuard},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use crate::errors::CheckError;
 | 
			
		||||
 | 
			
		||||
pub mod bool;
 | 
			
		||||
pub mod byte;
 | 
			
		||||
pub mod float;
 | 
			
		||||
@ -17,12 +19,12 @@ pub mod tuple;
 | 
			
		||||
pub mod defs;
 | 
			
		||||
 | 
			
		||||
pub trait MersData: Any + Debug + Display + Send + Sync {
 | 
			
		||||
    fn iterable(&self) -> Option<Box<dyn Iterator<Item = Data>>> {
 | 
			
		||||
    fn iterable(&self) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
 | 
			
		||||
        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<Data> {
 | 
			
		||||
    fn get(&self, i: usize) -> Option<Result<Data, CheckError>> {
 | 
			
		||||
        self.iterable()?.nth(i)
 | 
			
		||||
    }
 | 
			
		||||
    /// If self and other are different types (`other.as_any().downcast_ref::<Self>().is_none()`),
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,7 @@
 | 
			
		||||
use std::{any::Any, fmt::Display, sync::Arc};
 | 
			
		||||
 | 
			
		||||
use crate::errors::CheckError;
 | 
			
		||||
 | 
			
		||||
use super::{Data, MersData, MersType, Type};
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
@ -22,8 +24,8 @@ impl MersData for Tuple {
 | 
			
		||||
            false
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    fn iterable(&self) -> Option<Box<dyn Iterator<Item = Data>>> {
 | 
			
		||||
        Some(Box::new(self.0.clone().into_iter()))
 | 
			
		||||
    fn iterable(&self) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
 | 
			
		||||
        Some(Box::new(self.0.clone().into_iter().map(Ok)))
 | 
			
		||||
    }
 | 
			
		||||
    fn clone(&self) -> Box<dyn MersData> {
 | 
			
		||||
        Box::new(Clone::clone(self))
 | 
			
		||||
 | 
			
		||||
@ -395,6 +395,11 @@ impl From<String> for CheckError {
 | 
			
		||||
        Self::new().msg(value)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
impl From<&str> for CheckError {
 | 
			
		||||
    fn from(value: &str) -> Self {
 | 
			
		||||
        Self::new().msg(value.to_owned())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
impl Debug for CheckError {
 | 
			
		||||
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
			
		||||
        write!(f, "{self}")
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,7 @@ use crate::{
 | 
			
		||||
 | 
			
		||||
pub fn to_mers_func(
 | 
			
		||||
    out: impl Fn(&Type) -> Result<Type, CheckError> + Send + Sync + 'static,
 | 
			
		||||
    run: impl Fn(Data) -> Data + Send + Sync + 'static,
 | 
			
		||||
    run: impl Fn(Data) -> Result<Data, CheckError> + Send + Sync + 'static,
 | 
			
		||||
) -> data::function::Function {
 | 
			
		||||
    data::function::Function {
 | 
			
		||||
        info: Arc::new(Info::neverused()),
 | 
			
		||||
@ -22,7 +22,7 @@ pub fn to_mers_func(
 | 
			
		||||
pub fn to_mers_func_with_in_type(
 | 
			
		||||
    in_type: Type,
 | 
			
		||||
    out: impl Fn(&Type) -> Result<Type, CheckError> + Send + Sync + 'static,
 | 
			
		||||
    run: impl Fn(Data) -> Data + Send + Sync + 'static,
 | 
			
		||||
    run: impl Fn(Data) -> Result<Data, CheckError> + Send + Sync + 'static,
 | 
			
		||||
) -> data::function::Function {
 | 
			
		||||
    to_mers_func(
 | 
			
		||||
        move |a| {
 | 
			
		||||
@ -39,7 +39,7 @@ pub fn to_mers_func_with_in_type(
 | 
			
		||||
pub fn to_mers_func_with_in_out_types(
 | 
			
		||||
    in_type: Type,
 | 
			
		||||
    out_type: Type,
 | 
			
		||||
    run: impl Fn(Data) -> Data + Send + Sync + 'static,
 | 
			
		||||
    run: impl Fn(Data) -> Result<Data, CheckError> + Send + Sync + 'static,
 | 
			
		||||
) -> data::function::Function {
 | 
			
		||||
    to_mers_func(
 | 
			
		||||
        move |a| {
 | 
			
		||||
@ -55,7 +55,7 @@ pub fn to_mers_func_with_in_out_types(
 | 
			
		||||
 | 
			
		||||
pub fn to_mers_func_concrete_string_to_any(
 | 
			
		||||
    out_type: Type,
 | 
			
		||||
    f: impl Fn(&str) -> Data + Send + Sync + 'static,
 | 
			
		||||
    f: impl Fn(&str) -> Result<Data, CheckError> + Send + Sync + 'static,
 | 
			
		||||
) -> data::function::Function {
 | 
			
		||||
    to_mers_func_with_in_out_types(Type::new(data::string::StringT), out_type, move |a| {
 | 
			
		||||
        f(a.get()
 | 
			
		||||
@ -70,13 +70,13 @@ pub fn to_mers_func_concrete_string_to_string(
 | 
			
		||||
    f: impl Fn(&str) -> String + Send + Sync + 'static,
 | 
			
		||||
) -> data::function::Function {
 | 
			
		||||
    to_mers_func_concrete_string_to_any(Type::new(data::string::StringT), move |a| {
 | 
			
		||||
        Data::new(data::string::String(f(a)))
 | 
			
		||||
        Ok(Data::new(data::string::String(f(a))))
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn to_mers_func_concrete_string_string_to_any(
 | 
			
		||||
    out_type: Type,
 | 
			
		||||
    f: impl Fn(&str, &str) -> Data + Send + Sync + 'static,
 | 
			
		||||
    f: impl Fn(&str, &str) -> Result<Data, CheckError> + Send + Sync + 'static,
 | 
			
		||||
) -> data::function::Function {
 | 
			
		||||
    to_mers_func_with_in_out_types(
 | 
			
		||||
        Type::new(data::tuple::TupleT(vec![
 | 
			
		||||
@ -109,13 +109,13 @@ pub fn to_mers_func_concrete_string_string_to_opt_int(
 | 
			
		||||
) -> data::function::Function {
 | 
			
		||||
    to_mers_func_concrete_string_string_to_any(
 | 
			
		||||
        Type::newm(vec![
 | 
			
		||||
            Arc::new(data::tuple::TupleT(vec![Type::new(data::int::IntT)])),
 | 
			
		||||
            Arc::new(data::tuple::TupleT(vec![])),
 | 
			
		||||
            Arc::new(data::int::IntT),
 | 
			
		||||
        ]),
 | 
			
		||||
        move |a, b| {
 | 
			
		||||
            f(a, b)
 | 
			
		||||
                .map(|v| Data::new(data::int::Int(v)))
 | 
			
		||||
                .unwrap_or_else(|| Data::empty_tuple())
 | 
			
		||||
            Ok(f(a, b)
 | 
			
		||||
                .map(|v| Data::one_tuple(Data::new(data::int::Int(v))))
 | 
			
		||||
                .unwrap_or_else(|| Data::empty_tuple()))
 | 
			
		||||
        },
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
@ -123,7 +123,7 @@ pub fn to_mers_func_concrete_string_string_to_bool(
 | 
			
		||||
    f: impl Fn(&str, &str) -> bool + Send + Sync + 'static,
 | 
			
		||||
) -> data::function::Function {
 | 
			
		||||
    to_mers_func_concrete_string_string_to_any(Type::new(data::bool::BoolT), move |a, b| {
 | 
			
		||||
        Data::new(data::bool::Bool(f(a, b)))
 | 
			
		||||
        Ok(Data::new(data::bool::Bool(f(a, b))))
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
pub fn to_mers_func_concrete_string_string_to_opt_string_string(
 | 
			
		||||
@ -138,14 +138,14 @@ pub fn to_mers_func_concrete_string_string_to_opt_string_string(
 | 
			
		||||
            ])),
 | 
			
		||||
        ]),
 | 
			
		||||
        move |a, b| {
 | 
			
		||||
            f(a, b)
 | 
			
		||||
            Ok(f(a, b)
 | 
			
		||||
                .map(|(a, b)| {
 | 
			
		||||
                    Data::new(data::tuple::Tuple(vec![
 | 
			
		||||
                        Data::new(data::string::String(a)),
 | 
			
		||||
                        Data::new(data::string::String(b)),
 | 
			
		||||
                    ]))
 | 
			
		||||
                })
 | 
			
		||||
                .unwrap_or_else(|| Data::empty_tuple())
 | 
			
		||||
                .unwrap_or_else(|| Data::empty_tuple()))
 | 
			
		||||
        },
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -70,10 +70,10 @@ impl Config {
 | 
			
		||||
                    let mut arg = arg_ref.0.write().unwrap();
 | 
			
		||||
                    let func = a.0[1].get();
 | 
			
		||||
                    let func = func.as_any().downcast_ref::<data::function::Function>().unwrap();
 | 
			
		||||
                    *arg = func.run(arg.clone());
 | 
			
		||||
                    Data::empty_tuple()
 | 
			
		||||
                    *arg = func.run(arg.clone())?;
 | 
			
		||||
                    Ok(Data::empty_tuple())
 | 
			
		||||
                }),
 | 
			
		||||
            inner_statements: None,
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
            }))
 | 
			
		||||
            .add_var("sleep".to_string(), Data::new(data::function::Function {
 | 
			
		||||
                info: Arc::new(Info::neverused()),
 | 
			
		||||
@ -95,11 +95,11 @@ impl Config {
 | 
			
		||||
                    } else {
 | 
			
		||||
                        unreachable!("sleep called on non-int/non-float")
 | 
			
		||||
                    });
 | 
			
		||||
                    Data::empty_tuple()
 | 
			
		||||
                    Ok(Data::empty_tuple())
 | 
			
		||||
                }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
            }))
 | 
			
		||||
            .add_var("panic".to_string(), Data::new(data::function::Function {
 | 
			
		||||
            .add_var("exit".to_string(), Data::new(data::function::Function {
 | 
			
		||||
                info: Arc::new(Info::neverused()),
 | 
			
		||||
                info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
 | 
			
		||||
            out: Arc::new(|a, _i| if a.is_included_in_single(&data::int::IntT) {
 | 
			
		||||
@ -111,6 +111,26 @@ impl Config {
 | 
			
		||||
                std::process::exit(a.get().as_any().downcast_ref::<data::int::Int>().map(|i| i.0 as _).unwrap_or(1));
 | 
			
		||||
            }),
 | 
			
		||||
            inner_statements: None,
 | 
			
		||||
        }))
 | 
			
		||||
            .add_var("panic".to_string(), Data::new(data::function::Function {
 | 
			
		||||
                info: Arc::new(Info::neverused()),
 | 
			
		||||
                info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
 | 
			
		||||
            out: Arc::new(|a, _i| if a.is_included_in_single(&data::string::StringT) {
 | 
			
		||||
                Ok(Type::empty())
 | 
			
		||||
            } else {
 | 
			
		||||
                Err(format!("cannot call panic with non-string argument").into())
 | 
			
		||||
            }),
 | 
			
		||||
            run: Arc::new(|a, _i|  {
 | 
			
		||||
                Err(
 | 
			
		||||
                    a
 | 
			
		||||
                        .get()
 | 
			
		||||
                        .as_any()
 | 
			
		||||
                        .downcast_ref::<data::string::String>()
 | 
			
		||||
                        .map(|i| i.0.to_owned())
 | 
			
		||||
                        .unwrap_or_else(String::new).into()
 | 
			
		||||
                )
 | 
			
		||||
            }),
 | 
			
		||||
            inner_statements: None,
 | 
			
		||||
        }))
 | 
			
		||||
            .add_var(
 | 
			
		||||
            "len".to_string(),
 | 
			
		||||
@ -126,7 +146,7 @@ impl Config {
 | 
			
		||||
                    Ok(Type::new(data::int::IntT))
 | 
			
		||||
                }),
 | 
			
		||||
                run: Arc::new(|a, _i| {
 | 
			
		||||
                    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() as _
 | 
			
		||||
                    } else if let Some(s) = a.get().as_any().downcast_ref::<data::string::String>() {
 | 
			
		||||
                        s.0.len() as _
 | 
			
		||||
@ -135,7 +155,7 @@ impl Config {
 | 
			
		||||
                            i.take(isize::MAX as usize + 1).count() as isize
 | 
			
		||||
                    } else {
 | 
			
		||||
                        unreachable!("called len on {a:?}, which isn't a tuple or a string")
 | 
			
		||||
                    }))
 | 
			
		||||
                    })))
 | 
			
		||||
                }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
            }),
 | 
			
		||||
@ -154,10 +174,12 @@ impl Config {
 | 
			
		||||
                        Ok(Type::new(data::bool::BoolT))
 | 
			
		||||
                    }),
 | 
			
		||||
                run: Arc::new(|a, _i| {
 | 
			
		||||
                    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() {
 | 
			
		||||
                        if let Some(f) = i.next() {
 | 
			
		||||
                            let f = f?;
 | 
			
		||||
                            let mut o = true;
 | 
			
		||||
                            for el in i {
 | 
			
		||||
                                let el = el?;
 | 
			
		||||
                                if el != f {
 | 
			
		||||
                                    o = false;
 | 
			
		||||
                                    break;
 | 
			
		||||
@ -169,7 +191,7 @@ impl Config {
 | 
			
		||||
                        }
 | 
			
		||||
                    } else {
 | 
			
		||||
                        false
 | 
			
		||||
                    }))
 | 
			
		||||
                    })))
 | 
			
		||||
                }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
            }),
 | 
			
		||||
@ -181,7 +203,7 @@ impl Config {
 | 
			
		||||
                info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
 | 
			
		||||
                out: Arc::new(|a, _i| Ok(Type::new(data::reference::ReferenceT(a.clone())))),
 | 
			
		||||
                run: Arc::new(|a, _i| {
 | 
			
		||||
                    Data::new(data::reference::Reference(Arc::new(RwLock::new(a.clone()))))
 | 
			
		||||
                    Ok(Data::new(data::reference::Reference(Arc::new(RwLock::new(a.clone())))))
 | 
			
		||||
                }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
            }),
 | 
			
		||||
@ -199,9 +221,9 @@ impl Config {
 | 
			
		||||
                        .as_any()
 | 
			
		||||
                        .downcast_ref::<data::reference::Reference>()
 | 
			
		||||
                    {
 | 
			
		||||
                        r.0.write().unwrap().clone()
 | 
			
		||||
                        Ok(r.0.write().unwrap().clone())
 | 
			
		||||
                    } else {
 | 
			
		||||
                        unreachable!("called deref on non-reference")
 | 
			
		||||
                        Err("called deref on non-reference".into())
 | 
			
		||||
                    }
 | 
			
		||||
                }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
 | 
			
		||||
@ -7,6 +7,7 @@ use std::{
 | 
			
		||||
 | 
			
		||||
use crate::{
 | 
			
		||||
    data::{self, Data, MersData, MersType, Type},
 | 
			
		||||
    errors::CheckError,
 | 
			
		||||
    program::{self, run::CheckInfo},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -51,8 +52,9 @@ impl Config {
 | 
			
		||||
                        cmd.as_any().downcast_ref::<data::string::String>().unwrap(),
 | 
			
		||||
                        args.get().iterable().unwrap(),
 | 
			
		||||
                    );
 | 
			
		||||
                    let args = args.map(|v| v.map(|v| v.get().to_string())).collect::<Result<Vec<_>, _>>()?;
 | 
			
		||||
                    match Command::new(&cmd.0)
 | 
			
		||||
                        .args(args.map(|v| v.get().to_string()))
 | 
			
		||||
                        .args(args)
 | 
			
		||||
                        .output()
 | 
			
		||||
                    {
 | 
			
		||||
                        Ok(output) => {
 | 
			
		||||
@ -65,13 +67,13 @@ impl Config {
 | 
			
		||||
                                String::from_utf8_lossy(&output.stdout).into_owned();
 | 
			
		||||
                            let stderr =
 | 
			
		||||
                                String::from_utf8_lossy(&output.stderr).into_owned();
 | 
			
		||||
                            Data::new(data::tuple::Tuple(vec![
 | 
			
		||||
                            Ok(Data::new(data::tuple::Tuple(vec![
 | 
			
		||||
                                status,
 | 
			
		||||
                                Data::new(data::string::String(stdout)),
 | 
			
		||||
                                Data::new(data::string::String(stderr)),
 | 
			
		||||
                            ]))
 | 
			
		||||
                            ])))
 | 
			
		||||
                        }
 | 
			
		||||
                        Err(e) => Data::new(data::object::Object(vec![("run_command_error".to_owned(), Data::new(data::string::String(e.to_string())))])),
 | 
			
		||||
                        Err(e) => Ok(Data::new(data::object::Object(vec![("run_command_error".to_owned(), Data::new(data::string::String(e.to_string())))]))),
 | 
			
		||||
                    }
 | 
			
		||||
                }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
@ -101,8 +103,9 @@ impl Config {
 | 
			
		||||
                        cmd.as_any().downcast_ref::<data::string::String>().unwrap(),
 | 
			
		||||
                        args.get().iterable().unwrap(),
 | 
			
		||||
                    );
 | 
			
		||||
                    let args = args.map(|v| v.map(|v| v.get().to_string())).collect::<Result<Vec<_>, _>>()?;
 | 
			
		||||
                    match Command::new(&cmd.0)
 | 
			
		||||
                        .args(args.map(|v| v.get().to_string()))
 | 
			
		||||
                        .args(args)
 | 
			
		||||
                        .stdin(Stdio::piped())
 | 
			
		||||
                        .stdout(Stdio::piped())
 | 
			
		||||
                        .stderr(Stdio::piped())
 | 
			
		||||
@ -112,9 +115,9 @@ impl Config {
 | 
			
		||||
                            let a = Some(child.stdin.take().unwrap());
 | 
			
		||||
                            let b = BufReader::new(child.stdout.take().unwrap());
 | 
			
		||||
                            let c = BufReader::new(child.stderr.take().unwrap());
 | 
			
		||||
                            Data::new(ChildProcess(Arc::new(Mutex::new((child, a, b, c)))))
 | 
			
		||||
                            Ok(Data::new(ChildProcess(Arc::new(Mutex::new((child, a, b, c))))))
 | 
			
		||||
                        }
 | 
			
		||||
                        Err(e) => Data::new(data::object::Object(vec![("run_command_error".to_owned(), Data::new(data::string::String(e.to_string())))])),
 | 
			
		||||
                        Err(e) => Ok(Data::new(data::object::Object(vec![("run_command_error".to_owned(), Data::new(data::string::String(e.to_string())))]))),
 | 
			
		||||
                    }
 | 
			
		||||
                }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
@ -139,11 +142,11 @@ impl Config {
 | 
			
		||||
                    let a = a.get();
 | 
			
		||||
                    let child = a.as_any().downcast_ref::<ChildProcess>().unwrap();
 | 
			
		||||
                    let mut child = child.0.lock().unwrap();
 | 
			
		||||
                    match child.0.try_wait() {
 | 
			
		||||
                    Ok(match child.0.try_wait() {
 | 
			
		||||
                        Ok(Some(_)) => Data::one_tuple(Data::new(data::bool::Bool(true))),
 | 
			
		||||
                        Ok(None) => Data::one_tuple(Data::new(data::bool::Bool(false))),
 | 
			
		||||
                        Err(_) => Data::empty_tuple(),
 | 
			
		||||
                    }
 | 
			
		||||
                    })
 | 
			
		||||
                }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
            }),
 | 
			
		||||
@ -169,14 +172,14 @@ impl Config {
 | 
			
		||||
                    let child = a.as_any().downcast_ref::<ChildProcess>().unwrap();
 | 
			
		||||
                    let mut child = child.0.lock().unwrap();
 | 
			
		||||
                    drop(child.1.take());
 | 
			
		||||
                    match child.0.wait() {
 | 
			
		||||
                    Ok(match child.0.wait() {
 | 
			
		||||
                        Ok(s) => if let Some(s) = s.code() {
 | 
			
		||||
                            Data::new(data::int::Int(s as _))
 | 
			
		||||
                        } else {
 | 
			
		||||
                            Data::new(data::bool::Bool(s.success()))
 | 
			
		||||
                        }
 | 
			
		||||
                        Err(_) => Data::empty_tuple(),
 | 
			
		||||
                    }
 | 
			
		||||
                    })
 | 
			
		||||
                }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
            }),
 | 
			
		||||
@ -200,12 +203,12 @@ impl Config {
 | 
			
		||||
                    let bytes = tuple.0[1].get();
 | 
			
		||||
                    let child = child.as_any().downcast_ref::<ChildProcess>().unwrap();
 | 
			
		||||
                    let mut child = child.0.lock().unwrap();
 | 
			
		||||
                    let buf = bytes.iterable().unwrap().map(|v| v.get().as_any().downcast_ref::<data::byte::Byte>().unwrap().0).collect::<Vec<_>>();
 | 
			
		||||
                    if child.1.as_mut().is_some_and(|v| v.write_all(&buf).is_ok() && v.flush().is_ok()) {
 | 
			
		||||
                    let buf = bytes.iterable().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()) {
 | 
			
		||||
                        Data::new(data::bool::Bool(true))
 | 
			
		||||
                    } else {
 | 
			
		||||
                        Data::new(data::bool::Bool(false))
 | 
			
		||||
                    }
 | 
			
		||||
                    })
 | 
			
		||||
                }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
            }),
 | 
			
		||||
@ -230,11 +233,11 @@ impl Config {
 | 
			
		||||
                    let child = child.as_any().downcast_ref::<ChildProcess>().unwrap();
 | 
			
		||||
                    let mut child = child.0.lock().unwrap();
 | 
			
		||||
                    let buf = string.as_any().downcast_ref::<data::string::String>().unwrap().0.as_bytes();
 | 
			
		||||
                    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))
 | 
			
		||||
                    } else {
 | 
			
		||||
                        Data::new(data::bool::Bool(false))
 | 
			
		||||
                    }
 | 
			
		||||
                    })
 | 
			
		||||
                }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
            }),
 | 
			
		||||
@ -259,11 +262,11 @@ impl Config {
 | 
			
		||||
                    let child = a.as_any().downcast_ref::<ChildProcess>().unwrap();
 | 
			
		||||
                        let mut child = child.0.lock().unwrap();
 | 
			
		||||
                        let mut buf = [0];
 | 
			
		||||
                        if child.2.read_exact(&mut buf).is_ok() {
 | 
			
		||||
                        Ok(if child.2.read_exact(&mut buf).is_ok() {
 | 
			
		||||
                            Data::one_tuple(Data::new(data::byte::Byte(buf[0])))
 | 
			
		||||
                        } else {
 | 
			
		||||
                            Data::empty_tuple()
 | 
			
		||||
                        }
 | 
			
		||||
                        })
 | 
			
		||||
                }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
            }),
 | 
			
		||||
@ -288,11 +291,11 @@ impl Config {
 | 
			
		||||
                    let child = a.as_any().downcast_ref::<ChildProcess>().unwrap();
 | 
			
		||||
                    let mut child = child.0.lock().unwrap();
 | 
			
		||||
                    let mut buf = [0];
 | 
			
		||||
                    if child.3.read_exact(&mut buf).is_ok() {
 | 
			
		||||
                    Ok(if child.3.read_exact(&mut buf).is_ok() {
 | 
			
		||||
                        Data::one_tuple(Data::new(data::byte::Byte(buf[0])))
 | 
			
		||||
                    } else {
 | 
			
		||||
                        Data::empty_tuple()
 | 
			
		||||
                    }
 | 
			
		||||
                    })
 | 
			
		||||
                }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
            }),
 | 
			
		||||
@ -317,11 +320,11 @@ impl Config {
 | 
			
		||||
                    let child = a.as_any().downcast_ref::<ChildProcess>().unwrap();
 | 
			
		||||
                    let mut child = child.0.lock().unwrap();
 | 
			
		||||
                    let mut buf = String::new();
 | 
			
		||||
                    if child.2.read_line(&mut buf).is_ok() {
 | 
			
		||||
                    Ok(if child.2.read_line(&mut buf).is_ok() {
 | 
			
		||||
                        Data::one_tuple(Data::new(data::string::String(buf)))
 | 
			
		||||
                    } else {
 | 
			
		||||
                        Data::empty_tuple()
 | 
			
		||||
                    }
 | 
			
		||||
                    })
 | 
			
		||||
                }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
            }),
 | 
			
		||||
@ -346,11 +349,11 @@ impl Config {
 | 
			
		||||
                    let child = a.as_any().downcast_ref::<ChildProcess>().unwrap();
 | 
			
		||||
                    let mut child = child.0.lock().unwrap();
 | 
			
		||||
                    let mut buf = String::new();
 | 
			
		||||
                    if child.3.read_line(&mut buf).is_ok() {
 | 
			
		||||
                    Ok(if child.3.read_line(&mut buf).is_ok() {
 | 
			
		||||
                        Data::one_tuple(Data::new(data::string::String(buf)))
 | 
			
		||||
                    } else {
 | 
			
		||||
                        Data::empty_tuple()
 | 
			
		||||
                    }
 | 
			
		||||
                    })
 | 
			
		||||
                }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
            }),
 | 
			
		||||
@ -372,10 +375,10 @@ pub struct ChildProcess(
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
pub struct ChildProcessT;
 | 
			
		||||
impl MersData for ChildProcess {
 | 
			
		||||
    fn iterable(&self) -> Option<Box<dyn Iterator<Item = Data>>> {
 | 
			
		||||
    fn iterable(&self) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
 | 
			
		||||
        None
 | 
			
		||||
    }
 | 
			
		||||
    fn get(&self, _i: usize) -> Option<Data> {
 | 
			
		||||
    fn get(&self, _i: usize) -> Option<Result<Data, CheckError>> {
 | 
			
		||||
        None
 | 
			
		||||
    }
 | 
			
		||||
    fn is_eq(&self, other: &dyn MersData) -> bool {
 | 
			
		||||
 | 
			
		||||
@ -49,21 +49,24 @@ impl Config {
 | 
			
		||||
                run: Arc::new(|a, _i| {
 | 
			
		||||
                    let a = a.get();
 | 
			
		||||
                    if let (Some(v), Some(i)) = (a.get(0), a.get(1)) {
 | 
			
		||||
                        if let Some(i) = i.get().as_any().downcast_ref::<data::int::Int>() {
 | 
			
		||||
                            if let Ok(i) = i.0.try_into() {
 | 
			
		||||
                        let (v, i2) = (v?, i?);
 | 
			
		||||
                        let o = if let Some(i3) = i2.get().as_any().downcast_ref::<data::int::Int>()
 | 
			
		||||
                        {
 | 
			
		||||
                            if let Ok(i) = i3.0.try_into() {
 | 
			
		||||
                                if let Some(v) = v.get().get(i) {
 | 
			
		||||
                                    Data::one_tuple(v)
 | 
			
		||||
                                    Ok(Data::one_tuple(v?))
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    Data::empty_tuple()
 | 
			
		||||
                                    Ok(Data::empty_tuple())
 | 
			
		||||
                                }
 | 
			
		||||
                            } else {
 | 
			
		||||
                                Data::empty_tuple()
 | 
			
		||||
                                Ok(Data::empty_tuple())
 | 
			
		||||
                            }
 | 
			
		||||
                        } else {
 | 
			
		||||
                            unreachable!("get called with non-int index")
 | 
			
		||||
                        }
 | 
			
		||||
                            Err("get called with non-int index".into())
 | 
			
		||||
                        };
 | 
			
		||||
                        o
 | 
			
		||||
                    } else {
 | 
			
		||||
                        unreachable!("get called with less than 2 args")
 | 
			
		||||
                        Err("get called with less than 2 args".into())
 | 
			
		||||
                    }
 | 
			
		||||
                }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
 | 
			
		||||
@ -29,10 +29,20 @@ impl Config {
 | 
			
		||||
    pub fn with_iters(self) -> Self {
 | 
			
		||||
        self
 | 
			
		||||
            .add_var("any".to_string(), Data::new(genfunc_iter_in_val_out("all".to_string(), data::bool::BoolT, Type::new(data::bool::BoolT), |a, _i| {
 | 
			
		||||
                Data::new(data::bool::Bool(a.get().iterable().unwrap().any(|v| v.get().as_any().downcast_ref::<data::bool::Bool>().is_some_and(|v| v.0))))
 | 
			
		||||
                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))) {
 | 
			
		||||
                    if v? {
 | 
			
		||||
                        return Ok(Data::new(data::bool::Bool(true)));
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                Ok(Data::new(data::bool::Bool(false)))
 | 
			
		||||
            })))
 | 
			
		||||
            .add_var("all".to_string(), Data::new(genfunc_iter_in_val_out("all".to_string(), data::bool::BoolT, Type::new(data::bool::BoolT), |a, _i| {
 | 
			
		||||
                Data::new(data::bool::Bool(a.get().iterable().unwrap().all(|v| v.get().as_any().downcast_ref::<data::bool::Bool>().is_some_and(|v| v.0))))
 | 
			
		||||
                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))) {
 | 
			
		||||
                    if !v? {
 | 
			
		||||
                        return Ok(Data::new(data::bool::Bool(false)));
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                Ok(Data::new(data::bool::Bool(true)))
 | 
			
		||||
            })))
 | 
			
		||||
            .add_var(
 | 
			
		||||
            "for_each".to_string(),
 | 
			
		||||
@ -83,9 +93,9 @@ impl Config {
 | 
			
		||||
                                f.get().as_any().downcast_ref::<data::function::Function>(),
 | 
			
		||||
                            ) {
 | 
			
		||||
                                for v in iter {
 | 
			
		||||
                                    f.run(v);
 | 
			
		||||
                                    f.run(v?)?;
 | 
			
		||||
                                }
 | 
			
		||||
                                Data::empty_tuple()
 | 
			
		||||
                                Ok(Data::empty_tuple())
 | 
			
		||||
                            } else {
 | 
			
		||||
                                unreachable!(
 | 
			
		||||
                                    "for_each called on tuple not containing iterable and function"
 | 
			
		||||
@ -133,7 +143,7 @@ impl Config {
 | 
			
		||||
                    };
 | 
			
		||||
                    Ok(Type::new(IterT::new(ItersT::Enumerate, data)?))
 | 
			
		||||
                }),
 | 
			
		||||
                run: Arc::new(|a, _i| Data::new(Iter(Iters::Enumerate, a.clone()))),
 | 
			
		||||
                run: Arc::new(|a, _i| Ok(Data::new(Iter(Iters::Enumerate, a.clone())))),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
            }),
 | 
			
		||||
        )
 | 
			
		||||
@ -150,7 +160,7 @@ impl Config {
 | 
			
		||||
                    };
 | 
			
		||||
                    Ok(Type::new(IterT::new(ItersT::Chained, data)?))
 | 
			
		||||
                }),
 | 
			
		||||
                run: Arc::new(|a, _i| Data::new(Iter(Iters::Chained, a.clone()))),
 | 
			
		||||
                run: Arc::new(|a, _i| Ok(Data::new(Iter(Iters::Chained, a.clone())))),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
            }),
 | 
			
		||||
        )
 | 
			
		||||
@ -211,7 +221,7 @@ fn genfunc_iter_and_arg<T: MersType, D: MersData>(
 | 
			
		||||
            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(f) = f.get().as_any().downcast_ref::<D>() {
 | 
			
		||||
                        Data::new(Iter(fd(f), v.clone()))
 | 
			
		||||
                        Ok(Data::new(Iter(fd(f), v.clone())))
 | 
			
		||||
                    } else {
 | 
			
		||||
                        unreachable!("{name} called on tuple not containing function")
 | 
			
		||||
                    }
 | 
			
		||||
@ -254,55 +264,76 @@ impl MersData for Iter {
 | 
			
		||||
    fn is_eq(&self, _other: &dyn MersData) -> bool {
 | 
			
		||||
        false
 | 
			
		||||
    }
 | 
			
		||||
    fn iterable(&self) -> Option<Box<dyn Iterator<Item = Data>>> {
 | 
			
		||||
    fn iterable(&self) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
 | 
			
		||||
        Some(match &self.0 {
 | 
			
		||||
            Iters::Map(f) => {
 | 
			
		||||
                let f = Clone::clone(f);
 | 
			
		||||
                Box::new(self.1.get().iterable()?.map(move |v| f.run(v)))
 | 
			
		||||
                Box::new(self.1.get().iterable()?.map(move |v| f.run(v?)))
 | 
			
		||||
            }
 | 
			
		||||
            Iters::Filter(f) => {
 | 
			
		||||
                let f = Clone::clone(f);
 | 
			
		||||
                Box::new(self.1.get().iterable()?.filter(move |v| {
 | 
			
		||||
                    f.run(v.clone())
 | 
			
		||||
                        .get()
 | 
			
		||||
                        .as_any()
 | 
			
		||||
                        .downcast_ref::<data::bool::Bool>()
 | 
			
		||||
                        .is_some_and(|b| b.0)
 | 
			
		||||
                Box::new(self.1.get().iterable()?.filter_map(move |v| {
 | 
			
		||||
                    match v {
 | 
			
		||||
                        Ok(v) => match f.run(v.clone()) {
 | 
			
		||||
                            Ok(f) => {
 | 
			
		||||
                                if f.get()
 | 
			
		||||
                                    .as_any()
 | 
			
		||||
                                    .downcast_ref::<data::bool::Bool>()
 | 
			
		||||
                                    .is_some_and(|b| b.0)
 | 
			
		||||
                                {
 | 
			
		||||
                                    Some(Ok(v))
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    None
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            Err(e) => Some(Err(e)),
 | 
			
		||||
                        },
 | 
			
		||||
                        Err(e) => Some(Err(e)),
 | 
			
		||||
                    }
 | 
			
		||||
                }))
 | 
			
		||||
            }
 | 
			
		||||
            Iters::FilterMap(f) => {
 | 
			
		||||
                let f = Clone::clone(f);
 | 
			
		||||
                Box::new(
 | 
			
		||||
                    self.1
 | 
			
		||||
                        .get()
 | 
			
		||||
                        .iterable()?
 | 
			
		||||
                        .filter_map(move |v| f.run(v).one_tuple_content()),
 | 
			
		||||
                )
 | 
			
		||||
                Box::new(self.1.get().iterable()?.filter_map(move |v| match v {
 | 
			
		||||
                    Ok(v) => match f.run(v) {
 | 
			
		||||
                        Ok(r) => Some(Ok(r.one_tuple_content()?)),
 | 
			
		||||
                        Err(e) => Some(Err(e)),
 | 
			
		||||
                    },
 | 
			
		||||
                    Err(e) => Some(Err(e)),
 | 
			
		||||
                }))
 | 
			
		||||
            }
 | 
			
		||||
            Iters::MapWhile(f) => {
 | 
			
		||||
                let f = Clone::clone(f);
 | 
			
		||||
                Box::new(
 | 
			
		||||
                    self.1
 | 
			
		||||
                        .get()
 | 
			
		||||
                        .iterable()?
 | 
			
		||||
                        .map_while(move |v| f.run(v).one_tuple_content()),
 | 
			
		||||
                )
 | 
			
		||||
                Box::new(self.1.get().iterable()?.map_while(move |v| match v {
 | 
			
		||||
                    Ok(v) => match f.run(v) {
 | 
			
		||||
                        Ok(r) => Some(Ok(r.one_tuple_content()?)),
 | 
			
		||||
                        Err(e) => Some(Err(e)),
 | 
			
		||||
                    },
 | 
			
		||||
                    Err(e) => Some(Err(e)),
 | 
			
		||||
                }))
 | 
			
		||||
            }
 | 
			
		||||
            Iters::Take(limit) => Box::new(self.1.get().iterable()?.take(*limit)),
 | 
			
		||||
            Iters::Enumerate => Box::new(self.1.get().iterable()?.enumerate().map(|(i, v)| {
 | 
			
		||||
                Data::new(data::tuple::Tuple(vec![
 | 
			
		||||
                    Data::new(data::int::Int(i as _)),
 | 
			
		||||
                    v,
 | 
			
		||||
                ]))
 | 
			
		||||
            })),
 | 
			
		||||
            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),
 | 
			
		||||
                }))
 | 
			
		||||
            }
 | 
			
		||||
            Iters::Chained => {
 | 
			
		||||
                let iters = self
 | 
			
		||||
                match self
 | 
			
		||||
                    .1
 | 
			
		||||
                    .get()
 | 
			
		||||
                    .iterable()?
 | 
			
		||||
                    .map(|v| v.get().iterable())
 | 
			
		||||
                    .collect::<Option<Vec<_>>>()?;
 | 
			
		||||
                Box::new(iters.into_iter().flatten())
 | 
			
		||||
                    .map(|v| Ok(v?.get().iterable()))
 | 
			
		||||
                    .collect::<Result<Option<Vec<_>>, CheckError>>()
 | 
			
		||||
                {
 | 
			
		||||
                    Ok(Some(iters)) => Box::new(iters.into_iter().flatten()),
 | 
			
		||||
                    Ok(None) => return None,
 | 
			
		||||
                    Err(e) => Box::new([Err(e)].into_iter()),
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
@ -433,7 +464,10 @@ fn genfunc_iter_in_val_out(
 | 
			
		||||
    name: String,
 | 
			
		||||
    iter_type: impl MersType + 'static,
 | 
			
		||||
    out_type: Type,
 | 
			
		||||
    run: impl Fn(Data, &mut crate::info::Info<program::run::Local>) -> Data + Send + Sync + 'static,
 | 
			
		||||
    run: impl Fn(Data, &mut crate::info::Info<program::run::Local>) -> Result<Data, CheckError>
 | 
			
		||||
        + Send
 | 
			
		||||
        + Sync
 | 
			
		||||
        + 'static,
 | 
			
		||||
) -> Function {
 | 
			
		||||
    Function {
 | 
			
		||||
        info: Arc::new(crate::info::Info::neverused()),
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,7 @@ use std::{
 | 
			
		||||
 | 
			
		||||
use crate::{
 | 
			
		||||
    data::{self, Data, MersData, MersType, Type},
 | 
			
		||||
    errors::CheckError,
 | 
			
		||||
    parsing::{statements::to_string_literal, Source},
 | 
			
		||||
    program::{self, run::CheckInfo},
 | 
			
		||||
};
 | 
			
		||||
@ -93,7 +94,7 @@ impl Config {
 | 
			
		||||
                            }
 | 
			
		||||
                            None => Data::empty_tuple(),
 | 
			
		||||
                        };
 | 
			
		||||
                        o
 | 
			
		||||
                        Ok(o)
 | 
			
		||||
                    }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
            }))
 | 
			
		||||
@ -123,7 +124,7 @@ impl Config {
 | 
			
		||||
                        }
 | 
			
		||||
                    }),
 | 
			
		||||
                    run: Arc::new(|a, _i| {
 | 
			
		||||
                        match a
 | 
			
		||||
                        Ok(match a
 | 
			
		||||
                            .get()
 | 
			
		||||
                            .as_any()
 | 
			
		||||
                            .downcast_ref::<data::reference::Reference>()
 | 
			
		||||
@ -140,7 +141,7 @@ impl Config {
 | 
			
		||||
                        {
 | 
			
		||||
                            Some(data) => Data::one_tuple(data.read().unwrap().clone()),
 | 
			
		||||
                            None => Data::empty_tuple(),
 | 
			
		||||
                        }
 | 
			
		||||
                        })
 | 
			
		||||
                    }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
                }),
 | 
			
		||||
@ -203,7 +204,7 @@ impl Config {
 | 
			
		||||
                            .unwrap()
 | 
			
		||||
                            .0
 | 
			
		||||
                            .push(Arc::new(RwLock::new(tuple.0[1].clone())));
 | 
			
		||||
                            Data::empty_tuple()
 | 
			
		||||
                            Ok(Data::empty_tuple())
 | 
			
		||||
                    }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
                }),
 | 
			
		||||
@ -224,9 +225,9 @@ impl Config {
 | 
			
		||||
                    }),
 | 
			
		||||
                    run: Arc::new(|a, _i| {
 | 
			
		||||
                        if let Some(i) = a.get().iterable() {
 | 
			
		||||
                            Data::new(List(i.map(|v| Arc::new(RwLock::new(v))).collect()))
 | 
			
		||||
                            Ok(Data::new(List(i.map(|v| Ok::<_, CheckError>(Arc::new(RwLock::new(v?)))).collect::<Result<_, _>>()?)))
 | 
			
		||||
                        } else {
 | 
			
		||||
                            unreachable!("as_list called on non-iterable")
 | 
			
		||||
                            Err("as_list called on non-iterable".into())
 | 
			
		||||
                        }
 | 
			
		||||
                    }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
@ -262,12 +263,12 @@ impl MersData for List {
 | 
			
		||||
            false
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    fn iterable(&self) -> Option<Box<dyn Iterator<Item = Data>>> {
 | 
			
		||||
    fn iterable(&self) -> Option<Box<dyn Iterator<Item = Result<Data, CheckError>>>> {
 | 
			
		||||
        Some(Box::new(
 | 
			
		||||
            self.0
 | 
			
		||||
                .clone()
 | 
			
		||||
                .into_iter()
 | 
			
		||||
                .map(|v| v.read().unwrap().clone()),
 | 
			
		||||
                .map(|v| Ok(v.read().unwrap().clone())),
 | 
			
		||||
        ))
 | 
			
		||||
    }
 | 
			
		||||
    fn clone(&self) -> Box<dyn MersData> {
 | 
			
		||||
 | 
			
		||||
@ -72,11 +72,11 @@ impl Config {
 | 
			
		||||
                }
 | 
			
		||||
            }),
 | 
			
		||||
            run: Arc::new(|a, _i| {
 | 
			
		||||
                if let Ok(n) = a.get().as_any().downcast_ref::<data::string::String>().unwrap().0.parse() {
 | 
			
		||||
                Ok(if let Ok(n) = a.get().as_any().downcast_ref::<data::string::String>().unwrap().0.parse() {
 | 
			
		||||
                    Data::one_tuple(Data::new(data::float::Float(n)))
 | 
			
		||||
                } else {
 | 
			
		||||
                    Data::empty_tuple()
 | 
			
		||||
                }
 | 
			
		||||
                })
 | 
			
		||||
            }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
        })).add_var("parse_int".to_string(), Data::new(data::function::Function {
 | 
			
		||||
@ -95,11 +95,11 @@ impl Config {
 | 
			
		||||
                }
 | 
			
		||||
            }),
 | 
			
		||||
            run: Arc::new(|a, _i| {
 | 
			
		||||
                if let Ok(n) = a.get().as_any().downcast_ref::<data::string::String>().unwrap().0.parse() {
 | 
			
		||||
                Ok(if let Ok(n) = a.get().as_any().downcast_ref::<data::string::String>().unwrap().0.parse() {
 | 
			
		||||
                    Data::one_tuple(Data::new(data::int::Int(n)))
 | 
			
		||||
                } else {
 | 
			
		||||
                    Data::empty_tuple()
 | 
			
		||||
                }
 | 
			
		||||
                })
 | 
			
		||||
            }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
        })).add_var("signum".to_string(), Data::new(data::function::Function {
 | 
			
		||||
@ -113,7 +113,7 @@ impl Config {
 | 
			
		||||
                }
 | 
			
		||||
            }),
 | 
			
		||||
            run: Arc::new(|a, _i| {
 | 
			
		||||
                Data::new(data::int::Int(if let Some(n) = a.get().as_any().downcast_ref::<data::int::Int>() {
 | 
			
		||||
                Ok(Data::new(data::int::Int(if let Some(n) = a.get().as_any().downcast_ref::<data::int::Int>() {
 | 
			
		||||
                    n.0.signum()
 | 
			
		||||
                } else
 | 
			
		||||
                if let Some(n) = a.get().as_any().downcast_ref::<data::float::Float>() {
 | 
			
		||||
@ -123,7 +123,7 @@ impl Config {
 | 
			
		||||
                        -1
 | 
			
		||||
                    } else { 0
 | 
			
		||||
                    }
 | 
			
		||||
                } else { unreachable!("called signum on non-number type")}))
 | 
			
		||||
                } else { unreachable!("called signum on non-number type")})))
 | 
			
		||||
            }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
        }))            .add_var("div".to_string(), Data::new(data::function::Function {
 | 
			
		||||
@ -137,10 +137,10 @@ impl Config {
 | 
			
		||||
                    match (left.downcast_ref::<data::int::Int>(), left.downcast_ref::<data::float::Float>(),
 | 
			
		||||
                        right.downcast_ref::<data::int::Int>(), right.downcast_ref::<data::float::Float>()
 | 
			
		||||
                    ) {
 | 
			
		||||
                        (Some(data::int::Int(l)), None, Some(data::int::Int(r)), None) => Data::new(data::int::Int(l / r)),
 | 
			
		||||
                        (Some(data::int::Int(l)), None, None, Some(data::float::Float(r))) => Data::new(data::float::Float(*l as f64 / r)),
 | 
			
		||||
                        (None, Some(data::float::Float(l)), Some(data::int::Int(r)), None) => Data::new(data::float::Float(l / *r as f64)),
 | 
			
		||||
                        (None, Some(data::float::Float(l)), None, Some(data::float::Float(r))) => Data::new(data::float::Float(l / r)),
 | 
			
		||||
                        (Some(data::int::Int(l)), None, Some(data::int::Int(r)), None) => Ok(Data::new(data::int::Int(l / r))),
 | 
			
		||||
                        (Some(data::int::Int(l)), None, None, Some(data::float::Float(r))) => Ok(Data::new(data::float::Float(*l as f64 / r))),
 | 
			
		||||
                        (None, Some(data::float::Float(l)), Some(data::int::Int(r)), None) => Ok(Data::new(data::float::Float(l / *r as f64))),
 | 
			
		||||
                        (None, Some(data::float::Float(l)), None, Some(data::float::Float(r))) => Ok(Data::new(data::float::Float(l / r))),
 | 
			
		||||
                        _ => unreachable!(),
 | 
			
		||||
                    }
 | 
			
		||||
                } else { unreachable!() }),
 | 
			
		||||
@ -156,10 +156,10 @@ impl Config {
 | 
			
		||||
                    match (left.downcast_ref::<data::int::Int>(), left.downcast_ref::<data::float::Float>(),
 | 
			
		||||
                        right.downcast_ref::<data::int::Int>(), right.downcast_ref::<data::float::Float>()
 | 
			
		||||
                    ) {
 | 
			
		||||
                        (Some(data::int::Int(l)), None, Some(data::int::Int(r)), None) => Data::new(data::int::Int(l % r)),
 | 
			
		||||
                        (Some(data::int::Int(l)), None, None, Some(data::float::Float(r))) => Data::new(data::float::Float(*l as f64 % r)),
 | 
			
		||||
                        (None, Some(data::float::Float(l)), Some(data::int::Int(r)), None) => Data::new(data::float::Float(l % *r as f64)),
 | 
			
		||||
                        (None, Some(data::float::Float(l)), None, Some(data::float::Float(r))) => Data::new(data::float::Float(l % r)),
 | 
			
		||||
                        (Some(data::int::Int(l)), None, Some(data::int::Int(r)), None) => Ok(Data::new(data::int::Int(l % r))),
 | 
			
		||||
                        (Some(data::int::Int(l)), None, None, Some(data::float::Float(r))) => Ok(Data::new(data::float::Float(*l as f64 % r))),
 | 
			
		||||
                        (None, Some(data::float::Float(l)), Some(data::int::Int(r)), None) => Ok(Data::new(data::float::Float(l % *r as f64))),
 | 
			
		||||
                        (None, Some(data::float::Float(l)), None, Some(data::float::Float(r))) => Ok(Data::new(data::float::Float(l % r))),
 | 
			
		||||
                        _ => unreachable!(),
 | 
			
		||||
                    }
 | 
			
		||||
                } else { unreachable!() }),
 | 
			
		||||
@ -206,20 +206,22 @@ impl Config {
 | 
			
		||||
                        let mut sumf = 0.0;
 | 
			
		||||
                        let mut usef = false;
 | 
			
		||||
                        for val in i {
 | 
			
		||||
                            if let Some(i) = val.get().as_any().downcast_ref::<data::int::Int>() {
 | 
			
		||||
                            let val = val?;
 | 
			
		||||
                            let o = if let Some(i) = val.get().as_any().downcast_ref::<data::int::Int>() {
 | 
			
		||||
                                sumi += i.0;
 | 
			
		||||
                            } else if let Some(i) =
 | 
			
		||||
                                val.get().as_any().downcast_ref::<data::float::Float>()
 | 
			
		||||
                            {
 | 
			
		||||
                                sumf += i.0;
 | 
			
		||||
                                usef = true;
 | 
			
		||||
                            }
 | 
			
		||||
                            };
 | 
			
		||||
                            o
 | 
			
		||||
                        }
 | 
			
		||||
                        if usef {
 | 
			
		||||
                        Ok(if usef {
 | 
			
		||||
                            Data::new(data::float::Float(sumi as f64 + sumf))
 | 
			
		||||
                        } else {
 | 
			
		||||
                            Data::new(data::int::Int(sumi))
 | 
			
		||||
                        }
 | 
			
		||||
                        })
 | 
			
		||||
                    } else {
 | 
			
		||||
                        unreachable!("sum called on non-tuple")
 | 
			
		||||
                    }
 | 
			
		||||
@ -269,6 +271,7 @@ impl Config {
 | 
			
		||||
                        let mut sumf = 0.0;
 | 
			
		||||
                        let mut usef = false;
 | 
			
		||||
                        for val in i {
 | 
			
		||||
                            let val = val?;
 | 
			
		||||
                            if let Some(i) = val.get().as_any().downcast_ref::<data::int::Int>() {
 | 
			
		||||
                                if first {
 | 
			
		||||
                                    sumi = i.0;
 | 
			
		||||
@ -289,11 +292,11 @@ impl Config {
 | 
			
		||||
                                first = false;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        if usef {
 | 
			
		||||
                        Ok(if usef {
 | 
			
		||||
                            Data::new(data::float::Float(sumi as f64 + sumf))
 | 
			
		||||
                        } else {
 | 
			
		||||
                            Data::new(data::int::Int(sumi))
 | 
			
		||||
                        }
 | 
			
		||||
                        })
 | 
			
		||||
                    } else {
 | 
			
		||||
                        unreachable!("sum called on non-tuple")
 | 
			
		||||
                    }
 | 
			
		||||
@ -342,20 +345,22 @@ impl Config {
 | 
			
		||||
                        let mut prodf = 1.0;
 | 
			
		||||
                        let mut usef = false;
 | 
			
		||||
                        for val in i {
 | 
			
		||||
                            if let Some(i) = val.get().as_any().downcast_ref::<data::int::Int>() {
 | 
			
		||||
                            let val = val?;
 | 
			
		||||
                            let o = if let Some(i) = val.get().as_any().downcast_ref::<data::int::Int>() {
 | 
			
		||||
                                prodi *= i.0;
 | 
			
		||||
                            } else if let Some(i) =
 | 
			
		||||
                                val.get().as_any().downcast_ref::<data::float::Float>()
 | 
			
		||||
                            {
 | 
			
		||||
                                prodf *= i.0;
 | 
			
		||||
                                usef = true;
 | 
			
		||||
                            }
 | 
			
		||||
                            };
 | 
			
		||||
                            o
 | 
			
		||||
                        }
 | 
			
		||||
                        if usef {
 | 
			
		||||
                        Ok(if usef {
 | 
			
		||||
                            Data::new(data::float::Float(prodi as f64 * prodf))
 | 
			
		||||
                        } else {
 | 
			
		||||
                            Data::new(data::int::Int(prodi))
 | 
			
		||||
                        }
 | 
			
		||||
                        })
 | 
			
		||||
                    } else {
 | 
			
		||||
                        unreachable!("product called on non-tuple")
 | 
			
		||||
                    }
 | 
			
		||||
@ -424,6 +429,7 @@ fn ltgtoe_function(
 | 
			
		||||
        run: Arc::new(move |a, _i| {
 | 
			
		||||
            let mut prev = IntOrFloatOrNothing::Nothing;
 | 
			
		||||
            for item in a.get().iterable().unwrap() {
 | 
			
		||||
                let item = item?;
 | 
			
		||||
                let item = item.get();
 | 
			
		||||
                let new = if let Some(data::int::Int(v)) = item.as_any().downcast_ref() {
 | 
			
		||||
                    IntOrFloatOrNothing::Int(*v)
 | 
			
		||||
@ -435,10 +441,10 @@ fn ltgtoe_function(
 | 
			
		||||
                if op(prev, new) {
 | 
			
		||||
                    prev = new;
 | 
			
		||||
                } else {
 | 
			
		||||
                    return Data::new(data::bool::Bool(false));
 | 
			
		||||
                    return Ok(Data::new(data::bool::Bool(false)));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            Data::new(data::bool::Bool(true))
 | 
			
		||||
            Ok(Data::new(data::bool::Bool(true)))
 | 
			
		||||
        }),
 | 
			
		||||
        inner_statements: None,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -53,9 +53,9 @@ impl Config {
 | 
			
		||||
                        .downcast_ref::<data::function::Function>()
 | 
			
		||||
                        .cloned()
 | 
			
		||||
                    {
 | 
			
		||||
                        Data::new(Thread(Arc::new(Mutex::new(Ok(std::thread::spawn(
 | 
			
		||||
                        Ok(Data::new(Thread(Arc::new(Mutex::new(Ok(std::thread::spawn(
 | 
			
		||||
                            move || f.run(Data::empty_tuple()),
 | 
			
		||||
                        ))))))
 | 
			
		||||
                        )))))))
 | 
			
		||||
                    } else {
 | 
			
		||||
                        unreachable!("thread called, but arg wasn't a function");
 | 
			
		||||
                    }
 | 
			
		||||
@ -77,10 +77,10 @@ impl Config {
 | 
			
		||||
                run: Arc::new(|a, _i| {
 | 
			
		||||
                    let a = a.get();
 | 
			
		||||
                    let t = a.as_any().downcast_ref::<Thread>().unwrap().0.lock().unwrap();
 | 
			
		||||
                    Data::new(data::bool::Bool(match &*t {
 | 
			
		||||
                    Ok(Data::new(data::bool::Bool(match &*t {
 | 
			
		||||
                        Ok(t) => t.is_finished(),
 | 
			
		||||
                        Err(_d) => true,
 | 
			
		||||
                    }))
 | 
			
		||||
                    })))
 | 
			
		||||
                }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
            }))
 | 
			
		||||
@ -101,7 +101,7 @@ impl Config {
 | 
			
		||||
                run: Arc::new(|a, _i| {
 | 
			
		||||
                    let a = a.get();
 | 
			
		||||
                    let mut t = a.as_any().downcast_ref::<Thread>().unwrap().0.lock().unwrap();
 | 
			
		||||
                    let d = match std::mem::replace(&mut *t, Err(Data::empty_tuple())) {
 | 
			
		||||
                    let d = match std::mem::replace(&mut *t, Err(Err(CheckError::new()))) {
 | 
			
		||||
                        Ok(t) => t.join().unwrap(),
 | 
			
		||||
                        Err(d) => d,
 | 
			
		||||
                    };
 | 
			
		||||
@ -114,7 +114,9 @@ impl Config {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Clone)]
 | 
			
		||||
pub struct Thread(pub Arc<Mutex<Result<JoinHandle<Data>, Data>>>);
 | 
			
		||||
pub struct Thread(
 | 
			
		||||
    pub Arc<Mutex<Result<JoinHandle<Result<Data, CheckError>>, Result<Data, CheckError>>>>,
 | 
			
		||||
);
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
pub struct ThreadT(pub Type);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -41,11 +41,11 @@ impl Config {
 | 
			
		||||
                    }
 | 
			
		||||
                }),
 | 
			
		||||
                run: Arc::new(|_a, _i| {
 | 
			
		||||
                    if let Some(Ok(line)) = std::io::stdin().lines().next() {
 | 
			
		||||
                    Ok(if let Some(Ok(line)) = std::io::stdin().lines().next() {
 | 
			
		||||
                        Data::one_tuple(Data::new(data::string::String(line)))
 | 
			
		||||
                    } else {
 | 
			
		||||
                        Data::empty_tuple()
 | 
			
		||||
                    }
 | 
			
		||||
                    })
 | 
			
		||||
                }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
            }),
 | 
			
		||||
@ -60,7 +60,7 @@ impl Config {
 | 
			
		||||
                    let a2 = a.get();
 | 
			
		||||
                    eprintln!("{} :: {}", a2.as_type(), a2);
 | 
			
		||||
                    drop(a2);
 | 
			
		||||
                    a
 | 
			
		||||
                    Ok(a)
 | 
			
		||||
                }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
            }),
 | 
			
		||||
@ -74,7 +74,7 @@ impl Config {
 | 
			
		||||
                run: Arc::new(|a, _i| {
 | 
			
		||||
                    eprint!("{}", a.get());
 | 
			
		||||
                    _ = std::io::stderr().lock().flush();
 | 
			
		||||
                    Data::empty_tuple()
 | 
			
		||||
                    Ok(Data::empty_tuple())
 | 
			
		||||
                }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
            }),
 | 
			
		||||
@ -87,7 +87,7 @@ impl Config {
 | 
			
		||||
                out: Arc::new(|_a, _i| Ok(Type::empty_tuple())),
 | 
			
		||||
                run: Arc::new(|a, _i| {
 | 
			
		||||
                    eprintln!("{}", a.get());
 | 
			
		||||
                    Data::empty_tuple()
 | 
			
		||||
                    Ok(Data::empty_tuple())
 | 
			
		||||
                }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
            }),
 | 
			
		||||
@ -101,7 +101,7 @@ impl Config {
 | 
			
		||||
                run: Arc::new(|a, _i| {
 | 
			
		||||
                    print!("{}", a.get());
 | 
			
		||||
                    _ = std::io::stdout().lock().flush();
 | 
			
		||||
                    Data::empty_tuple()
 | 
			
		||||
                    Ok(Data::empty_tuple())
 | 
			
		||||
                }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
            }),
 | 
			
		||||
@ -114,7 +114,7 @@ impl Config {
 | 
			
		||||
                out: Arc::new(|_a, _i| Ok(Type::empty_tuple())),
 | 
			
		||||
                run: Arc::new(|a, _i| {
 | 
			
		||||
                    println!("{}", a.get());
 | 
			
		||||
                    Data::empty_tuple()
 | 
			
		||||
                    Ok(Data::empty_tuple())
 | 
			
		||||
                }),
 | 
			
		||||
                inner_statements: None,
 | 
			
		||||
            }),
 | 
			
		||||
 | 
			
		||||
@ -25,17 +25,17 @@ impl Config {
 | 
			
		||||
            .add_var("ends_with".to_string(), Data::new(util::to_mers_func_concrete_string_string_to_bool(|v, p| v.ends_with(p))))
 | 
			
		||||
            .add_var("str_split_once".to_string(), Data::new(util::to_mers_func_concrete_string_string_to_opt_string_string(|v, p| v.split_once(p).map(|(a, b)| (a.to_owned(), b.to_owned())))))
 | 
			
		||||
            .add_var("str_split_once_rev".to_string(), Data::new(util::to_mers_func_concrete_string_string_to_opt_string_string(|v, p| v.rsplit_once(p).map(|(a, b)| (a.to_owned(), b.to_owned())))))
 | 
			
		||||
            .add_var("str_split".to_string(), Data::new(util::to_mers_func_concrete_string_string_to_any(Type::new(super::with_list::ListT(Type::new(data::string::StringT))), |v, p| Data::new(super::with_list::List(v.split(p).map(|v| Arc::new(RwLock::new(Data::new(data::string::String(v.to_owned()))))).collect())))))
 | 
			
		||||
            .add_var("str_split".to_string(), Data::new(util::to_mers_func_concrete_string_string_to_any(Type::new(super::with_list::ListT(Type::new(data::string::StringT))), |v, p| Ok(Data::new(super::with_list::List(v.split(p).map(|v| Arc::new(RwLock::new(Data::new(data::string::String(v.to_owned()))))).collect()))))))
 | 
			
		||||
            .add_var("concat".to_string(), Data::new(util::to_mers_func(
 | 
			
		||||
                |a| if a.iterable().is_some() {
 | 
			
		||||
                    Ok(Type::new(data::string::StringT))
 | 
			
		||||
                } else {
 | 
			
		||||
                    Err(format!("concat called on non-iterable type {a}").into())
 | 
			
		||||
                },
 | 
			
		||||
                |a| Data::new(data::string::String(a.get().iterable().unwrap().map(|v| v.get().to_string()).collect()))),
 | 
			
		||||
                |a| Ok(Data::new(data::string::String(a.get().iterable().unwrap().map(|v| v.map(|v| v.get().to_string())).collect::<Result<_, _>>()?)))),
 | 
			
		||||
            ))
 | 
			
		||||
            .add_var("to_string".to_string(), Data::new(util::to_mers_func(|_a| Ok(Type::new(data::string::StringT)),
 | 
			
		||||
                |a| Data::new(data::string::String(a.get().to_string()))
 | 
			
		||||
                |a| Ok(Data::new(data::string::String(a.get().to_string())))
 | 
			
		||||
            )))
 | 
			
		||||
            .add_var("substring".to_string(), Data::new(util::to_mers_func(
 | 
			
		||||
                |a| {
 | 
			
		||||
@ -79,9 +79,9 @@ impl Config {
 | 
			
		||||
                        .unwrap_or(usize::MAX);
 | 
			
		||||
                    let end = end.min(s.len());
 | 
			
		||||
                    if end < start {
 | 
			
		||||
                        return Data::new(data::string::String(String::new()));
 | 
			
		||||
                        return Ok(Data::new(data::string::String(String::new())));
 | 
			
		||||
                    }
 | 
			
		||||
                    Data::new(data::string::String(s[start..end].to_owned()))
 | 
			
		||||
                    Ok(Data::new(data::string::String(s[start..end].to_owned())))
 | 
			
		||||
                })
 | 
			
		||||
            ))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ impl MersStatement for Function {
 | 
			
		||||
                    Ok(run2.check(i, None)?)
 | 
			
		||||
                }),
 | 
			
		||||
                run: Arc::new(move |arg, info| {
 | 
			
		||||
                    data::defs::assign(&arg, &arg_target.run(info));
 | 
			
		||||
                    data::defs::assign(&arg, &arg_target.run(info)?);
 | 
			
		||||
                    run.run(info)
 | 
			
		||||
                }),
 | 
			
		||||
                inner_statements: Some((arg3, run3)),
 | 
			
		||||
 | 
			
		||||
@ -66,7 +66,7 @@ impl MersStatement for AsType {
 | 
			
		||||
            return_type
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
    fn run_custom(&self, info: &mut super::Info) -> Data {
 | 
			
		||||
    fn run_custom(&self, info: &mut super::Info) -> Result<Data, CheckError> {
 | 
			
		||||
        self.statement.run(info)
 | 
			
		||||
    }
 | 
			
		||||
    fn has_scope(&self) -> bool {
 | 
			
		||||
 | 
			
		||||
@ -77,11 +77,11 @@ impl MersStatement for AssignTo {
 | 
			
		||||
        }
 | 
			
		||||
        Ok(Type::empty_tuple())
 | 
			
		||||
    }
 | 
			
		||||
    fn run_custom(&self, info: &mut super::Info) -> crate::data::Data {
 | 
			
		||||
        let source = self.source.run(info);
 | 
			
		||||
        let target = self.target.run(info);
 | 
			
		||||
    fn run_custom(&self, info: &mut super::Info) -> Result<Data, CheckError> {
 | 
			
		||||
        let source = self.source.run(info)?;
 | 
			
		||||
        let target = self.target.run(info)?;
 | 
			
		||||
        data::defs::assign(&source, &target);
 | 
			
		||||
        Data::empty_tuple()
 | 
			
		||||
        Ok(Data::empty_tuple())
 | 
			
		||||
    }
 | 
			
		||||
    fn has_scope(&self) -> bool {
 | 
			
		||||
        false
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
use crate::{
 | 
			
		||||
    data::Type,
 | 
			
		||||
    data::{self, Data, Type},
 | 
			
		||||
    errors::{CheckError, SourceRange},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -25,12 +25,12 @@ impl MersStatement for Block {
 | 
			
		||||
        }
 | 
			
		||||
        Ok(o)
 | 
			
		||||
    }
 | 
			
		||||
    fn run_custom(&self, info: &mut super::Info) -> crate::data::Data {
 | 
			
		||||
    fn run_custom(&self, info: &mut super::Info) -> Result<Data, CheckError> {
 | 
			
		||||
        self.statements
 | 
			
		||||
            .iter()
 | 
			
		||||
            .map(|s| s.run(info))
 | 
			
		||||
            .last()
 | 
			
		||||
            .unwrap_or_else(|| crate::data::Data::new(crate::data::tuple::Tuple(vec![])))
 | 
			
		||||
            .unwrap_or_else(|| Ok(Data::new(data::tuple::Tuple(vec![]))))
 | 
			
		||||
    }
 | 
			
		||||
    fn has_scope(&self) -> bool {
 | 
			
		||||
        true
 | 
			
		||||
 | 
			
		||||
@ -88,12 +88,42 @@ impl MersStatement for Chain {
 | 
			
		||||
        }
 | 
			
		||||
        Ok(o)
 | 
			
		||||
    }
 | 
			
		||||
    fn run_custom(&self, info: &mut super::Info) -> Data {
 | 
			
		||||
        let f = self.first.run(info);
 | 
			
		||||
        let c = self.chained.run(info);
 | 
			
		||||
    fn run_custom(&self, info: &mut super::Info) -> Result<Data, CheckError> {
 | 
			
		||||
        let f = self.first.run(info)?;
 | 
			
		||||
        let c = self.chained.run(info)?;
 | 
			
		||||
        let c = c.get();
 | 
			
		||||
        if let Some(func) = c.as_any().downcast_ref::<crate::data::function::Function>() {
 | 
			
		||||
            func.run(f)
 | 
			
		||||
            match func.run(f) {
 | 
			
		||||
                Ok(v) => Ok(v),
 | 
			
		||||
                Err(e) => Err(if let Some(_) = &self.as_part_of_include {
 | 
			
		||||
                    CheckError::new()
 | 
			
		||||
                        .src(vec![(
 | 
			
		||||
                            self.pos_in_src.clone(),
 | 
			
		||||
                            Some(error_colors::HashIncludeErrorInIncludedFile),
 | 
			
		||||
                        )])
 | 
			
		||||
                        .msg(
 | 
			
		||||
                            "Error in #include:"
 | 
			
		||||
                                .color(error_colors::HashIncludeErrorInIncludedFile)
 | 
			
		||||
                                .to_string(),
 | 
			
		||||
                        )
 | 
			
		||||
                        .err_with_diff_src(e)
 | 
			
		||||
                } else {
 | 
			
		||||
                    CheckError::new()
 | 
			
		||||
                        .src(vec![
 | 
			
		||||
                            (self.pos_in_src.clone(), None),
 | 
			
		||||
                            (
 | 
			
		||||
                                self.first.source_range(),
 | 
			
		||||
                                Some(error_colors::FunctionArgument),
 | 
			
		||||
                            ),
 | 
			
		||||
                            (self.chained.source_range(), Some(error_colors::Function)),
 | 
			
		||||
                        ])
 | 
			
		||||
                        .msg(format!(
 | 
			
		||||
                            "Error in {}:",
 | 
			
		||||
                            "this function".color(error_colors::Function)
 | 
			
		||||
                        ))
 | 
			
		||||
                        .err(e)
 | 
			
		||||
                }),
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            todo!("err: not a function");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -56,8 +56,8 @@ impl MersStatement for CustomType {
 | 
			
		||||
        }
 | 
			
		||||
        Ok(Type::empty_tuple())
 | 
			
		||||
    }
 | 
			
		||||
    fn run_custom(&self, _info: &mut Info) -> Data {
 | 
			
		||||
        Data::empty_tuple()
 | 
			
		||||
    fn run_custom(&self, _info: &mut Info) -> Result<Data, CheckError> {
 | 
			
		||||
        Ok(Data::empty_tuple())
 | 
			
		||||
    }
 | 
			
		||||
    fn has_scope(&self) -> bool {
 | 
			
		||||
        false
 | 
			
		||||
 | 
			
		||||
@ -25,8 +25,10 @@ impl MersStatement for Function {
 | 
			
		||||
        self.func_no_info.with_info_check(info.clone());
 | 
			
		||||
        Ok(self.func_no_info.as_type())
 | 
			
		||||
    }
 | 
			
		||||
    fn run_custom(&self, info: &mut super::Info) -> Data {
 | 
			
		||||
        Data::new(self.func_no_info.with_info_run(Arc::new(info.clone())))
 | 
			
		||||
    fn run_custom(&self, info: &mut super::Info) -> Result<Data, CheckError> {
 | 
			
		||||
        Ok(Data::new(
 | 
			
		||||
            self.func_no_info.with_info_run(Arc::new(info.clone())),
 | 
			
		||||
        ))
 | 
			
		||||
    }
 | 
			
		||||
    fn has_scope(&self) -> bool {
 | 
			
		||||
        true
 | 
			
		||||
 | 
			
		||||
@ -52,20 +52,22 @@ impl MersStatement for If {
 | 
			
		||||
        }
 | 
			
		||||
        Ok(t)
 | 
			
		||||
    }
 | 
			
		||||
    fn run_custom(&self, info: &mut super::Info) -> crate::data::Data {
 | 
			
		||||
        if let Some(data::bool::Bool(true)) = self
 | 
			
		||||
            .condition
 | 
			
		||||
            .run(info)
 | 
			
		||||
            .get()
 | 
			
		||||
            .as_any()
 | 
			
		||||
            .downcast_ref::<data::bool::Bool>()
 | 
			
		||||
        {
 | 
			
		||||
            self.on_true.run(info)
 | 
			
		||||
        } else if let Some(on_false) = &self.on_false {
 | 
			
		||||
            on_false.run(info)
 | 
			
		||||
        } else {
 | 
			
		||||
            Data::empty_tuple()
 | 
			
		||||
        }
 | 
			
		||||
    fn run_custom(&self, info: &mut super::Info) -> Result<Data, CheckError> {
 | 
			
		||||
        Ok(
 | 
			
		||||
            if let Some(data::bool::Bool(true)) = self
 | 
			
		||||
                .condition
 | 
			
		||||
                .run(info)?
 | 
			
		||||
                .get()
 | 
			
		||||
                .as_any()
 | 
			
		||||
                .downcast_ref::<data::bool::Bool>()
 | 
			
		||||
            {
 | 
			
		||||
                self.on_true.run(info)?
 | 
			
		||||
            } else if let Some(on_false) = &self.on_false {
 | 
			
		||||
                on_false.run(info)?
 | 
			
		||||
            } else {
 | 
			
		||||
                Data::empty_tuple()
 | 
			
		||||
            },
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
    fn has_scope(&self) -> bool {
 | 
			
		||||
        true
 | 
			
		||||
 | 
			
		||||
@ -47,10 +47,10 @@ impl MersStatement for Loop {
 | 
			
		||||
        }
 | 
			
		||||
        Ok(t)
 | 
			
		||||
    }
 | 
			
		||||
    fn run_custom(&self, info: &mut Info) -> Data {
 | 
			
		||||
    fn run_custom(&self, info: &mut Info) -> Result<Data, CheckError> {
 | 
			
		||||
        loop {
 | 
			
		||||
            if let Some(v) = self.inner.run(info).one_tuple_content() {
 | 
			
		||||
                return v;
 | 
			
		||||
            if let Some(v) = self.inner.run(info)?.one_tuple_content() {
 | 
			
		||||
                return Ok(v);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ pub trait MersStatement: Debug + Send + Sync {
 | 
			
		||||
        info: &mut CheckInfo,
 | 
			
		||||
        init_to: Option<&Type>,
 | 
			
		||||
    ) -> Result<Type, CheckError>;
 | 
			
		||||
    fn run_custom(&self, info: &mut Info) -> Data;
 | 
			
		||||
    fn run_custom(&self, info: &mut Info) -> Result<Data, CheckError>;
 | 
			
		||||
    /// if true, local variables etc. will be contained inside their own scope.
 | 
			
		||||
    fn has_scope(&self) -> bool;
 | 
			
		||||
    fn check(&self, info: &mut CheckInfo, init_to: Option<&Type>) -> Result<Type, CheckError> {
 | 
			
		||||
@ -93,7 +93,7 @@ pub trait MersStatement: Debug + Send + Sync {
 | 
			
		||||
        info.global.depth -= 1;
 | 
			
		||||
        o
 | 
			
		||||
    }
 | 
			
		||||
    fn run(&self, info: &mut Info) -> Data {
 | 
			
		||||
    fn run(&self, info: &mut Info) -> Result<Data, CheckError> {
 | 
			
		||||
        if self.has_scope() {
 | 
			
		||||
            info.create_scope();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -119,13 +119,13 @@ impl MersStatement for Object {
 | 
			
		||||
                .collect::<Result<_, _>>()?,
 | 
			
		||||
        )))
 | 
			
		||||
    }
 | 
			
		||||
    fn run_custom(&self, info: &mut super::Info) -> crate::data::Data {
 | 
			
		||||
        Data::new(data::object::Object(
 | 
			
		||||
    fn run_custom(&self, info: &mut super::Info) -> Result<Data, CheckError> {
 | 
			
		||||
        Ok(Data::new(data::object::Object(
 | 
			
		||||
            self.elems
 | 
			
		||||
                .iter()
 | 
			
		||||
                .map(|(n, s)| (n.clone(), s.run(info)))
 | 
			
		||||
                .collect(),
 | 
			
		||||
        ))
 | 
			
		||||
                .map(|(n, s)| Ok::<_, CheckError>((n.clone(), s.run(info)?)))
 | 
			
		||||
                .collect::<Result<_, _>>()?,
 | 
			
		||||
        )))
 | 
			
		||||
    }
 | 
			
		||||
    fn has_scope(&self) -> bool {
 | 
			
		||||
        false
 | 
			
		||||
 | 
			
		||||
@ -103,8 +103,8 @@ impl MersStatement for Try {
 | 
			
		||||
        }
 | 
			
		||||
        Ok(t)
 | 
			
		||||
    }
 | 
			
		||||
    fn run_custom(&self, info: &mut Info) -> Data {
 | 
			
		||||
        let arg = self.arg.run(info);
 | 
			
		||||
    fn run_custom(&self, info: &mut Info) -> Result<Data, CheckError> {
 | 
			
		||||
        let arg = self.arg.run(info)?;
 | 
			
		||||
        let ar = arg.get();
 | 
			
		||||
        let a = ar.as_ref();
 | 
			
		||||
        let arg_type = a.as_type();
 | 
			
		||||
@ -112,14 +112,16 @@ impl MersStatement for Try {
 | 
			
		||||
            .funcs
 | 
			
		||||
            .iter()
 | 
			
		||||
            .map(|v| {
 | 
			
		||||
                v.run(info)
 | 
			
		||||
                    .get()
 | 
			
		||||
                    .as_any()
 | 
			
		||||
                    .downcast_ref::<data::function::Function>()
 | 
			
		||||
                    .unwrap()
 | 
			
		||||
                    .clone()
 | 
			
		||||
                Ok::<_, CheckError>(
 | 
			
		||||
                    v.run(info)?
 | 
			
		||||
                        .get()
 | 
			
		||||
                        .as_any()
 | 
			
		||||
                        .downcast_ref::<data::function::Function>()
 | 
			
		||||
                        .unwrap()
 | 
			
		||||
                        .clone(),
 | 
			
		||||
                )
 | 
			
		||||
            })
 | 
			
		||||
            .collect::<Vec<_>>();
 | 
			
		||||
            .collect::<Result<Vec<_>, _>>()?;
 | 
			
		||||
        let mut found = None;
 | 
			
		||||
        for (i, func) in functions.iter().enumerate() {
 | 
			
		||||
            match func.get_as_type().o(&arg_type) {
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@ use colored::Colorize;
 | 
			
		||||
 | 
			
		||||
use crate::{
 | 
			
		||||
    data::{self, tuple::TupleT, Data, Type},
 | 
			
		||||
    errors::{error_colors, SourceRange},
 | 
			
		||||
    errors::{error_colors, CheckError, SourceRange},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use super::MersStatement;
 | 
			
		||||
@ -82,10 +82,13 @@ impl MersStatement for Tuple {
 | 
			
		||||
                .collect::<Result<_, _>>()?,
 | 
			
		||||
        )))
 | 
			
		||||
    }
 | 
			
		||||
    fn run_custom(&self, info: &mut super::Info) -> crate::data::Data {
 | 
			
		||||
        Data::new(data::tuple::Tuple(
 | 
			
		||||
            self.elems.iter().map(|s| s.run(info)).collect(),
 | 
			
		||||
        ))
 | 
			
		||||
    fn run_custom(&self, info: &mut super::Info) -> Result<Data, CheckError> {
 | 
			
		||||
        Ok(Data::new(data::tuple::Tuple(
 | 
			
		||||
            self.elems
 | 
			
		||||
                .iter()
 | 
			
		||||
                .map(|s| Ok(s.run(info)?))
 | 
			
		||||
                .collect::<Result<_, CheckError>>()?,
 | 
			
		||||
        )))
 | 
			
		||||
    }
 | 
			
		||||
    fn has_scope(&self) -> bool {
 | 
			
		||||
        false
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
use crate::{
 | 
			
		||||
    data::{Data, Type},
 | 
			
		||||
    errors::SourceRange,
 | 
			
		||||
    errors::{CheckError, SourceRange},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use super::{CheckInfo, MersStatement};
 | 
			
		||||
@ -25,8 +25,8 @@ impl MersStatement for Value {
 | 
			
		||||
        }
 | 
			
		||||
        Ok(self.val.get().as_type())
 | 
			
		||||
    }
 | 
			
		||||
    fn run_custom(&self, _info: &mut super::Info) -> Data {
 | 
			
		||||
        self.val.clone()
 | 
			
		||||
    fn run_custom(&self, _info: &mut super::Info) -> Result<Data, CheckError> {
 | 
			
		||||
        Ok(self.val.clone())
 | 
			
		||||
    }
 | 
			
		||||
    fn source_range(&self) -> SourceRange {
 | 
			
		||||
        self.pos_in_src.clone()
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@ use std::sync::{Arc, RwLock};
 | 
			
		||||
 | 
			
		||||
use crate::{
 | 
			
		||||
    data::{self, Data, Type},
 | 
			
		||||
    errors::SourceRange,
 | 
			
		||||
    errors::{CheckError, SourceRange},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use super::MersStatement;
 | 
			
		||||
@ -50,7 +50,7 @@ impl MersStatement for Variable {
 | 
			
		||||
        };
 | 
			
		||||
        Ok(val)
 | 
			
		||||
    }
 | 
			
		||||
    fn run_custom(&self, info: &mut super::Info) -> Data {
 | 
			
		||||
    fn run_custom(&self, info: &mut super::Info) -> Result<Data, CheckError> {
 | 
			
		||||
        if self.is_init {
 | 
			
		||||
            if self.is_ref_not_ignore {
 | 
			
		||||
                let nothing = Arc::new(RwLock::new(Data::new(data::bool::Bool(false))));
 | 
			
		||||
@ -60,12 +60,12 @@ impl MersStatement for Variable {
 | 
			
		||||
                info.scopes[self.var.0].vars[self.var.1] = nothing;
 | 
			
		||||
            } else {
 | 
			
		||||
                // (reference to) data which will never be referenced again
 | 
			
		||||
                return Data::new(data::reference::Reference(Arc::new(RwLock::new(
 | 
			
		||||
                    Data::empty_tuple(),
 | 
			
		||||
                return Ok(Data::new(data::reference::Reference(Arc::new(
 | 
			
		||||
                    RwLock::new(Data::empty_tuple()),
 | 
			
		||||
                ))));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if self.is_ref_not_ignore {
 | 
			
		||||
        Ok(if self.is_ref_not_ignore {
 | 
			
		||||
            let v = &info.scopes[self.var.0].vars[self.var.1];
 | 
			
		||||
            Data::new(data::reference::Reference(Arc::clone(v)))
 | 
			
		||||
        } else {
 | 
			
		||||
@ -73,7 +73,7 @@ impl MersStatement for Variable {
 | 
			
		||||
                .write()
 | 
			
		||||
                .unwrap()
 | 
			
		||||
                .clone()
 | 
			
		||||
        }
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
    fn source_range(&self) -> SourceRange {
 | 
			
		||||
        self.pos_in_src.clone()
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user