diff options
Diffstat (limited to 'src/type')
-rw-r--r-- | src/type/check.rs | 17 | ||||
-rw-r--r-- | src/type/display.rs | 1 | ||||
-rw-r--r-- | src/type/mod.rs | 6 | ||||
-rw-r--r-- | src/type/subst.rs | 2 | ||||
-rw-r--r-- | src/type/util.rs | 3 |
5 files changed, 29 insertions, 0 deletions
diff --git a/src/type/check.rs b/src/type/check.rs index c3bdcb4..10ef8b4 100644 --- a/src/type/check.rs +++ b/src/type/check.rs @@ -44,6 +44,20 @@ impl SExp { /// ); /// ``` /// + /// Vectors are kind of special... + /// ```rust + /// use myslip::{ + /// r#type::{*, Type::*, TypeError::*, util::*}, + /// sexp::{SExp::*, SLeaf::*, util::*}, + /// }; + /// + /// assert_eq!( + /// scons(Vector, scons(1, scons(3, Nil))).type_check(), + /// Ok(vecof(Integer)) + /// ); + /// ``` + /// ...so please don't ask what their type is. + /// /// Some common operators get arrow types: /// ```rust /// use myslip::{ @@ -109,6 +123,8 @@ impl SExp { /// assert!(scons(And, scons(1, scons(Atom(True), Nil))).type_check().is_err()); /// assert!(scons(Mul, scons(1, scons(Atom(True), Nil))).type_check().is_err()); /// assert!(scons(Not, scons(1, Nil)).type_check().is_err()); + /// + /// assert!(scons(Vector, scons(1, scons(True, Nil))).type_check().is_err()); /// ``` /// /// Also, free variables should result in an error @@ -153,6 +169,7 @@ impl SExp { vt("T"), List(vec![QuoteTy, vt("T")]) )), + Atom(Vector) => todo!(), SCons(op, l) => { let opertype = (*op).infer_type(ctx.clone())?; diff --git a/src/type/display.rs b/src/type/display.rs index 8eb0647..6c3177a 100644 --- a/src/type/display.rs +++ b/src/type/display.rs @@ -20,6 +20,7 @@ impl fmt::Display for Type { Integer => write!(f, "{}", "Int"), Boolean => write!(f, "{}", "Bool"), QuoteTy => write!(f, "{}", "Quote"), + VecOf(ty) => write!(f, "({} ... {})", *ty, *ty), Arrow(a, b) => write!(f, "({} -> {})", a, b), List(types) => write!( f, diff --git a/src/type/mod.rs b/src/type/mod.rs index e29e069..01aed40 100644 --- a/src/type/mod.rs +++ b/src/type/mod.rs @@ -22,6 +22,8 @@ pub enum Type { List(Vec<Type>), + VecOf(Box<Type>), + /// Type for generics /// and also error messages /// with unknown types @@ -89,6 +91,9 @@ impl Type { /// .is_concrete(), /// Err("a".to_string()) /// ); + /// + /// assert_eq!(vecof(vt("a")).is_concrete(), Err("a".to_string())); + /// assert_eq!(vecof(Integer).is_concrete(), Ok(())); /// ``` pub fn is_concrete(&self) -> Result<(), String> { match self { @@ -103,6 +108,7 @@ impl Type { } res }, + VecOf(ty) => (*ty).is_concrete(), VarType(s) => Err(s.clone()), } } diff --git a/src/type/subst.rs b/src/type/subst.rs index d63f71b..12a9f15 100644 --- a/src/type/subst.rs +++ b/src/type/subst.rs @@ -33,6 +33,8 @@ impl Type { .collect() ), + VecOf(ty) => vecof((*ty).subst(name, value)), + VarType(s) if s == name => value.clone(), VarType(s) => VarType(s), diff --git a/src/type/util.rs b/src/type/util.rs index 9be8c6e..85e64f1 100644 --- a/src/type/util.rs +++ b/src/type/util.rs @@ -9,3 +9,6 @@ pub fn vt(name: &str) -> Type { VarType(name.to_string()) } +pub fn vecof(ty: impl Into<Box<Type>>) -> Type { + VecOf(ty.into()) +} |