From d44bb02d614b1ef0856e510958f3057d3eccc1ae Mon Sep 17 00:00:00 2001 From: greg Date: Thu, 8 Nov 2018 20:30:17 -0800 Subject: [PATCH] Even more types --- schala-lang/language/src/lib.rs | 2 +- schala-lang/language/src/typechecking.rs | 52 ++++++++++++++++++++---- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/schala-lang/language/src/lib.rs b/schala-lang/language/src/lib.rs index e5cdafc..1802bb6 100644 --- a/schala-lang/language/src/lib.rs +++ b/schala-lang/language/src/lib.rs @@ -43,7 +43,7 @@ mod eval; pub struct Schala { state: eval::State<'static>, symbol_table: Rc>, - type_context: typechecking::TypeContext, + type_context: typechecking::TypeContext<'static>, active_parser: Option, } diff --git a/schala-lang/language/src/typechecking.rs b/schala-lang/language/src/typechecking.rs index 25fc233..394f937 100644 --- a/schala-lang/language/src/typechecking.rs +++ b/schala-lang/language/src/typechecking.rs @@ -1,11 +1,12 @@ use std::rc::Rc; use ast::*; +use util::ScopeStack; pub type TypeName = Rc; -pub struct TypeContext { - +pub struct TypeContext<'a> { + variable_map: ScopeStack<'a, Rc, MonoType> } type InferResult = Result; @@ -28,7 +29,19 @@ enum MonoType { impl TypeIdentifier { fn to_monotype(&self) -> MonoType { - unimplemented!() + match self { + TypeIdentifier::Tuple(items) => unimplemented!(), + TypeIdentifier::Singleton(TypeSingletonName { name, .. }) => { + match &name[..] { + "Nat" => MonoType::Const(TConst::Nat), + "Int" => MonoType::Const(TConst::Int), + "Float" => MonoType::Const(TConst::Float), + "Bool" => MonoType::Const(TConst::Bool), + "String" => MonoType::Const(TConst::StringT), + _ => unimplemented!() + } + } + } } } @@ -55,9 +68,11 @@ struct PolyType { ty: MonoType } -impl TypeContext { - pub fn new() -> TypeContext { - TypeContext { } +impl<'a> TypeContext<'a> { + pub fn new() -> TypeContext<'a> { + TypeContext { + variable_map: ScopeStack::new(None), + } } pub fn typecheck(&mut self, ast: &AST) -> Result { @@ -68,7 +83,7 @@ impl TypeContext { } } -impl TypeContext { +impl<'a> TypeContext<'a> { fn infer_ast(&mut self, ast: &AST) -> InferResult { let mut output = MonoType::Const(TConst::Unit); for statement in ast.0.iter() { @@ -102,6 +117,15 @@ impl TypeContext { FloatLiteral(_) => MonoType::Const(TConst::Float), StringLiteral(_) => MonoType::Const(TConst::StringT), BoolLiteral(_) => MonoType::Const(TConst::Bool), + Value(name) => { + //TODO handle the distinction between 0-arg constructors and variables at some point + // need symbol table for that + match self.variable_map.lookup(name) { + Some(ty) => ty.clone(), + None => return TypeError::new(&format!("Variable {} not found", name)) + } + }, + IfExpression { discriminator, body } => self.infer_if_expr(discriminator, body)?, Call { f, arguments } => { let tf: MonoType = self.infer_expr(f)?; //has to be an Arrow MonoType let targ = self.infer_expr(&arguments[0])?; // TODO make this work with functions with more than one arg @@ -117,6 +141,20 @@ impl TypeContext { }) } + fn infer_if_expr(&mut self, discriminator: &Discriminator, body: &IfExpressionBody) -> InferResult { + let test = match discriminator { + Discriminator::Simple(expr) => expr, + _ => return TypeError::new("Dame desu") + }; + + let (then_clause, maybe_else_clause) = match body { + IfExpressionBody::SimpleConditional(a, b) => (a, b), + _ => return TypeError::new("Dont work") + }; + + unimplemented!() + } + fn unify(&mut self, t1: &MonoType, t2: &MonoType) -> InferResult { unimplemented!() }