schala/schala-lang/language/src/typechecking.rs

120 lines
2.5 KiB
Rust
Raw Normal View History

2018-02-21 02:31:28 -08:00
use std::rc::Rc;
2018-11-06 16:47:34 -08:00
use ast::*;
2018-11-06 13:44:52 -08:00
2018-05-27 02:44:06 -07:00
pub type TypeName = Rc<String>;
2018-11-06 13:44:52 -08:00
pub struct TypeContext {
}
2018-11-06 16:47:34 -08:00
type TypeResult<T> = Result<T, TypeError>;
#[derive(Debug, Clone)]
struct TypeError { }
2018-11-07 13:44:28 -08:00
#[derive(Debug, Clone)]
2018-11-07 03:39:31 -08:00
enum MonoType {
Var(Rc<String>),
2018-11-07 15:39:40 -08:00
Const(TConst),
2018-11-07 03:39:31 -08:00
Arrow(Rc<String>)
}
2018-11-06 16:47:34 -08:00
2018-11-07 15:39:40 -08:00
#[derive(Debug, Clone)]
enum TConst {
User(Rc<String>),
Unit,
Nat,
2018-11-07 16:39:32 -08:00
Int,
Float,
StringT,
2018-11-07 15:39:40 -08:00
}
impl TConst {
fn user(name: &str) -> TConst {
TConst::User(Rc::new(name.to_string()))
}
}
2018-11-07 13:44:28 -08:00
#[derive(Debug, Clone)]
2018-11-07 03:39:31 -08:00
struct PolyType {
vars: Vec<Rc<String>>,
ty: MonoType
2018-11-06 16:47:34 -08:00
}
2018-11-06 13:44:52 -08:00
impl TypeContext {
pub fn new() -> TypeContext {
TypeContext { }
}
2018-11-07 13:44:28 -08:00
pub fn typecheck(&mut self, ast: &AST) -> Result<String, String> {
2018-11-06 16:47:34 -08:00
match self.infer_ast(ast) {
2018-11-07 13:44:28 -08:00
Ok(t) => Ok(format!("{:?}", t)),
2018-11-06 16:47:34 -08:00
Err(err) => Err(format!("Type error: {:?}", err))
}
}
}
impl TypeContext {
2018-11-07 03:39:31 -08:00
fn infer_ast(&mut self, ast: &AST) -> TypeResult<MonoType> {
2018-11-07 15:39:40 -08:00
let mut output = MonoType::Const(TConst::Unit);
2018-11-07 03:39:31 -08:00
for statement in ast.0.iter() {
2018-11-07 13:44:28 -08:00
output = match statement {
2018-11-07 03:39:31 -08:00
Statement::ExpressionStatement(ref expr) => self.infer_expr(expr)?,
Statement::Declaration(ref decl) => self.infer_decl(decl)?,
};
}
Ok(output)
}
fn infer_expr(&mut self, expr: &Expression) -> TypeResult<MonoType> {
match expr {
Expression(expr_type, Some(type_anno)) => unimplemented!(),
Expression(expr_type, None) => self.infer_expr_type(expr_type)
}
}
fn infer_decl(&mut self, expr: &Declaration) -> TypeResult<MonoType> {
2018-11-07 15:39:40 -08:00
Ok(MonoType::Const(TConst::user("unimplemented")))
2018-11-06 16:47:34 -08:00
}
2018-11-07 03:39:31 -08:00
fn infer_expr_type(&mut self, expr_type: &ExpressionType) -> TypeResult<MonoType> {
use self::ExpressionType::*;
match expr_type {
2018-11-07 15:39:40 -08:00
NatLiteral(_) => Ok(MonoType::Const(TConst::Nat)),
2018-11-07 16:39:32 -08:00
FloatLiteral(_) => Ok(MonoType::Const(TConst::Float)),
StringLiteral(_) => Ok(MonoType::Const(TConst::StringT)),
2018-11-07 15:39:40 -08:00
_ => Ok(MonoType::Const(TConst::user("unimplemented")))
2018-11-07 03:39:31 -08:00
}
}
2018-11-06 16:47:34 -08:00
}
#[cfg(test)]
mod tests {
use super::*;
2018-11-07 16:39:32 -08:00
fn parse(input: &str) -> AST {
let tokens: Vec<::tokenizing::Token> = ::tokenizing::tokenize(input);
let mut parser = ::parsing::Parser::new(tokens);
parser.parse().unwrap()
}
macro_rules! type_test {
($input:expr, $correct:expr) => {
{
let mut tc = TypeContext::new();
let ast = parse($input);
tc.add_symbols(&ast);
assert_eq!($correct, tc.type_check(&ast).unwrap())
}
}
}
2018-11-06 16:47:34 -08:00
#[test]
fn basic_inference() {
2018-11-06 13:44:52 -08:00
}
}