Super-basic type inference working
with a bunch of assumptions and hard-coded values
This commit is contained in:
parent
3b249045aa
commit
60fc9fd7e1
@ -1,4 +1,4 @@
|
|||||||
#![feature(advanced_slice_patterns, slice_patterns, box_patterns)]
|
#![feature(advanced_slice_patterns, slice_patterns, box_patterns, box_syntax)]
|
||||||
#![feature(plugin)]
|
#![feature(plugin)]
|
||||||
#![plugin(rocket_codegen)]
|
#![plugin(rocket_codegen)]
|
||||||
extern crate getopts;
|
extern crate getopts;
|
||||||
|
@ -46,6 +46,10 @@ impl SymbolTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn lookup(&mut self, binding: &Rc<String>) -> Option<SchalaType> {
|
||||||
|
use self::SchalaType::*;
|
||||||
|
Some(Function(Box::new(Integer), Box::new(Boolean)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TypeContext {
|
pub struct TypeContext {
|
||||||
@ -64,11 +68,12 @@ impl TypeContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum SchalaType {
|
pub enum SchalaType {
|
||||||
Integer,
|
Integer,
|
||||||
Boolean,
|
Boolean,
|
||||||
Unit,
|
Unit,
|
||||||
|
Function(Box<SchalaType>, Box<SchalaType>),
|
||||||
}
|
}
|
||||||
|
|
||||||
type TypeCheckResult = Result<SchalaType, String>;
|
type TypeCheckResult = Result<SchalaType, String>;
|
||||||
@ -112,15 +117,31 @@ impl TypeContext {
|
|||||||
Ok(match (&expr.0, &expr.1) {
|
Ok(match (&expr.0, &expr.1) {
|
||||||
(&IntLiteral(_), _) => SchalaType::Integer,
|
(&IntLiteral(_), _) => SchalaType::Integer,
|
||||||
(&BoolLiteral(_), _) => SchalaType::Boolean,
|
(&BoolLiteral(_), _) => SchalaType::Boolean,
|
||||||
/*
|
(&Variable(ref name), _) => self.symbol_table
|
||||||
(&Call { name, arguments }, _) => {
|
.lookup(name)
|
||||||
let f_type = self.infer
|
.ok_or(format!("Couldn't find {}", name))?,
|
||||||
|
|
||||||
|
(&Call { ref f, ref arguments }, _) => {
|
||||||
|
let f_type = self.infer(&*f)?;
|
||||||
|
let arg_type = self.infer(arguments.get(0).unwrap())?; // TODO fix later
|
||||||
|
match f_type {
|
||||||
|
SchalaType::Function(box t1, box ret_type) => {
|
||||||
|
let _ = self.unify(&t1, &arg_type)?;
|
||||||
|
ret_type
|
||||||
|
},
|
||||||
|
_ => return Err(format!("Type error"))
|
||||||
|
}
|
||||||
},
|
},
|
||||||
*/
|
|
||||||
_ => SchalaType::Unit,
|
_ => SchalaType::Unit,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn unify(&mut self, t1: &SchalaType, t2: &SchalaType) -> TypeCheckResult {
|
||||||
|
if t1 == t2 {
|
||||||
|
Ok(t1.clone())
|
||||||
|
} else {
|
||||||
|
Err(format!("Types {:?} and {:?} don't unify", t1, t2))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user