mirror of
				https://github.com/Dummi26/mers.git
				synced 2025-11-04 05:16:17 +01:00 
			
		
		
		
	remove diff, add subtract to replace it and work with iters, add lt, gt, ltoe, gtoe for < > <= >=
This commit is contained in:
		
							parent
							
								
									79660c1976
								
							
						
					
					
						commit
						db59a1e92e
					
				
							
								
								
									
										0
									
								
								examples/00_Hello_World.mers
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								examples/00_Hello_World.mers
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								examples/01_Hello_Name.mers
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								examples/01_Hello_Name.mers
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								examples/02_Calc_Sum.mers
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								examples/02_Calc_Sum.mers
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								examples/03_Basic_Calculator.mers
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								examples/03_Basic_Calculator.mers
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								examples/04_Greatest_Common_Divisor.mers
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								examples/04_Greatest_Common_Divisor.mers
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								examples/05_Matrix_Multiplicator.mers
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								examples/05_Matrix_Multiplicator.mers
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								examples/fib.mers
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								examples/fib.mers
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								examples/iter.mers
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								examples/iter.mers
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								examples/try.mers
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								examples/try.mers
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@ -329,6 +329,9 @@ impl MersType for Type {
 | 
			
		||||
    fn is_included_in_single(&self, target: &dyn MersType) -> bool {
 | 
			
		||||
        self.types.iter().all(|t| t.is_included_in_single(target))
 | 
			
		||||
    }
 | 
			
		||||
    fn is_included_in(&self, target: &dyn MersType) -> bool {
 | 
			
		||||
        self.types.iter().all(|t| t.is_included_in(target))
 | 
			
		||||
    }
 | 
			
		||||
    fn subtypes(&self, acc: &mut Type) {
 | 
			
		||||
        for t in &self.types {
 | 
			
		||||
            t.subtypes(acc);
 | 
			
		||||
 | 
			
		||||
@ -12,11 +12,15 @@ use super::Config;
 | 
			
		||||
 | 
			
		||||
impl Config {
 | 
			
		||||
    /// `sum: fn` returns the sum of all the numbers in the tuple
 | 
			
		||||
    /// `diff: fn` returns b - a
 | 
			
		||||
    /// `minus: fn` returns the first number minus all the others
 | 
			
		||||
    /// `product: fn` returns the product of all the numbers in the tuple
 | 
			
		||||
    /// `div: fn` returns a / b. Performs integer division if a and b are both integers.
 | 
			
		||||
    /// `modulo: fn` returns a % b
 | 
			
		||||
    /// `signum: fn` returns 1 for positive numbers, -1 for negative ones and 0 for 0 (always returns an Int, even when input is Float)
 | 
			
		||||
    /// `lt: fn` returns true if the input keeps increasing, that is, for (a, b), a < b, for (a, b, c), a < b < c, and so on.
 | 
			
		||||
    /// `gt: fn` returns true if the input keeps decreasing, that is, for (a, b), a > b, for (a, b, c), a > b > c, and so on.
 | 
			
		||||
    /// `ltoe: fn` returns true if the input only increases, that is, for (a, b), a <= b, for (a, b, c), a <= b <= c, and so on.
 | 
			
		||||
    /// `gtoe: fn` returns true if the input only decreases, that is, for (a, b), a >= b, for (a, b, c), a >= b >= c, and so on.
 | 
			
		||||
    /// `parse_int: fn` parses a string to an int, returns () on failure
 | 
			
		||||
    /// `parse_float: fn` parses a string to an int, returns () on failure
 | 
			
		||||
    /// TODO!
 | 
			
		||||
@ -25,7 +29,36 @@ impl Config {
 | 
			
		||||
    /// `ceil: fn` rounds the float [?] and returns an int
 | 
			
		||||
    /// `floor: fn` rounds the float [?] and returns an int
 | 
			
		||||
    pub fn with_math(self) -> Self {
 | 
			
		||||
        self.add_var("parse_float".to_string(), Data::new(data::function::Function {
 | 
			
		||||
        self
 | 
			
		||||
            .add_var("lt".to_string(), Data::new(ltgtoe_function("lt".to_string(), |l, r| match (l, r) {
 | 
			
		||||
                (IntOrFloatOrNothing::Nothing, _) | (_, IntOrFloatOrNothing::Nothing) => true,
 | 
			
		||||
                (IntOrFloatOrNothing::Int(l), IntOrFloatOrNothing::Int(r)) => l < r,
 | 
			
		||||
                (IntOrFloatOrNothing::Int(l), IntOrFloatOrNothing::Float(r)) => (l as f64) < r,
 | 
			
		||||
                (IntOrFloatOrNothing::Float(l), IntOrFloatOrNothing::Int(r)) => l < r as f64,
 | 
			
		||||
                (IntOrFloatOrNothing::Float(l), IntOrFloatOrNothing::Float(r)) => l < r,
 | 
			
		||||
            })))
 | 
			
		||||
            .add_var("gt".to_string(), Data::new(ltgtoe_function("gt".to_string(), |l, r| match (l, r) {
 | 
			
		||||
                (IntOrFloatOrNothing::Nothing, _) | (_, IntOrFloatOrNothing::Nothing) => true,
 | 
			
		||||
                (IntOrFloatOrNothing::Int(l), IntOrFloatOrNothing::Int(r)) => l > r,
 | 
			
		||||
                (IntOrFloatOrNothing::Int(l), IntOrFloatOrNothing::Float(r)) => (l as f64) > r,
 | 
			
		||||
                (IntOrFloatOrNothing::Float(l), IntOrFloatOrNothing::Int(r)) => l > r as f64,
 | 
			
		||||
                (IntOrFloatOrNothing::Float(l), IntOrFloatOrNothing::Float(r)) => l > r,
 | 
			
		||||
            })))
 | 
			
		||||
            .add_var("ltoe".to_string(), Data::new(ltgtoe_function("ltoe".to_string(), |l, r| match (l, r) {
 | 
			
		||||
                (IntOrFloatOrNothing::Nothing, _) | (_, IntOrFloatOrNothing::Nothing) => true,
 | 
			
		||||
                (IntOrFloatOrNothing::Int(l), IntOrFloatOrNothing::Int(r)) => l <= r,
 | 
			
		||||
                (IntOrFloatOrNothing::Int(l), IntOrFloatOrNothing::Float(r)) => (l as f64) <= r,
 | 
			
		||||
                (IntOrFloatOrNothing::Float(l), IntOrFloatOrNothing::Int(r)) => l <= r as f64,
 | 
			
		||||
                (IntOrFloatOrNothing::Float(l), IntOrFloatOrNothing::Float(r)) => l <= r,
 | 
			
		||||
            })))
 | 
			
		||||
            .add_var("gtoe".to_string(), Data::new(ltgtoe_function("gtoe".to_string(), |l, r| match (l, r) {
 | 
			
		||||
                (IntOrFloatOrNothing::Nothing, _) | (_, IntOrFloatOrNothing::Nothing) => true,
 | 
			
		||||
                (IntOrFloatOrNothing::Int(l), IntOrFloatOrNothing::Int(r)) => l >= r,
 | 
			
		||||
                (IntOrFloatOrNothing::Int(l), IntOrFloatOrNothing::Float(r)) => (l as f64) >= r,
 | 
			
		||||
                (IntOrFloatOrNothing::Float(l), IntOrFloatOrNothing::Int(r)) => l >= r as f64,
 | 
			
		||||
                (IntOrFloatOrNothing::Float(l), IntOrFloatOrNothing::Float(r)) => l >= r,
 | 
			
		||||
            })))
 | 
			
		||||
            .add_var("parse_float".to_string(), Data::new(data::function::Function {
 | 
			
		||||
            info: Arc::new(program::run::Info::neverused()),
 | 
			
		||||
            info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
 | 
			
		||||
            out: Arc::new(|a, _i| {
 | 
			
		||||
@ -125,25 +158,6 @@ impl Config {
 | 
			
		||||
                    }
 | 
			
		||||
                } else { unreachable!() }),
 | 
			
		||||
            }))
 | 
			
		||||
            .add_var("diff".to_string(), Data::new(data::function::Function {
 | 
			
		||||
                info: Arc::new(program::run::Info::neverused()),
 | 
			
		||||
                info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
 | 
			
		||||
                out: Arc::new(|a, _i| two_tuple_to_num(a, "diff")),
 | 
			
		||||
                run: Arc::new(|a, _i| if let Some(t) = a.get().as_any().downcast_ref::<data::tuple::Tuple>() {
 | 
			
		||||
                    let left = t.0[0].get();
 | 
			
		||||
                    let right = t.0[1].get();
 | 
			
		||||
                    let (left, right) = (left.as_any(), right.as_any());
 | 
			
		||||
                    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(r - l)),
 | 
			
		||||
                        (Some(data::int::Int(l)), None, None, Some(data::float::Float(r))) => Data::new(data::float::Float(r - *l as f64)),
 | 
			
		||||
                        (None, Some(data::float::Float(l)), Some(data::int::Int(r)), None) => Data::new(data::float::Float(*r as f64 - l)),
 | 
			
		||||
                        (None, Some(data::float::Float(l)), None, Some(data::float::Float(r))) => Data::new(data::float::Float(r - l)),
 | 
			
		||||
                        _ => unreachable!(),
 | 
			
		||||
                    }
 | 
			
		||||
                } else { unreachable!() }),
 | 
			
		||||
            }))
 | 
			
		||||
            .add_var(
 | 
			
		||||
            "sum".to_string(),
 | 
			
		||||
            Data::new(data::function::Function {
 | 
			
		||||
@ -204,6 +218,79 @@ impl Config {
 | 
			
		||||
                    }
 | 
			
		||||
                }),
 | 
			
		||||
            }),
 | 
			
		||||
        )
 | 
			
		||||
            .add_var(
 | 
			
		||||
            "subtract".to_string(),
 | 
			
		||||
            Data::new(data::function::Function {
 | 
			
		||||
                info: Arc::new(program::run::Info::neverused()),
 | 
			
		||||
                info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
 | 
			
		||||
                out: Arc::new(|a, _i| {
 | 
			
		||||
                    let mut ints = false;
 | 
			
		||||
                    let mut floats = false;
 | 
			
		||||
                    for a in &a.types {
 | 
			
		||||
                        if let Some(i) = a.iterable() {
 | 
			
		||||
                            if i.types
 | 
			
		||||
                                .iter()
 | 
			
		||||
                                .all(|t| t.as_any().downcast_ref::<data::int::IntT>().is_some())
 | 
			
		||||
                            {
 | 
			
		||||
                                ints = true;
 | 
			
		||||
                            } else if i.types.iter().all(|t| {
 | 
			
		||||
                                t.as_any().downcast_ref::<data::int::IntT>().is_some()
 | 
			
		||||
                                    || t.as_any().downcast_ref::<data::float::FloatT>().is_some()
 | 
			
		||||
                            }) {
 | 
			
		||||
                                floats = true;
 | 
			
		||||
                            } else {
 | 
			
		||||
                                return Err(format!("cannot subtract on iterator over type {i} because it contains types that aren't int/float").into())
 | 
			
		||||
                            }
 | 
			
		||||
                        } else {
 | 
			
		||||
                            return Err(format!(
 | 
			
		||||
                                "cannot subtract over non-iterable type {a}"
 | 
			
		||||
                            ).into());
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    Ok(match (ints, floats) {
 | 
			
		||||
                        (_, true) => Type::new(data::float::FloatT),
 | 
			
		||||
                        (true, false) => Type::new(data::int::IntT),
 | 
			
		||||
                        (false, false) => Type::empty(),
 | 
			
		||||
                    })
 | 
			
		||||
                }),
 | 
			
		||||
                run: Arc::new(|a, _i| {
 | 
			
		||||
                    if let Some(i) = a.get().iterable() {
 | 
			
		||||
                        let mut first = true;
 | 
			
		||||
                        let mut sumi = 0;
 | 
			
		||||
                        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>() {
 | 
			
		||||
                                if first {
 | 
			
		||||
                                    sumi = i.0;
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    sumi -= i.0;
 | 
			
		||||
                                }
 | 
			
		||||
                            } else if let Some(i) =
 | 
			
		||||
                                val.get().as_any().downcast_ref::<data::float::Float>()
 | 
			
		||||
                            {
 | 
			
		||||
                                if first {
 | 
			
		||||
                                    sumf = i.0;
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    sumf -= i.0;
 | 
			
		||||
                                }
 | 
			
		||||
                                usef = true;
 | 
			
		||||
                            }
 | 
			
		||||
                            if first {
 | 
			
		||||
                                first = false;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        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")
 | 
			
		||||
                    }
 | 
			
		||||
                }),
 | 
			
		||||
            }),
 | 
			
		||||
        )
 | 
			
		||||
            .add_var(
 | 
			
		||||
            "product".to_string(),
 | 
			
		||||
@ -301,3 +388,53 @@ fn two_tuple_to_num(a: &Type, func_name: &str) -> Result<Type, CheckError> {
 | 
			
		||||
        Type::new(data::int::IntT)
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn ltgtoe_function(
 | 
			
		||||
    func_name: String,
 | 
			
		||||
    op: impl Fn(IntOrFloatOrNothing, IntOrFloatOrNothing) -> bool + Send + Sync + 'static,
 | 
			
		||||
) -> data::function::Function {
 | 
			
		||||
    data::function::Function {
 | 
			
		||||
        info: Arc::new(program::run::Info::neverused()),
 | 
			
		||||
        info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
 | 
			
		||||
        out: Arc::new(move |a, _i| {
 | 
			
		||||
            if let Some(iter_type) = a.iterable() {
 | 
			
		||||
                let iter_required_type = Type::newm(vec![
 | 
			
		||||
                    Arc::new(data::int::IntT),
 | 
			
		||||
                    Arc::new(data::float::FloatT),
 | 
			
		||||
                ]);
 | 
			
		||||
                if iter_type.is_included_in(&iter_required_type) {
 | 
			
		||||
                    Ok(Type::new(data::bool::BoolT))
 | 
			
		||||
                } else {
 | 
			
		||||
                    Err(CheckError::from(format!("Cannot use {func_name} on iterator over type {iter_type} (has to be at most {iter_required_type}).")))
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                Err(CheckError::from(format!("Cannot use {func_name}")))
 | 
			
		||||
            }
 | 
			
		||||
        }),
 | 
			
		||||
        run: Arc::new(move |a, _i| {
 | 
			
		||||
            let mut prev = IntOrFloatOrNothing::Nothing;
 | 
			
		||||
            for item in a.get().iterable().unwrap() {
 | 
			
		||||
                let item = item.get();
 | 
			
		||||
                let new = if let Some(data::int::Int(v)) = item.as_any().downcast_ref() {
 | 
			
		||||
                    IntOrFloatOrNothing::Int(*v)
 | 
			
		||||
                } else if let Some(data::float::Float(v)) = item.as_any().downcast_ref() {
 | 
			
		||||
                    IntOrFloatOrNothing::Float(*v)
 | 
			
		||||
                } else {
 | 
			
		||||
                    unreachable!()
 | 
			
		||||
                };
 | 
			
		||||
                if op(prev, new) {
 | 
			
		||||
                    prev = new;
 | 
			
		||||
                } else {
 | 
			
		||||
                    return Data::new(data::bool::Bool(false));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            Data::new(data::bool::Bool(true))
 | 
			
		||||
        }),
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
#[derive(Clone, Copy)]
 | 
			
		||||
enum IntOrFloatOrNothing {
 | 
			
		||||
    Nothing,
 | 
			
		||||
    Int(isize),
 | 
			
		||||
    Float(f64),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										0
									
								
								mers_lib/src/program/configs/with_string.rs
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								mers_lib/src/program/configs/with_string.rs
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user