diff options
Diffstat (limited to 'src/type/check.rs')
-rw-r--r-- | src/type/check.rs | 50 |
1 files changed, 48 insertions, 2 deletions
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 + } + } + } + } |