From 385019e43cd001e8c2774a67fc05ee275c7fffa7 Mon Sep 17 00:00:00 2001 From: Mark <> Date: Thu, 29 Aug 2024 15:04:32 +0200 Subject: [PATCH] replace Bool type with Bool=True/False + bugfix Bool is a type alias for True/False Bugfix: [[T] String] { [[T] Int] // this would use the outer T (String), // but now it correctly uses the inner T (Int). [T] 1 } --- mers/Cargo.toml | 4 +- mers_lib/src/data/bool.rs | 45 ++++++++++++++++--- mers_lib/src/parsing/types.rs | 1 + mers_lib/src/program/configs/gen/mod.rs | 6 +-- mers_lib/src/program/configs/mod.rs | 9 +++- mers_lib/src/program/configs/util.rs | 45 ------------------- mers_lib/src/program/configs/with_base.rs | 4 +- .../program/configs/with_command_running.rs | 11 ++--- mers_lib/src/program/configs/with_iters.rs | 10 ++--- .../program/configs/with_multithreading.rs | 2 +- mers_lib/src/program/run/if.rs | 20 ++++++--- 11 files changed, 81 insertions(+), 76 deletions(-) diff --git a/mers/Cargo.toml b/mers/Cargo.toml index 8534c69..a994c72 100644 --- a/mers/Cargo.toml +++ b/mers/Cargo.toml @@ -15,7 +15,7 @@ default = ["colored-output"] colored-output = ["mers_lib/ecolor-term", "mers_lib/pretty-print", "dep:colored"] [dependencies] -mers_lib = "0.9.1" -# mers_lib = { path = "../mers_lib" } +# mers_lib = "0.9.1" +mers_lib = { path = "../mers_lib" } clap = { version = "4.3.19", features = ["derive"] } colored = { version = "2.1.0", optional = true } diff --git a/mers_lib/src/data/bool.rs b/mers_lib/src/data/bool.rs index 65e5184..2734969 100755 --- a/mers_lib/src/data/bool.rs +++ b/mers_lib/src/data/bool.rs @@ -17,7 +17,11 @@ impl MersData for Bool { Box::new(Clone::clone(self)) } fn as_type(&self) -> super::Type { - Type::new(BoolT) + if self.0 { + Type::new(TrueT) + } else { + Type::new(FalseT) + } } fn as_any(&self) -> &dyn Any { self @@ -31,8 +35,34 @@ impl MersData for Bool { } #[derive(Debug, Clone)] -pub struct BoolT; -impl MersType for BoolT { +pub struct TrueT; +#[derive(Debug, Clone)] +pub struct FalseT; +/// Returns the type `True/False`. +pub fn bool_type() -> Type { + Type::newm(vec![Arc::new(TrueT), Arc::new(FalseT)]) +} +impl MersType for TrueT { + fn is_same_type_as(&self, other: &dyn MersType) -> bool { + other.as_any().downcast_ref::().is_some() + } + fn is_included_in(&self, target: &dyn MersType) -> bool { + self.is_same_type_as(target) + } + fn subtypes(&self, acc: &mut Type) { + acc.add(Arc::new(self.clone())); + } + fn as_any(&self) -> &dyn Any { + self + } + fn mut_any(&mut self) -> &mut dyn Any { + self + } + fn to_any(self) -> Box { + Box::new(self) + } +} +impl MersType for FalseT { fn is_same_type_as(&self, other: &dyn MersType) -> bool { other.as_any().downcast_ref::().is_some() } @@ -58,8 +88,13 @@ impl Display for Bool { write!(f, "{}", self.0) } } -impl Display for BoolT { +impl Display for TrueT { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "Bool") + write!(f, "True") + } +} +impl Display for FalseT { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "False") } } diff --git a/mers_lib/src/parsing/types.rs b/mers_lib/src/parsing/types.rs index e476a51..46b6d9d 100755 --- a/mers_lib/src/parsing/types.rs +++ b/mers_lib/src/parsing/types.rs @@ -256,6 +256,7 @@ pub fn type_from_parsed( ParsedType::Type(name) => match info .scopes .iter() + .rev() .find_map(|scope| scope.types.iter().find(|v| v.0 == name).map(|(_, v)| v)) { Some(Ok(t)) => as_type.add_all(&*t), diff --git a/mers_lib/src/program/configs/gen/mod.rs b/mers_lib/src/program/configs/gen/mod.rs index 463abb6..e771753 100644 --- a/mers_lib/src/program/configs/gen/mod.rs +++ b/mers_lib/src/program/configs/gen/mod.rs @@ -2,7 +2,7 @@ pub mod function; use std::sync::{Arc, RwLock}; -use crate::data::{self, Data, MersData, Type}; +use crate::data::{self, bool::bool_type, Data, MersData, Type}; pub trait FromMersData: Sized { fn as_type_from() -> Type; @@ -336,7 +336,7 @@ impl FromMersData for bool { Self::as_type_to() } fn can_represent(t: &Type) -> bool { - t.is_included_in(&Type::new(data::bool::BoolT)) + t.is_included_in(&bool_type()) } fn try_represent) -> O>(d: &(impl MersData + ?Sized), f: F) -> O { if let Some(v) = d.as_any().downcast_ref::() { @@ -348,7 +348,7 @@ impl FromMersData for bool { } impl ToMersData for bool { fn as_type_to() -> Type { - Type::new(data::bool::BoolT) + bool_type() } fn represent(self) -> Data { Data::new(data::bool::Bool(self)) diff --git a/mers_lib/src/program/configs/mod.rs b/mers_lib/src/program/configs/mod.rs index 274e8bb..962d00e 100755 --- a/mers_lib/src/program/configs/mod.rs +++ b/mers_lib/src/program/configs/mod.rs @@ -75,7 +75,14 @@ impl Config { .insert(t.to_string(), Ok(Arc::new(data::Type::new(t)))); }; } - init_d!(data::bool::BoolT); + init_d!(data::bool::TrueT); + init_d!(data::bool::FalseT); + info_check + .scopes + .last_mut() + .unwrap() + .types + .insert("Bool".to_owned(), Ok(Arc::new(data::bool::bool_type()))); init_d!(data::byte::ByteT); init_d!(data::int::IntT); init_d!(data::float::FloatT); diff --git a/mers_lib/src/program/configs/util.rs b/mers_lib/src/program/configs/util.rs index 2f56490..630e604 100644 --- a/mers_lib/src/program/configs/util.rs +++ b/mers_lib/src/program/configs/util.rs @@ -95,48 +95,3 @@ pub fn to_mers_func_concrete_string_string_to_any( }, ) } -pub fn to_mers_func_concrete_string_string_to_opt_int( - f: impl Fn(&str, &str) -> Option + Send + Sync + 'static, -) -> 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![])), - ]), - move |a, b| { - Ok(f(a, b) - .map(|v| Data::one_tuple(Data::new(data::int::Int(v)))) - .unwrap_or_else(|| Data::empty_tuple())) - }, - ) -} -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| { - Ok(Data::new(data::bool::Bool(f(a, b)))) - }) -} -pub fn to_mers_func_concrete_string_string_to_opt_string_string( - f: impl Fn(&str, &str) -> Option<(String, String)> + Send + Sync + 'static, -) -> data::function::Function { - to_mers_func_concrete_string_string_to_any( - Type::newm(vec![ - Arc::new(data::tuple::TupleT(vec![])), - Arc::new(data::tuple::TupleT(vec![ - Type::new(data::string::StringT), - Type::new(data::string::StringT), - ])), - ]), - move |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())) - }, - ) -} diff --git a/mers_lib/src/program/configs/with_base.rs b/mers_lib/src/program/configs/with_base.rs index e6bce21..fe3387b 100755 --- a/mers_lib/src/program/configs/with_base.rs +++ b/mers_lib/src/program/configs/with_base.rs @@ -4,7 +4,7 @@ use std::{ }; use crate::{ - data::{self, Data, Type}, + data::{self, bool::bool_type, Data, Type}, errors::CheckError, program::run::{CheckInfo, Info}, }; @@ -132,7 +132,7 @@ impl Config { return Err(format!("called eq on non-iterable").into()) } } - Ok(Type::new(data::bool::BoolT)) + Ok(bool_type()) })), run: Arc::new(|a, _i| { Ok(Data::new(data::bool::Bool(if let Some(mut i) = a.get().iterable() { diff --git a/mers_lib/src/program/configs/with_command_running.rs b/mers_lib/src/program/configs/with_command_running.rs index 4f4cbee..108ecb5 100755 --- a/mers_lib/src/program/configs/with_command_running.rs +++ b/mers_lib/src/program/configs/with_command_running.rs @@ -33,7 +33,7 @@ impl Config { if a.types.iter().all(|t| t.as_any().downcast_ref::().is_some_and(|t| t.0.len() == 2 && t.0[0].is_included_in_single(&data::string::StringT) && t.0[1].iterable().is_some_and(|t| t.is_included_in_single(&data::string::StringT)))) { Ok(Type::newm(vec![ Arc::new(data::tuple::TupleT(vec![ - Type::newm(vec![Arc::new(data::int::IntT), Arc::new(data::bool::BoolT)]), + Type::newm(vec![Arc::new(data::int::IntT), Arc::new(data::bool::TrueT), Arc::new(data::bool::FalseT)]), Type::new(data::string::StringT), Type::new(data::string::StringT), ])), @@ -131,7 +131,7 @@ impl Config { out: Ok(Arc::new(|a, _i| { if a.is_included_in_single(&ChildProcessT) { Ok(Type::newm(vec![ - Arc::new(data::tuple::TupleT(vec![Type::new(data::bool::BoolT)])), + Arc::new(data::tuple::TupleT(vec![data::bool::bool_type()])), Arc::new(data::tuple::TupleT(vec![])), ])) } else { @@ -160,7 +160,8 @@ impl Config { if a.is_included_in_single(&ChildProcessT) { Ok(Type::newm(vec![ Arc::new(data::int::IntT), - Arc::new(data::bool::BoolT), + Arc::new(data::bool::TrueT), + Arc::new(data::bool::FalseT), Arc::new(data::tuple::TupleT(vec![])), ])) } else { @@ -191,7 +192,7 @@ impl Config { info_check: Arc::new(Mutex::new( CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| { if a.types.iter().all(|a| a.as_any().downcast_ref::().is_some_and(|t| t.0.len() == 2 && t.0[0].is_included_in_single(&ChildProcessT) && t.0[1].iterable().is_some_and(|i| i.is_included_in_single(&data::byte::ByteT)))) { - Ok(Type::new(data::bool::BoolT)) + Ok(data::bool::bool_type()) } else { return Err(format!("childproc_write_bytes called on non-`(ChildProcess, Iter)` type {a}").into()); } @@ -220,7 +221,7 @@ impl Config { info_check: Arc::new(Mutex::new( CheckInfo::neverused())), out: Ok(Arc::new(|a, _i| { if a.is_included_in_single(&data::tuple::TupleT(vec![Type::new(ChildProcessT), Type::new(data::string::StringT)])) { - Ok(Type::new(data::bool::BoolT)) + Ok(data::bool::bool_type()) } else { return Err(format!("childproc_write_string called on non-`(ChildProcess, String)` type {a}").into()); } diff --git a/mers_lib/src/program/configs/with_iters.rs b/mers_lib/src/program/configs/with_iters.rs index 0f20044..faa92df 100755 --- a/mers_lib/src/program/configs/with_iters.rs +++ b/mers_lib/src/program/configs/with_iters.rs @@ -28,7 +28,7 @@ impl Config { /// `all: fn` returns true if all elements of the iterator are true pub fn with_iters(self) -> Self { self - .add_var("any", genfunc_iter_in_val_out("all".to_string(), data::bool::BoolT, Type::new(data::bool::BoolT), |a, _i| { + .add_var("any", genfunc_iter_in_val_out("all".to_string(), data::bool::bool_type(), data::bool::bool_type(), |a, _i| { for v in a.get().iterable().unwrap().map(|v| v.map(|v| v.get().as_any().downcast_ref::().is_some_and(|v| v.0))) { if v? { return Ok(Data::new(data::bool::Bool(true))); @@ -36,7 +36,7 @@ impl Config { } Ok(Data::new(data::bool::Bool(false))) })) - .add_var("all", genfunc_iter_in_val_out("all".to_string(), data::bool::BoolT, Type::new(data::bool::BoolT), |a, _i| { + .add_var("all", genfunc_iter_in_val_out("all".to_string(), data::bool::bool_type(), data::bool::bool_type(), |a, _i| { for v in a.get().iterable().unwrap().map(|v| v.map(|v| v.get().as_any().downcast_ref::().is_some_and(|v| v.0))) { if !v? { return Ok(Data::new(data::bool::Bool(false))); @@ -413,7 +413,7 @@ impl IterT { let t = match &iter { ItersT::Map(f) => f.o(&data)?, ItersT::Filter(f) => { - if f.o(&data)?.is_included_in_single(&data::bool::BoolT) { + if f.o(&data)?.is_included_in(&data::bool::bool_type()) { data.clone() } else { return Err(format!( @@ -517,7 +517,7 @@ impl Iters { fn genfunc_iter_in_val_out( name: String, - iter_type: impl MersType + 'static, + iter_type: Type, out_type: Type, run: impl Fn(Data, &mut crate::info::Info) -> Result + Send @@ -529,7 +529,7 @@ fn genfunc_iter_in_val_out( info_check: Arc::new(Mutex::new(crate::info::Info::neverused())), out: Ok(Arc::new(move |a, _i| { if let Some(iter_over) = a.iterable() { - if iter_over.is_included_in_single(&iter_type) { + if iter_over.is_included_in(&iter_type) { Ok(out_type.clone()) } else { Err(format!("Cannot call function {name} on iterator over type {a}, which isn't {iter_type}.").into()) diff --git a/mers_lib/src/program/configs/with_multithreading.rs b/mers_lib/src/program/configs/with_multithreading.rs index 6bd8eff..b2cc41d 100755 --- a/mers_lib/src/program/configs/with_multithreading.rs +++ b/mers_lib/src/program/configs/with_multithreading.rs @@ -63,7 +63,7 @@ impl Config { return Err(CheckError::new().msg_str(format!("Cannot call thread_finished on a value of type {t}, which isn't a thread but part of the argument {a}."))); } } - Ok(Type::new(data::bool::BoolT)) + Ok(data::bool::bool_type()) })), run: Arc::new(|a, _i| { let a = a.get(); diff --git a/mers_lib/src/program/run/if.rs b/mers_lib/src/program/run/if.rs index 7846e27..33ebf67 100755 --- a/mers_lib/src/program/run/if.rs +++ b/mers_lib/src/program/run/if.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use crate::{ - data::{self, tuple::TupleT, Data, Type}, + data::{self, tuple::TupleT, Data, MersType, Type}, errors::{CheckError, EColor, SourceRange}, }; @@ -25,7 +25,7 @@ impl MersStatement for If { return Err("can't init to statement type If".to_string().into()); } let cond_return_type = self.condition.check(info, None)?; - if !cond_return_type.is_included_in_single(&data::bool::BoolT) { + if !cond_return_type.is_included_in(&data::bool::bool_type()) { return Err(CheckError::new() .src(vec![ (self.pos_in_src.clone(), None), @@ -38,7 +38,7 @@ impl MersStatement for If { ("The ".to_owned(), None), ("condition".to_owned(), Some(EColor::IfConditionNotBool)), ( - " in an if-statement must return bool, not ".to_owned(), + " in an if-statement must return Bool, not ".to_owned(), None, ), ( @@ -47,11 +47,17 @@ impl MersStatement for If { ), ])); } - let mut t = self.on_true.check(info, None)?; - if let Some(f) = &self.on_false { - t.add_all(&f.check(info, None)?); + let mut t = if Type::new(data::bool::TrueT).is_included_in(&cond_return_type) { + self.on_true.check(info, None)? } else { - t.add(Arc::new(TupleT(vec![]))); + Type::empty() + }; + if Type::new(data::bool::FalseT).is_included_in(&cond_return_type) { + if let Some(f) = &self.on_false { + t.add_all(&f.check(info, None)?); + } else { + t.add(Arc::new(TupleT(vec![]))); + } } Ok(t) }