From 35da1748f049af4d8d99cd812f402ff1f451e7fd Mon Sep 17 00:00:00 2001 From: greg Date: Sun, 10 Feb 2019 12:21:12 -0800 Subject: [PATCH] Some more type work --- schala-lang/language/src/builtin.rs | 6 ++---- schala-lang/language/src/typechecking.rs | 27 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/schala-lang/language/src/builtin.rs b/schala-lang/language/src/builtin.rs index c150fe2..192f0cf 100644 --- a/schala-lang/language/src/builtin.rs +++ b/schala-lang/language/src/builtin.rs @@ -80,12 +80,10 @@ impl PrefixOp { pub fn is_prefix(op: &str) -> bool { PREFIX_OPS.get(op).is_some() } - /* pub fn get_type(&self) -> Result { let s = self.sigil.as_str(); PREFIX_OPS.get(s).map(|x| x.0.clone()).ok_or(format!("Prefix op {} not found", s)) } - */ } //TODO make this macro exportable? @@ -98,8 +96,8 @@ macro_rules! mk_type { lazy_static! { static ref PREFIX_OPS: HashMap<&'static str, (Type, ())> = hashmap! { - "+" => (mk_type!(Int -> Int), ()), - "-" => (mk_type!(Int -> Int), ()), + "+" => (mk_type!(Nat -> Int), ()), + "-" => (mk_type!(Nat -> Int), ()), "!" => (mk_type!(Bool -> Bool), ()), }; } diff --git a/schala-lang/language/src/typechecking.rs b/schala-lang/language/src/typechecking.rs index 8429060..e01db56 100644 --- a/schala-lang/language/src/typechecking.rs +++ b/schala-lang/language/src/typechecking.rs @@ -1,7 +1,12 @@ use std::rc::Rc; +//THINGS TODO +// look at the haskell compiler, see where in its flow the typechecking happens +// -nope, ghc deliberately does typechecking before desugaring to core +// cf. a history of haskell, peyton-jones use crate::ast::*; use crate::util::ScopeStack; +use crate::builtin::PrefixOp; pub type TypeName = Rc; @@ -218,10 +223,32 @@ impl<'a> TypeContext<'a> { BoolLiteral(_) => Type::Const(TypeConst::Bool), FloatLiteral(_) => Type::Const(TypeConst::Float), StringLiteral(_) => Type::Const(TypeConst::StringT), + PrefixExp(op, expr) => self.typecheck_prefix(op, expr.node())?, + IfExpression { discriminator, body } => self.typecheck_if_expr(discriminator, body)?, _ => Type::Const(TypeConst::Unit) }) } + //TODO get rid of 'typecheck_' on all these methods - too wordy, already in typecontext + fn typecheck_prefix(&mut self, op: &PrefixOp, expr: &Expression) -> InferResult { + let f = match op.get_type() { + Ok(ty) => ty, + Err(e) => return TypeError::new("Couldn't find a type for this prefix op") + }; + + let x = self.typecheck_expr(expr)?; + self.handle_apply(f, x) + } + + fn handle_apply(&mut self, f: Type, x: Type) -> InferResult { + Ok(Type::Const(TypeConst::Unit)) + } + + fn typecheck_if_expr(&mut self, discriminator: &Discriminator, body: &IfExpressionBody) -> InferResult { + //only handle simple case for now + + Ok(Type::Const(TypeConst::Unit)) + } fn unify(&mut self, t1: Type, t2: Type) -> InferResult { use self::Type::*; use self::TypeConst::*;