Get rid of typecheck_

This commit is contained in:
greg 2019-02-17 04:08:49 -08:00
parent fbb7b995b8
commit 993741e67f

View File

@ -194,55 +194,54 @@ impl<'a> TypeContext<'a> {
pub fn typecheck(&mut self, ast: &AST) -> Result<String, String> { pub fn typecheck(&mut self, ast: &AST) -> Result<String, String> {
let mut returned_type = Type::Const(TypeConst::Unit); let mut returned_type = Type::Const(TypeConst::Unit);
for statement in ast.0.iter() { for statement in ast.0.iter() {
returned_type = self.typecheck_statement(statement.node()).map_err(|err| { err.msg })? returned_type = self.statement(statement.node()).map_err(|err| { err.msg })?
} }
Ok(returned_type.to_string()) Ok(returned_type.to_string())
} }
fn typecheck_statement(&mut self, statement: &Statement) -> InferResult<Type> { fn statement(&mut self, statement: &Statement) -> InferResult<Type> {
match statement { match statement {
Statement::ExpressionStatement(e) => self.typecheck_expr(e.node()), Statement::ExpressionStatement(e) => self.expr(e.node()),
Statement::Declaration(decl) => self.typecheck_decl(decl), Statement::Declaration(decl) => self.decl(decl),
} }
} }
fn typecheck_decl(&mut self, _decl: &Declaration) -> InferResult<Type> { fn decl(&mut self, _decl: &Declaration) -> InferResult<Type> {
Ok(Type::Const(TypeConst::Unit)) Ok(Type::Const(TypeConst::Unit))
} }
fn typecheck_expr(&mut self, expr: &Expression) -> InferResult<Type> { fn expr(&mut self, expr: &Expression) -> InferResult<Type> {
match expr { match expr {
Expression(expr_type, Some(anno)) => { Expression(expr_type, Some(anno)) => {
let t1 = self.typecheck_expr_type(expr_type)?; let t1 = self.expr_type(expr_type)?;
let t2 = self.get_type_from_name(anno)?; let t2 = self.get_type_from_name(anno)?;
self.unify(t2, t1) self.unify(t2, t1)
}, },
Expression(expr_type, None) => self.typecheck_expr_type(expr_type) Expression(expr_type, None) => self.expr_type(expr_type)
} }
} }
fn typecheck_expr_type(&mut self, expr: &ExpressionType) -> InferResult<Type> { fn expr_type(&mut self, expr: &ExpressionType) -> InferResult<Type> {
use self::ExpressionType::*; use self::ExpressionType::*;
Ok(match expr { Ok(match expr {
NatLiteral(_) => Type::Const(TypeConst::Nat), NatLiteral(_) => Type::Const(TypeConst::Nat),
BoolLiteral(_) => Type::Const(TypeConst::Bool), BoolLiteral(_) => Type::Const(TypeConst::Bool),
FloatLiteral(_) => Type::Const(TypeConst::Float), FloatLiteral(_) => Type::Const(TypeConst::Float),
StringLiteral(_) => Type::Const(TypeConst::StringT), StringLiteral(_) => Type::Const(TypeConst::StringT),
PrefixExp(op, expr) => self.typecheck_prefix(op, expr.node())?, PrefixExp(op, expr) => self.prefix(op, expr.node())?,
IfExpression { discriminator, body } => self.typecheck_if_expr(discriminator, body)?, IfExpression { discriminator, body } => self.if_expr(discriminator, body)?,
Value(val) => self.handle_value(val)?, Value(val) => self.handle_value(val)?,
_ => Type::Const(TypeConst::Unit) _ => Type::Const(TypeConst::Unit)
}) })
} }
//TODO get rid of 'typecheck_' on all these methods - too wordy, already in typecontext fn prefix(&mut self, op: &PrefixOp, expr: &Expression) -> InferResult<Type> {
fn typecheck_prefix(&mut self, op: &PrefixOp, expr: &Expression) -> InferResult<Type> {
let f = match op.get_type() { let f = match op.get_type() {
Ok(ty) => ty, Ok(ty) => ty,
Err(e) => return TypeError::new("Couldn't find a type for this prefix op") Err(e) => return TypeError::new("Couldn't find a type for this prefix op")
}; };
let x = self.typecheck_expr(expr)?; let x = self.expr(expr)?;
self.handle_apply(f, x) self.handle_apply(f, x)
} }
@ -250,7 +249,7 @@ impl<'a> TypeContext<'a> {
Ok(Type::Const(TypeConst::Unit)) Ok(Type::Const(TypeConst::Unit))
} }
fn typecheck_if_expr(&mut self, discriminator: &Discriminator, body: &IfExpressionBody) -> InferResult<Type> { fn if_expr(&mut self, discriminator: &Discriminator, body: &IfExpressionBody) -> InferResult<Type> {
//only handle simple case for now //only handle simple case for now
Ok(Type::Const(TypeConst::Unit)) Ok(Type::Const(TypeConst::Unit))