Starting on lambda typechecking

This commit is contained in:
greg 2019-02-23 02:45:11 -08:00
parent 8dc34e4b49
commit e34295a6f7
1 changed files with 14 additions and 3 deletions

View File

@ -217,7 +217,7 @@ impl<'a> TypeContext<'a> {
Singleton(TypeSingletonName { name, params }) => {
match Type::from_string(&name) {
Some(ty) => ty,
None => return TypeError::new("Unknown type name")
None => return TypeError::new(format!("Unknown type name: {}", name))
}
},
Tuple(_) => return TypeError::new("tuples aren't ready yet"),
@ -332,8 +332,18 @@ impl<'a> TypeContext<'a> {
}
fn lambda(&mut self, params: &Vec<FormalParam>, type_anno: &Option<TypeIdentifier>, body: &Block) -> InferResult<Type> {
let argument_types: InferResult<Vec<Type>> = params.iter().map(|param: &FormalParam| {
if let (_, Some(type_identifier)) = param {
self.get_type_from_name(type_identifier)
} else {
Ok(Type::Var(self.fresh_type_variable()))
}
}).collect();
let argument_types = argument_types?;
Ok(ty!(Unit))
println!("ARGUMENT TYPES: {:?}", argument_types);
Ok(ty!(UserDefined))
}
fn block(&mut self, block: &Block) -> InferResult<Type> {
@ -358,13 +368,14 @@ impl<'a> TypeContext<'a> {
match (t1, t2) {
(Const(ref c1), Const(ref c2)) if c1 == c2 => Ok(Const(c1.clone())), //choice of c1 is arbitrary I *think*
(a @ Var(_), b @ Const(_)) => self.unify(b, a),
(Const(ref c1), Var(ref v2)) => {
self.unification_table.unify_var_value(v2.clone(), Some(c1.clone()))
.or_else(|_| TypeError::new(format!("Couldn't unify {:?} and {:?}", Const(c1.clone()), Var(*v2))))?;
Ok(Const(c1.clone()))
},
(a @ Var(_), b @ Const(_)) => self.unify(b, a),
(Var(v1), Var(v2)) => {
//TODO add occurs check
self.unification_table.unify_var_var(v1.clone(), v2.clone())
.or_else(|_| TypeError::new(format!("Two type variables {:?} and {:?} couldn't unify", v1, v2)))?;
Ok(Var(v1.clone())) //arbitrary decision I think