diff --git a/schala-lang/language/src/typechecking.rs b/schala-lang/language/src/typechecking.rs index 52b6dba..25fc233 100644 --- a/schala-lang/language/src/typechecking.rs +++ b/schala-lang/language/src/typechecking.rs @@ -11,13 +11,25 @@ pub struct TypeContext { type InferResult = Result; #[derive(Debug, Clone)] -struct TypeError { } +struct TypeError { msg: String } + +impl TypeError { + fn new(msg: &str) -> InferResult { + Err(TypeError { msg: msg.to_string() }) + } +} #[derive(Debug, Clone)] enum MonoType { Var(Rc), Const(TConst), - Arrow(Rc) + Arrow(Box, Box) +} + +impl TypeIdentifier { + fn to_monotype(&self) -> MonoType { + unimplemented!() + } } #[derive(Debug, Clone)] @@ -70,7 +82,11 @@ impl TypeContext { fn infer_expr(&mut self, expr: &Expression) -> InferResult { match expr { - Expression(expr_type, Some(type_anno)) => unimplemented!(), + Expression(expr_type, Some(type_anno)) => { + let tx = self.infer_expr_type(expr_type)?; + let ty = type_anno.to_monotype(); + self.unify(&ty, &tx) + }, Expression(expr_type, None) => self.infer_expr_type(expr_type) } } @@ -86,11 +102,22 @@ impl TypeContext { FloatLiteral(_) => MonoType::Const(TConst::Float), StringLiteral(_) => MonoType::Const(TConst::StringT), BoolLiteral(_) => MonoType::Const(TConst::Bool), + Call { f, arguments } => { + let tf: MonoType = self.infer_expr(f)?; //has to be an Arrow MonoType + let targ = self.infer_expr(&arguments[0])?; // TODO make this work with functions with more than one arg + match tf { + MonoType::Arrow(t1, t2) => { + self.unify(&t1, &targ)?; + *t2.clone() + }, + _ => return TypeError::new("not a function") + } + }, _ => MonoType::Const(TConst::user("unimplemented")) }) } - fn unify(t1: MonoType, t2: MonoType) -> InferResult { + fn unify(&mut self, t1: &MonoType, t2: &MonoType) -> InferResult { unimplemented!() } }