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
}
This commit is contained in:
Mark 2024-08-29 15:04:32 +02:00
parent 7f318d9e1c
commit 385019e43c
11 changed files with 81 additions and 76 deletions

View File

@ -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 }

View File

@ -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::<Self>().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<dyn Any> {
Box::new(self)
}
}
impl MersType for FalseT {
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
other.as_any().downcast_ref::<Self>().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")
}
}

View File

@ -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),

View File

@ -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, F: FnOnce(Option<Self>) -> O>(d: &(impl MersData + ?Sized), f: F) -> O {
if let Some(v) = d.as_any().downcast_ref::<data::bool::Bool>() {
@ -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))

View File

@ -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);

View File

@ -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<isize> + 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()))
},
)
}

View File

@ -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() {

View File

@ -33,7 +33,7 @@ impl Config {
if a.types.iter().all(|t| t.as_any().downcast_ref::<data::tuple::TupleT>().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::<data::tuple::TupleT>().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<Byte>)` 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());
}

View File

@ -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::<data::bool::Bool>().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::<data::bool::Bool>().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<program::run::RunLocal>) -> Result<Data, CheckError>
+ 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())

View File

@ -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();

View File

@ -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)
}