Starting to actually do Hindley-Milner!!

This commit is contained in:
greg 2017-10-08 22:48:10 -07:00
parent 4bb8f82579
commit 8fe535597e
2 changed files with 25 additions and 19 deletions

View File

@ -70,7 +70,9 @@ impl ProgrammingLanguageInterface for Schala {
} }
match self.type_context.type_check(&ast) { match self.type_context.type_check(&ast) {
Ok(_) => (), Ok(ty) => {
output.add_artifact(TraceArtifact::new("type_check", format!("type: {:?}", ty)));
},
Err(msg) => { Err(msg) => {
output.add_artifact(TraceArtifact::new("type_check", msg)); output.add_artifact(TraceArtifact::new("type_check", msg));
output.add_output(format!("Type error")); output.add_output(format!("Type error"));
@ -87,7 +89,6 @@ impl ProgrammingLanguageInterface for Schala {
acc.push_str("\n"); acc.push_str("\n");
} }
} }
output.add_output(acc); output.add_output(acc);
return output; return output;
} }

View File

@ -64,7 +64,11 @@ impl TypeContext {
} }
} }
pub struct SchalaType { #[derive(Debug)]
pub enum SchalaType {
Integer,
Boolean,
Unit,
} }
type TypeCheckResult = Result<SchalaType, String>; type TypeCheckResult = Result<SchalaType, String>;
@ -81,35 +85,36 @@ type TypeCheckResult = Result<SchalaType, String>;
fn bare_type_check(exprssion, expected_type) -> Ty { ... } 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 { impl TypeContext {
pub fn type_check(&mut self, ast: &AST) -> TypeCheckResult { pub fn type_check(&mut self, ast: &AST) -> TypeCheckResult {
use self::ExpressionType::*; let mut last = SchalaType::Unit;
for statement in ast.0.iter() { for statement in ast.0.iter() {
match statement { match statement {
&Statement::Declaration(ref _decl) => { &Statement::Declaration(ref _decl) => {
return Err(format!("Declarations not supported")); //return Err(format!("Declarations not supported"));
}, },
&Statement::ExpressionStatement(ref expr) => { &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::*; use self::ExpressionType::*;
match (&expr.0, &expr.1) { Ok(match (&expr.0, &expr.1) {
(&IntLiteral(_), &Some(ref t)) => { (&IntLiteral(_), _) => SchalaType::Integer,
match t { (&BoolLiteral(_), _) => SchalaType::Boolean,
&TypeName::Singleton { ref name, ref params } if **name == "Int" && params.len() == 0 => (), _ => SchalaType::Unit,
t => return Err(format!("Bad type {:?} for int literal", t)), })
}
},
_ => (),
}
Ok(SchalaType { })
} }
} }