From 2e457cd5e8dc96a10c759a778804d2fd7a48abac Mon Sep 17 00:00:00 2001 From: greg Date: Fri, 18 May 2018 03:12:18 -0700 Subject: [PATCH] First real inferring --- schala-lang/src/typechecking.rs | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/schala-lang/src/typechecking.rs b/schala-lang/src/typechecking.rs index 3e2abc2..8ed7176 100644 --- a/schala-lang/src/typechecking.rs +++ b/schala-lang/src/typechecking.rs @@ -280,7 +280,8 @@ struct Infer { enum InferError { CannotUnify(MonoType, MonoType), OccursCheckFailed(Rc, MonoType), - UnknownIdentifier(Rc) + UnknownIdentifier(Rc), + Custom(String), } type InferResult = Result; @@ -339,11 +340,33 @@ impl Infer { } } - fn infer_exprtype(&mut self, expr: &parsing::ExpressionType, env: &TypeEnvironment) -> InferResult<(Substitution, MonoType)> { - unimplemented!() - } fn infer_annotated_expr(&mut self, expr: &parsing::ExpressionType, anno: &parsing::TypeName, env: &TypeEnvironment) -> InferResult<(Substitution, MonoType)> { - unimplemented!() + Err(InferError::Custom(format!("exprtype not done: {:?}", expr))) + } + fn infer_exprtype(&mut self, expr: &parsing::ExpressionType, env: &TypeEnvironment) -> InferResult<(Substitution, MonoType)> { + use self::parsing::ExpressionType::*; + use self::TypeConst::*; + Ok(match expr { + NatLiteral(_) => (Substitution::new(), MonoType::Const(Nat)), + FloatLiteral(_) => (Substitution::new(), MonoType::Const(Float)), + StringLiteral(_) => (Substitution::new(), MonoType::Const(StringT)), + BoolLiteral(_) => (Substitution::new(), MonoType::Const(Bool)), + /* + BinExp(op, lhs, rhs) => { /* remember there are both the haskell convention talk and the write you a haskell ways to do this! */ + match op.get_type()? { + Func(box t1, box Func(box t2, box t3)) => { + let lhs_ty = self.infer(lhs)?; + let rhs_ty = self.infer(rhs)?; + self.unify(t1, lhs_ty)?; + self.unify(t2, rhs_ty)?; + Ok(t3) + }, + other => return Err(format!("{:?} is not a binary function type", other)) + } + }, + */ + e => return Err(InferError::Custom(format!("Type inference for {:?} not done", e))) + }) } }