aboutsummaryrefslogtreecommitdiff
path: root/src/type
diff options
context:
space:
mode:
Diffstat (limited to 'src/type')
-rw-r--r--src/type/check.rs17
-rw-r--r--src/type/display.rs1
-rw-r--r--src/type/mod.rs6
-rw-r--r--src/type/subst.rs2
-rw-r--r--src/type/util.rs3
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())
+}