diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/type/conversion.rs | 129 | ||||
-rw-r--r-- | src/type/mod.rs | 1 |
2 files changed, 130 insertions, 0 deletions
diff --git a/src/type/conversion.rs b/src/type/conversion.rs new file mode 100644 index 0000000..128d1aa --- /dev/null +++ b/src/type/conversion.rs @@ -0,0 +1,129 @@ + +use crate::r#type::Type; + +impl Type { + + /// Checks if this type is known as the given other type, + /// ie. checks if there exists an implicit conversion from + /// one to the other. + /// + /// Currently this is only needed for list to vec conversions. + /// ```rust + /// use myslip::r#type::{Type::*, util::*}; + /// assert!(List(vec![Integer, Integer, Integer]).aka(&vecof(Integer))); + /// ``` + /// + /// Preferrably this should also work with generics: + /// ```rust + /// use myslip::r#type::{Type::*, util::*}; + /// assert!(List(vec![Integer, Boolean, Integer]).aka(&vecof(vt("T")))); + /// assert!(List(vec![Integer, Boolean, vt("X")]).aka(&vecof(vt("T")))); + /// ``` + /// + /// But of course it also should know when to fail: + /// ```rust + /// use myslip::r#type::{Type::*, util::*}; + /// assert!(!List(vec![Integer, Boolean]).aka(&vecof(Integer))); + /// assert!(!List(vec![Integer, Boolean]).aka(&vecof(Boolean))); + /// ``` + pub fn aka(&self, known_as: &Type) -> bool { + todo!() + } + + fn least_general_supertype(&self, other: &Type) -> Type { + todo!() + } + +} + +#[cfg(test)] +mod tests { + + use crate::r#type::{Type::*, util::*}; + + #[test] + fn test_basic_general_supertypes() { + + assert_eq!(Integer.least_general_supertype(&Integer), Integer); + assert_eq!(Integer.least_general_supertype(&Boolean), vt("T")); + + } + + #[test] + fn test_compound_general_supertypes() { + + assert_eq!( + List(vec![Integer, Integer]) + .least_general_supertype( + &List(vec![Integer, Integer]) + ), + List(vec![Integer, Integer]) + ); + + assert_eq!( + List(vec![Integer, Boolean]) + .least_general_supertype( + &List(vec![Integer, Integer]) + ), + List(vec![Integer, vt("T")]) + ); + + assert_eq!( + vecof(Integer) + .least_general_supertype( + &vecof(Integer) + ), + vecof(Integer) + ); + + assert_eq!( + vecof(Integer) + .least_general_supertype( + &vecof(Boolean) + ), + vecof(vt("T")) + ); + + assert_eq!( + List(vec![Integer, Boolean]).least_general_supertype( + &List(vec![Boolean, Integer]) + ), + List(vec![vt("T"), vt("T")]) + ); + + } + + #[test] + fn test_conversion_in_general_supertypes() { + + assert_eq!( + List(vec![Integer, Integer]).least_general_supertype( + &vecof(Integer) + ), + vecof(Integer) + ); + + assert_eq!( + List(vec![Integer, Integer]).least_general_supertype( + &List(vec![Integer, Integer, Integer]) + ), + vecof(Integer) + ); + + assert_eq!( + List(vec![Integer, Boolean]).least_general_supertype( + &List(vec![Integer, Boolean, Integer]) + ), + vecof(vt("T")) + ); + + assert_eq!( + List(vec![Boolean, Integer]).least_general_supertype( + &vecof(Integer) + ), + vecof(vt("T")) + ); + + } + +} diff --git a/src/type/mod.rs b/src/type/mod.rs index afb5a0b..eba817b 100644 --- a/src/type/mod.rs +++ b/src/type/mod.rs @@ -4,6 +4,7 @@ pub mod util; pub mod display; pub mod check; pub mod subst; +pub mod conversion; use crate::sexp::SExp; |