Some more type work

This commit is contained in:
greg 2019-02-10 12:21:12 -08:00
parent 5e1799268d
commit 35da1748f0
2 changed files with 29 additions and 4 deletions

View File

@ -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<Type, String> {
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), ()),
};
}

View File

@ -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<String>;
@ -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<Type> {
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<Type> {
Ok(Type::Const(TypeConst::Unit))
}
fn typecheck_if_expr(&mut self, discriminator: &Discriminator, body: &IfExpressionBody) -> InferResult<Type> {
//only handle simple case for now
Ok(Type::Const(TypeConst::Unit))
}
fn unify(&mut self, t1: Type, t2: Type) -> InferResult<Type> {
use self::Type::*; use self::TypeConst::*;