diff options
author | Joel Kronqvist <joel.kronqvist@iki.fi> | 2025-08-05 19:29:28 +0300 |
---|---|---|
committer | Joel Kronqvist <joel.kronqvist@iki.fi> | 2025-08-05 19:29:28 +0300 |
commit | 3d7ebeddc46e89c8e058b3f1805f836339a2f9ae (patch) | |
tree | 80736ecf56e6678e5ed9c1fd0d2bba3f99f377e5 | |
parent | d64165e9e6af92bfe350e5d2cc46545b28dbb5c0 (diff) | |
download | myslip-3d7ebeddc46e89c8e058b3f1805f836339a2f9ae.tar.gz myslip-3d7ebeddc46e89c8e058b3f1805f836339a2f9ae.zip |
Implemented vector.
-rw-r--r-- | src/sexp/mod.rs | 4 | ||||
-rw-r--r-- | src/type/check.rs | 50 | ||||
-rw-r--r-- | src/type/display.rs | 1 | ||||
-rw-r--r-- | src/type/mod.rs | 4 | ||||
-rw-r--r-- | src/type/subst.rs | 1 |
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, } } |