From 8fe535597e0f7d5c5e3f8b0433a63ffa9c0ccaa8 Mon Sep 17 00:00:00 2001 From: greg Date: Sun, 8 Oct 2017 22:48:10 -0700 Subject: [PATCH] Starting to actually do Hindley-Milner!! --- src/schala_lang/mod.rs | 5 +++-- src/schala_lang/type_check.rs | 39 ++++++++++++++++++++--------------- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/schala_lang/mod.rs b/src/schala_lang/mod.rs index 609e134..7dff4d1 100644 --- a/src/schala_lang/mod.rs +++ b/src/schala_lang/mod.rs @@ -70,7 +70,9 @@ impl ProgrammingLanguageInterface for Schala { } match self.type_context.type_check(&ast) { - Ok(_) => (), + Ok(ty) => { + output.add_artifact(TraceArtifact::new("type_check", format!("type: {:?}", ty))); + }, Err(msg) => { output.add_artifact(TraceArtifact::new("type_check", msg)); output.add_output(format!("Type error")); @@ -87,7 +89,6 @@ impl ProgrammingLanguageInterface for Schala { acc.push_str("\n"); } } - output.add_output(acc); return output; } diff --git a/src/schala_lang/type_check.rs b/src/schala_lang/type_check.rs index 7fdd931..1121319 100644 --- a/src/schala_lang/type_check.rs +++ b/src/schala_lang/type_check.rs @@ -64,7 +64,11 @@ impl TypeContext { } } -pub struct SchalaType { +#[derive(Debug)] +pub enum SchalaType { + Integer, + Boolean, + Unit, } type TypeCheckResult = Result; @@ -81,35 +85,36 @@ type TypeCheckResult = Result; fn bare_type_check(exprssion, expected_type) -> Ty { ... } */ + +// from https://www.youtube.com/watch?v=il3gD7XMdmA +// typeInfer :: Expr a -> Matching (Type a) +// unify :: Type a -> Type b -> Matching (Type c) + impl TypeContext { pub fn type_check(&mut self, ast: &AST) -> TypeCheckResult { - use self::ExpressionType::*; - + let mut last = SchalaType::Unit; for statement in ast.0.iter() { match statement { &Statement::Declaration(ref _decl) => { - return Err(format!("Declarations not supported")); + //return Err(format!("Declarations not supported")); }, &Statement::ExpressionStatement(ref expr) => { - self.expr_type_check(expr)?; + last = self.infer(expr)?; } } } - Ok(SchalaType { }) + Ok(last) } - fn expr_type_check(&mut self, expr: &Expression) -> TypeCheckResult { + fn infer(&mut self, expr: &Expression) -> TypeCheckResult { use self::ExpressionType::*; - match (&expr.0, &expr.1) { - (&IntLiteral(_), &Some(ref t)) => { - match t { - &TypeName::Singleton { ref name, ref params } if **name == "Int" && params.len() == 0 => (), - t => return Err(format!("Bad type {:?} for int literal", t)), - } - }, - _ => (), - } - Ok(SchalaType { }) + Ok(match (&expr.0, &expr.1) { + (&IntLiteral(_), _) => SchalaType::Integer, + (&BoolLiteral(_), _) => SchalaType::Boolean, + _ => SchalaType::Unit, + }) } } + +