diff options
author | Joel Kronqvist <joel.kronqvist@iki.fi> | 2025-08-10 14:36:02 +0300 |
---|---|---|
committer | Joel Kronqvist <joel.kronqvist@iki.fi> | 2025-08-10 14:36:02 +0300 |
commit | c121f20620499e9b7c497c82c7321474cbf59e1d (patch) | |
tree | 617c20d31cb577b459a423074d97a6e1b91e2a0c /src | |
parent | 09f39aebe68213799fdd7a33665a162c40baf299 (diff) | |
download | myslip-c121f20620499e9b7c497c82c7321474cbf59e1d.tar.gz myslip-c121f20620499e9b7c497c82c7321474cbf59e1d.zip |
Implemented aka. Changed Nil:st type to NilType from an empty list.
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 2 | ||||
-rw-r--r-- | src/type/conversion.rs | 55 | ||||
-rw-r--r-- | src/type/display.rs | 1 | ||||
-rw-r--r-- | src/type/mod.rs | 3 | ||||
-rw-r--r-- | src/type/subst.rs | 1 |
5 files changed, 56 insertions, 6 deletions
diff --git a/src/main.rs b/src/main.rs index 0c71fbe..b507cbd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -46,7 +46,7 @@ fn repl() -> Result<(), io::Error> { }; match &expression { - SCons(l, r) if **l == Atom(Let) => match scons(expression.clone(), Nil).type_check() { + SCons(l, _) if **l == Atom(Let) => match scons(expression.clone(), Nil).type_check() { Ok(_) => { binds.push(expression); println!("Bind saved"); 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, } } |