aboutsummaryrefslogtreecommitdiff
path: root/src/type/check.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/type/check.rs')
-rw-r--r--src/type/check.rs67
1 files changed, 26 insertions, 41 deletions
diff --git a/src/type/check.rs b/src/type/check.rs
index 77420e3..874db58 100644
--- a/src/type/check.rs
+++ b/src/type/check.rs
@@ -31,7 +31,9 @@ impl SExp {
/// Ok(List(vec![QuoteTy, List(vec![Integer, Boolean])]))
/// );
/// ```
- /// Though so is Nil given too:
+ ///
+ /// Even though Nil is formatted as an empty list,
+ /// it has its own type.
/// ```rust
/// use myslip::{
/// r#type::{*, Type::*, TypeError::*, util::*},
@@ -40,7 +42,7 @@ impl SExp {
///
/// assert_eq!(
/// Atom(Nil).type_check(),
- /// Ok(List(vec![]))
+ /// Ok(NilType)
/// );
/// ```
///
@@ -184,7 +186,7 @@ impl SExp {
Ok(arr(List(vec![Integer, Integer]), Boolean)),
Atom(Or | And | Xor) => Ok(arr(List(vec![Boolean, Boolean]), Boolean)),
Atom(Not) => Ok(arr(List(vec!(Boolean)), Boolean)),
- Atom(Nil) => Ok(List(vec![])),
+ Atom(Nil) => Ok(NilType),
Atom(Quote) => Ok(arr(
vt("T"),
List(vec![QuoteTy, vt("T")])
@@ -216,38 +218,40 @@ impl SExp {
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 conv_args = match (opertype.clone(), argstype.clone()) {
+ (Arrow(from, _), a) => match a.clone().into_type(&*from) {
+ Ok(s) => Ok(s),
+ Err(()) => Err(InvalidArgList {
+ arglist: (**l).clone(),
+ expected: *from,
+ found: a,
+ })
+ },
+ (a, _) => {
+ Err(InvalidOperator {
+ operator: *op.clone(),
+ expected: arr(vt("_"), vt("_")),
+ found: a,
+ })
+ }
+ }?;
let opertype = if opertype.is_concrete().is_ok() {
opertype
} else {
- opertype.infer_generics(&argstype)?
+ opertype.infer_generics(&conv_args)?
};
match (opertype, argstype) {
(Arrow(a, b), c) => {
- if *a != c {
+ if c.aka(&*a) {
+ Ok(*b)
+ } else {
Err(InvalidArgList {
arglist: (**l).clone(),
expected: *a,
found: c,
})
- } else {
- Ok(*b)
}
},
(t, _) => Err(InvalidOperator {
@@ -353,25 +357,6 @@ 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
- }
- }
- }
-
}