aboutsummaryrefslogtreecommitdiff
path: root/src/type
diff options
context:
space:
mode:
authorJoel Kronqvist <joel.kronqvist@iki.fi>2025-08-10 14:36:02 +0300
committerJoel Kronqvist <joel.kronqvist@iki.fi>2025-08-10 14:36:02 +0300
commitc121f20620499e9b7c497c82c7321474cbf59e1d (patch)
tree617c20d31cb577b459a423074d97a6e1b91e2a0c /src/type
parent09f39aebe68213799fdd7a33665a162c40baf299 (diff)
downloadmyslip-c121f20620499e9b7c497c82c7321474cbf59e1d.tar.gz
myslip-c121f20620499e9b7c497c82c7321474cbf59e1d.zip
Implemented aka. Changed Nil:st type to NilType from an empty list.
Diffstat (limited to 'src/type')
-rw-r--r--src/type/conversion.rs55
-rw-r--r--src/type/display.rs1
-rw-r--r--src/type/mod.rs3
-rw-r--r--src/type/subst.rs1
4 files changed, 55 insertions, 5 deletions
diff --git a/src/type/conversion.rs b/src/type/conversion.rs
index 128d1aa..a819409 100644
--- a/src/type/conversion.rs
+++ b/src/type/conversion.rs
@@ -1,5 +1,5 @@
-use crate::r#type::Type;
+use crate::r#type::{Type, Type::*, util::*};
impl Type {
@@ -27,11 +27,48 @@ impl Type {
/// assert!(!List(vec![Integer, Boolean]).aka(&vecof(Boolean)));
/// ```
pub fn aka(&self, known_as: &Type) -> bool {
- todo!()
+ self.least_general_supertype(known_as) == *known_as
}
fn least_general_supertype(&self, other: &Type) -> Type {
- todo!()
+
+ match (self, other) {
+
+ (a, b) if a == b => a.clone(),
+
+ (VecOf(a), VecOf(b)) => vecof(a.least_general_supertype(b)),
+
+ (List(v1), List(v2)) if v1.len() == v2.len() => {
+ let mut res = vec![];
+ for (a, b) in v1.into_iter().zip(v2) {
+ res.push(a.least_general_supertype(b));
+ }
+ List(res)
+ },
+
+ (List(v1), List(v2)) => match v1.get(0).or(v2.get(0)) {
+ Some(first) => vecof(
+ v1.into_iter()
+ .chain(v2)
+ .fold(first.clone(), |a, b| a.least_general_supertype(b))
+ ),
+ None => panic!("unreachable - types would be equal")
+ },
+
+ (List(v), VecOf(b)) => vecof(
+ v.into_iter()
+ .fold(*b.clone(), |a, b| a.least_general_supertype(b))
+ ),
+ (VecOf(b), List(v)) => vecof(
+ v.into_iter()
+ .fold(*b.clone(), |a, b| a.least_general_supertype(b))
+ ),
+
+
+ _ => vt("T")
+
+ }
+
}
}
@@ -44,8 +81,16 @@ mod tests {
#[test]
fn test_basic_general_supertypes() {
- assert_eq!(Integer.least_general_supertype(&Integer), Integer);
- assert_eq!(Integer.least_general_supertype(&Boolean), vt("T"));
+ assert_eq!(
+ Integer.least_general_supertype(&Integer),
+ Integer,
+ "if two types are equal, they get the same supertype"
+ );
+ assert_eq!(
+ Integer.least_general_supertype(&Boolean),
+ vt("T"),
+ "if two types have nothing in common, vt(\"t\") is returned"
+ );
}
diff --git a/src/type/display.rs b/src/type/display.rs
index 4a9b54a..72e3693 100644
--- a/src/type/display.rs
+++ b/src/type/display.rs
@@ -22,6 +22,7 @@ impl fmt::Display for Type {
QuoteTy => write!(f, "{}", "Quote"),
VecType => write!(f, "{}", "Vector"),
LetType => write!(f, "{}", "Let"),
+ NilType => write!(f, "()"),
VecOf(ty) => write!(f, "({} ... {})", *ty, *ty),
Arrow(a, b) => write!(f, "({} -> {})", a, b),
List(types) => write!(
diff --git a/src/type/mod.rs b/src/type/mod.rs
index eba817b..9c2f89c 100644
--- a/src/type/mod.rs
+++ b/src/type/mod.rs
@@ -23,6 +23,8 @@ pub enum Type {
List(Vec<Type>),
+ NilType,
+
VecOf(Box<Type>),
VecType, // constructor
@@ -108,6 +110,7 @@ impl Type {
QuoteTy => Ok(()),
VecType => Ok(()),
LetType => Ok(()),
+ NilType => Ok(()),
Arrow(a, b) => b.is_concrete().and_then(|_ok| a.is_concrete()),
List(v) => {
let mut res = Ok(());
diff --git a/src/type/subst.rs b/src/type/subst.rs
index 3ee4260..ab9d38a 100644
--- a/src/type/subst.rs
+++ b/src/type/subst.rs
@@ -44,6 +44,7 @@ impl Type {
QuoteTy => QuoteTy,
VecType => VecType,
LetType => LetType,
+ NilType => NilType,
}
}