From 5e20f9284945a22b8d8210ccfc389f9504fed6db Mon Sep 17 00:00:00 2001 From: Mark Date: Tue, 24 Oct 2023 09:31:49 +0200 Subject: [PATCH] Added the concept of `subtypes` ... ... which `try` now uses to avoid some problems with inner types --- mers_lib/src/data/bool.rs | 7 ++- mers_lib/src/data/float.rs | 7 ++- mers_lib/src/data/function.rs | 4 ++ mers_lib/src/data/int.rs | 7 ++- mers_lib/src/data/mod.rs | 19 ++++++++ mers_lib/src/data/reference.rs | 7 ++- mers_lib/src/data/string.rs | 7 ++- mers_lib/src/data/tuple.rs | 45 ++++++++++++++++++- mers_lib/src/program/configs/with_base.rs | 2 +- .../program/configs/with_command_running.rs | 5 ++- mers_lib/src/program/configs/with_iters.rs | 4 ++ mers_lib/src/program/configs/with_list.rs | 5 +++ .../program/configs/with_multithreading.rs | 5 +++ 13 files changed, 111 insertions(+), 13 deletions(-) diff --git a/mers_lib/src/data/bool.rs b/mers_lib/src/data/bool.rs index 85a1a1c..7323085 100755 --- a/mers_lib/src/data/bool.rs +++ b/mers_lib/src/data/bool.rs @@ -1,4 +1,4 @@ -use std::{any::Any, fmt::Display}; +use std::{any::Any, fmt::Display, sync::Arc}; use super::{MersData, MersType, Type}; @@ -30,7 +30,7 @@ impl MersData for Bool { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct BoolT; impl MersType for BoolT { fn is_same_type_as(&self, other: &dyn MersType) -> bool { @@ -39,6 +39,9 @@ impl MersType for BoolT { fn is_included_in_single(&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 } diff --git a/mers_lib/src/data/float.rs b/mers_lib/src/data/float.rs index 4a4eb9c..42a4bf9 100755 --- a/mers_lib/src/data/float.rs +++ b/mers_lib/src/data/float.rs @@ -1,4 +1,4 @@ -use std::{any::Any, fmt::Display}; +use std::{any::Any, fmt::Display, sync::Arc}; use super::{MersData, MersType, Type}; @@ -30,7 +30,7 @@ impl MersData for Float { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct FloatT; impl MersType for FloatT { fn is_same_type_as(&self, other: &dyn MersType) -> bool { @@ -39,6 +39,9 @@ impl MersType for FloatT { fn is_included_in_single(&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 } diff --git a/mers_lib/src/data/function.rs b/mers_lib/src/data/function.rs index 6d1343c..0c98a1f 100755 --- a/mers_lib/src/data/function.rs +++ b/mers_lib/src/data/function.rs @@ -72,6 +72,7 @@ impl MersData for Function { } } +#[derive(Clone)] pub struct FunctionT(pub Arc Result + Send + Sync>); impl MersType for FunctionT { fn iterable(&self) -> Option { @@ -100,6 +101,9 @@ impl MersType for FunctionT { fn is_included_in_single(&self, _target: &dyn MersType) -> bool { false } + fn subtypes(&self, acc: &mut Type) { + acc.add(Arc::new(self.clone())); + } fn as_any(&self) -> &dyn Any { self } diff --git a/mers_lib/src/data/int.rs b/mers_lib/src/data/int.rs index ab748d0..3f1b62a 100755 --- a/mers_lib/src/data/int.rs +++ b/mers_lib/src/data/int.rs @@ -1,4 +1,4 @@ -use std::{any::Any, fmt::Display}; +use std::{any::Any, fmt::Display, sync::Arc}; use super::{MersData, MersType, Type}; @@ -30,7 +30,7 @@ impl MersData for Int { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct IntT; impl MersType for IntT { fn is_same_type_as(&self, other: &dyn MersType) -> bool { @@ -39,6 +39,9 @@ impl MersType for IntT { fn is_included_in_single(&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 } diff --git a/mers_lib/src/data/mod.rs b/mers_lib/src/data/mod.rs index 1e3c14c..17084c5 100755 --- a/mers_lib/src/data/mod.rs +++ b/mers_lib/src/data/mod.rs @@ -59,6 +59,20 @@ pub trait MersType: Any + Debug + Display + Send + Sync { self.is_included_in_single(target) } } + /// Returns all types that can result from the use of this type. + /// Usually, this is just `acc.add(Arc::new(self.clone()))` + /// but if there exists one or more inner types, this becomes interesting: + /// Using `(int/string)` will end up being either `(int)` or `(string)`, + /// so this function should add `(int)` and `(string)`. + /// Since `(int/string)` can't exist at runtime, we don't need to list `self`. + /// note also: `subtypes` has to be called recursively, i.e. you would have to call `.substring` on `int` and `string`. + fn subtypes(&self, acc: &mut Type); + /// like `subtypes`, but returns the accumulator + fn subtypes_type(&self) -> Type { + let mut acc = Type::empty(); + self.subtypes(&mut acc); + acc + } fn as_any(&self) -> &dyn Any; fn mut_any(&mut self) -> &mut dyn Any; fn to_any(self) -> Box; @@ -293,6 +307,11 @@ 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 subtypes(&self, acc: &mut Type) { + for t in &self.types { + t.subtypes(acc); + } + } fn as_any(&self) -> &dyn Any { self } diff --git a/mers_lib/src/data/reference.rs b/mers_lib/src/data/reference.rs index 41f3e90..09e8670 100755 --- a/mers_lib/src/data/reference.rs +++ b/mers_lib/src/data/reference.rs @@ -34,7 +34,7 @@ impl MersData for Reference { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ReferenceT(pub Type); impl MersType for ReferenceT { fn is_same_type_as(&self, other: &dyn MersType) -> bool { @@ -48,6 +48,11 @@ impl MersType for ReferenceT { // &int isn't included in &(int/float), otherwise we could assign a float to it self.is_same_type_as(target) } + fn subtypes(&self, acc: &mut Type) { + // we don't call subtypes because (int/string) must stay that so we can assign either + // NOTE: this might not be right...? + acc.add(Arc::new(self.clone())); + } fn as_any(&self) -> &dyn Any { self } diff --git a/mers_lib/src/data/string.rs b/mers_lib/src/data/string.rs index db39c34..9c21a47 100755 --- a/mers_lib/src/data/string.rs +++ b/mers_lib/src/data/string.rs @@ -1,4 +1,4 @@ -use std::{any::Any, fmt::Display}; +use std::{any::Any, fmt::Display, sync::Arc}; use super::{MersData, MersType, Type}; @@ -30,7 +30,7 @@ impl MersData for String { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct StringT; impl MersType for StringT { fn is_same_type_as(&self, other: &dyn MersType) -> bool { @@ -39,6 +39,9 @@ impl MersType for StringT { fn is_included_in_single(&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 } diff --git a/mers_lib/src/data/tuple.rs b/mers_lib/src/data/tuple.rs index eb0a910..e959608 100755 --- a/mers_lib/src/data/tuple.rs +++ b/mers_lib/src/data/tuple.rs @@ -53,10 +53,31 @@ impl MersType for TupleT { Some(o) } fn is_same_type_as(&self, other: &dyn MersType) -> bool { - other.as_any().downcast_ref::().is_some() + if let Some(other) = other.as_any().downcast_ref::() { + self.0.len() == other.0.len() + && self + .0 + .iter() + .zip(other.0.iter()) + .all(|(s, o)| s.is_same_type_as(o)) + } else { + false + } } fn is_included_in_single(&self, target: &dyn MersType) -> bool { - self.is_same_type_as(target) + if let Some(target) = target.as_any().downcast_ref::() { + self.0.len() == target.0.len() + && self + .0 + .iter() + .zip(target.0.iter()) + .all(|(s, t)| s.is_included_in(t)) + } else { + false + } + } + fn subtypes(&self, acc: &mut Type) { + self.gen_subtypes_recursively(acc, &mut Vec::with_capacity(self.0.len())); } fn as_any(&self) -> &dyn Any { self @@ -95,3 +116,23 @@ impl Display for TupleT { Ok(()) } } + +impl TupleT { + pub fn gen_subtypes_recursively(&self, acc: &mut Type, types: &mut Vec>) { + if types.len() >= self.0.len() { + let nt = Self( + types + .iter() + .map(|v| Type::newm(vec![Arc::clone(v)])) + .collect(), + ); + acc.add(Arc::new(nt)); + } else { + for t in self.0[types.len()].subtypes_type().types { + types.push(t); + self.gen_subtypes_recursively(acc, types); + types.pop(); + } + } + } +} diff --git a/mers_lib/src/program/configs/with_base.rs b/mers_lib/src/program/configs/with_base.rs index c3ab507..3ede8a4 100755 --- a/mers_lib/src/program/configs/with_base.rs +++ b/mers_lib/src/program/configs/with_base.rs @@ -28,7 +28,7 @@ impl Config { } let arg_type = &t.0[0]; let functions = &t.0[1]; - for arg_type in arg_type.types.iter() { + for arg_type in arg_type.subtypes_type().types.iter() { let arg_type = Type::newm(vec![arg_type.clone()]); // possibilities for the tuple (f1, f2, f3, ..., fn) for ft in functions.types.iter() { diff --git a/mers_lib/src/program/configs/with_command_running.rs b/mers_lib/src/program/configs/with_command_running.rs index 55c2b69..4b1083a 100755 --- a/mers_lib/src/program/configs/with_command_running.rs +++ b/mers_lib/src/program/configs/with_command_running.rs @@ -83,7 +83,7 @@ impl Config { #[derive(Clone, Debug)] pub struct RunCommandError(String); -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct RunCommandErrorT; impl MersData for RunCommandError { fn is_eq(&self, other: &dyn MersData) -> bool { @@ -116,6 +116,9 @@ impl MersType for RunCommandErrorT { fn is_included_in_single(&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 std::any::Any { self } diff --git a/mers_lib/src/program/configs/with_iters.rs b/mers_lib/src/program/configs/with_iters.rs index a184d29..48cd875 100755 --- a/mers_lib/src/program/configs/with_iters.rs +++ b/mers_lib/src/program/configs/with_iters.rs @@ -247,6 +247,10 @@ impl MersType for IterT { false } } + fn subtypes(&self, acc: &mut Type) { + // NOTE: This might not be good enough + acc.add(Arc::new(self.clone())); + } fn as_any(&self) -> &dyn std::any::Any { self } diff --git a/mers_lib/src/program/configs/with_list.rs b/mers_lib/src/program/configs/with_list.rs index 530b49b..249a7ff 100755 --- a/mers_lib/src/program/configs/with_list.rs +++ b/mers_lib/src/program/configs/with_list.rs @@ -201,6 +201,11 @@ impl MersType for ListT { fn is_included_in_single(&self, target: &dyn MersType) -> bool { self.is_same_type_as(target) } + fn subtypes(&self, acc: &mut Type) { + for t in self.0.subtypes_type().types { + acc.add(Arc::new(Self(Type::newm(vec![t])))); + } + } fn as_any(&self) -> &dyn std::any::Any { self } diff --git a/mers_lib/src/program/configs/with_multithreading.rs b/mers_lib/src/program/configs/with_multithreading.rs index 584ecb3..2d1574f 100755 --- a/mers_lib/src/program/configs/with_multithreading.rs +++ b/mers_lib/src/program/configs/with_multithreading.rs @@ -127,6 +127,11 @@ impl MersType for ThreadT { false } } + fn subtypes(&self, acc: &mut Type) { + for t in self.0.subtypes_type().types { + acc.add(Arc::new(Self(Type::newm(vec![t])))); + } + } fn as_any(&self) -> &dyn std::any::Any { self }