diff --git a/schala-lang/src/typechecking.rs b/schala-lang/src/typechecking.rs index 467deb7..91db9ac 100644 --- a/schala-lang/src/typechecking.rs +++ b/schala-lang/src/typechecking.rs @@ -1,11 +1,17 @@ use std::rc::Rc; use std::collections::{HashSet, HashMap}; +use std::collections::hash_set::Union; +use std::iter::Iterator; //use std::char; use std::fmt; use std::fmt::Write; use itertools::Itertools; + +/* GIANT TODO - use the rust im crate, unless I make this code way less haskell-ish after it's done + */ + use parsing; pub struct TypeContext { @@ -56,9 +62,37 @@ enum TypeConst { Tuple(Vec), } +impl MonoType { + fn free_vars(&self) -> HashSet> { + use self::MonoType::*; + match self { + Const(_) => HashSet::new(), + Var(a) => { + let mut h = HashSet::new(); + h.insert(a.clone()); + h + }, + Function(a, b) => { + a.free_vars().union(&b.free_vars()).cloned().collect() + }, + } + } +} + #[derive(Debug, PartialEq, Clone)] struct PolyType(HashSet>, MonoType); +impl PolyType { + fn free_vars(&self) -> HashSet> { + let mtype = self.1.free_vars(); + self.0.difference(&mtype).cloned().collect() + } +} + +#[derive(Debug, PartialEq, Clone)] +struct Substitution(HashMap, MonoType>); + + #[derive(Debug, PartialEq, Clone)] pub enum Type { Const(TConstOld), @@ -160,11 +194,32 @@ impl TypeContext { pub fn type_check_ast(&mut self, ast: &parsing::AST) -> TypeResult { let ref block = ast.0; - //Ok(self.infer_block(block)?) - Ok(format!("Nothin' b/c redoing typechecking")) + let mut infer = Infer::new(); + let output = infer.infer_block(block)?; + + Ok(format!("{:?}", output)) } } +// this is the equivalent of the Haskell Infer monad +#[derive(Debug)] +struct Infer { + +} + +impl Infer { + fn new() -> Infer { + Infer { } + } + + fn infer_block(&mut self, block: &Vec) -> TypeResult { + Ok(MonoType::Const(TypeConst::Unit)) + } +} + + + + /* impl TypeContext { fn infer_block(&mut self, statements: &Vec) -> TypeResult {