Starting on lambda typechecking
This commit is contained in:
parent
8dc34e4b49
commit
e34295a6f7
@ -217,7 +217,7 @@ impl<'a> TypeContext<'a> {
|
|||||||
Singleton(TypeSingletonName { name, params }) => {
|
Singleton(TypeSingletonName { name, params }) => {
|
||||||
match Type::from_string(&name) {
|
match Type::from_string(&name) {
|
||||||
Some(ty) => ty,
|
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"),
|
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> {
|
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> {
|
fn block(&mut self, block: &Block) -> InferResult<Type> {
|
||||||
@ -358,13 +368,14 @@ impl<'a> TypeContext<'a> {
|
|||||||
|
|
||||||
match (t1, t2) {
|
match (t1, t2) {
|
||||||
(Const(ref c1), Const(ref c2)) if c1 == c2 => Ok(Const(c1.clone())), //choice of c1 is arbitrary I *think*
|
(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)) => {
|
(Const(ref c1), Var(ref v2)) => {
|
||||||
self.unification_table.unify_var_value(v2.clone(), Some(c1.clone()))
|
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))))?;
|
.or_else(|_| TypeError::new(format!("Couldn't unify {:?} and {:?}", Const(c1.clone()), Var(*v2))))?;
|
||||||
Ok(Const(c1.clone()))
|
Ok(Const(c1.clone()))
|
||||||
},
|
},
|
||||||
(a @ Var(_), b @ Const(_)) => self.unify(b, a),
|
|
||||||
(Var(v1), Var(v2)) => {
|
(Var(v1), Var(v2)) => {
|
||||||
|
//TODO add occurs check
|
||||||
self.unification_table.unify_var_var(v1.clone(), v2.clone())
|
self.unification_table.unify_var_var(v1.clone(), v2.clone())
|
||||||
.or_else(|_| TypeError::new(format!("Two type variables {:?} and {:?} couldn't unify", v1, v2)))?;
|
.or_else(|_| TypeError::new(format!("Two type variables {:?} and {:?} couldn't unify", v1, v2)))?;
|
||||||
Ok(Var(v1.clone())) //arbitrary decision I think
|
Ok(Var(v1.clone())) //arbitrary decision I think
|
||||||
|
Loading…
Reference in New Issue
Block a user