aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/sexp/mod.rs4
-rw-r--r--src/type/check.rs50
-rw-r--r--src/type/display.rs1
-rw-r--r--src/type/mod.rs4
-rw-r--r--src/type/subst.rs1
5 files changed, 56 insertions, 4 deletions
diff --git a/src/sexp/mod.rs b/src/sexp/mod.rs
index 3f17b79..07d8373 100644
--- a/src/sexp/mod.rs
+++ b/src/sexp/mod.rs
@@ -59,7 +59,9 @@ use SLeaf::*;
impl SExp {
pub fn is_value(&self) -> bool {
match self {
- SCons(a, b) => **a == Atom(Quote) && b.consists_of_values(),
+ SCons(a, b) =>
+ (**a == Atom(Quote) || **a == Atom(Vector))
+ && b.consists_of_values(),
Atom(Var(_)) => false,
Atom(_) => true,
}
diff --git a/src/type/check.rs b/src/type/check.rs
index 10ef8b4..df3f4d9 100644
--- a/src/type/check.rs
+++ b/src/type/check.rs
@@ -53,7 +53,7 @@ impl SExp {
///
/// assert_eq!(
/// scons(Vector, scons(1, scons(3, Nil))).type_check(),
- /// Ok(vecof(Integer))
+ /// Ok(List(vec![VecType, vecof(Integer)]))
/// );
/// ```
/// ...so please don't ask what their type is.
@@ -169,12 +169,31 @@ impl SExp {
vt("T"),
List(vec![QuoteTy, vt("T")])
)),
- Atom(Vector) => todo!(),
+ Atom(Vector) => Ok(arr(
+ vecof(vt("T")),
+ List(vec![VecType, vecof(vt("T"))])
+ )),
+
SCons(op, l) => {
let opertype = (*op).infer_type(ctx.clone())?;
let argstype = (*l).infer_list_type(ctx)?;
+ let argstype = if opertype == arr(
+ vecof(vt("T")),
+ List(vec![VecType, vecof(vt("T"))])
+ ) { // hacky...
+ argstype.list_to_vec().ok_or(
+ InvalidArgList {
+ arglist: (**l).clone(),
+ expected: vecof(vt("?")),
+ found: argstype
+ }
+ )?
+ } else {
+ argstype
+ };
+
let opertype = if opertype.is_concrete().is_ok() {
opertype
} else {
@@ -251,6 +270,7 @@ impl Type {
}
}
+
fn infer_generics_ctx(
&self,
argtype: &Type,
@@ -277,6 +297,13 @@ impl Type {
Ok(res)
},
+ (VecOf(t1), VecOf(t2)) => {
+ let mut res = ctx.clone();
+ let newctx = t1.infer_generics_ctx(t2, ctx.clone())?;
+ res.extend_from_slice(&newctx);
+ Ok(res)
+ },
+
(VarType(name), ty) => {
let mut res = ctx.clone();
res.push((name.clone(), ty.clone()));
@@ -288,6 +315,25 @@ impl Type {
}
}
+ fn list_to_vec(&self) -> Option<Type> {
+ println!("list to vec:");
+ match self {
+ List(tv) => match tv.get(0) {
+ Some(t1) => if tv.into_iter().all(|t| t == t1) {
+ Some(vecof(t1.clone()))
+ } else {
+ println!("all elements not of same type");
+ None
+ },
+ None => Some(vecof(vt("T"))),
+ },
+ _ => {
+ println!("not a list");
+ None
+ }
+ }
+ }
+
}
diff --git a/src/type/display.rs b/src/type/display.rs
index 6c3177a..03f8f4b 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"),
+ VecType => write!(f, "{}", "Vector"),
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 01aed40..0cbcf83 100644
--- a/src/type/mod.rs
+++ b/src/type/mod.rs
@@ -16,13 +16,14 @@ pub enum Type {
Boolean,
- QuoteTy,
+ QuoteTy, //constructor
Arrow(Box<Type>, Box<Type>),
List(Vec<Type>),
VecOf(Box<Type>),
+ VecType, // constructor
/// Type for generics
/// and also error messages
@@ -100,6 +101,7 @@ impl Type {
Integer => Ok(()),
Boolean => Ok(()),
QuoteTy => Ok(()),
+ VecType => 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 12a9f15..5f6573f 100644
--- a/src/type/subst.rs
+++ b/src/type/subst.rs
@@ -42,6 +42,7 @@ impl Type {
Integer => Integer,
Boolean => Boolean,
QuoteTy => QuoteTy,
+ VecType => VecType,
}
}