Starting to actually do Hindley-Milner!!
This commit is contained in:
parent
4bb8f82579
commit
8fe535597e
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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 { })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user