Some more type-checking work

This commit is contained in:
greg 2018-02-22 19:59:53 -08:00
parent 61795b0331
commit 23af2b1455

View File

@ -9,13 +9,14 @@ pub struct TypeContext {
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub enum Type { pub enum Type {
Unit,
Const(TConst), Const(TConst),
Func(Vec<Type>),
Void Void
} }
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub enum TConst { pub enum TConst {
Unit,
Int, Int,
Float, Float,
StringT, StringT,
@ -30,8 +31,8 @@ impl TypeContext {
TypeContext { bindings: HashMap::new() } TypeContext { bindings: HashMap::new() }
} }
pub fn type_check_ast(&mut self, ast: &parsing::AST) -> TypeResult<Type> { pub fn type_check_ast(&mut self, ast: &parsing::AST) -> TypeResult<Type> {
use self::Type::*; use self::Type::*; use self::TConst::*;
let mut ret_type = Unit; let mut ret_type = Const(Unit);
for statement in ast.0.iter() { for statement in ast.0.iter() {
ret_type = self.type_check_statement(statement)?; ret_type = self.type_check_statement(statement)?;
} }
@ -42,7 +43,7 @@ impl TypeContext {
use self::parsing::Statement::*; use self::parsing::Statement::*;
match statement { match statement {
&ExpressionStatement(ref expr) => self.type_infer(expr), &ExpressionStatement(ref expr) => self.infer(expr),
&Declaration(ref decl) => self.add_declaration(decl), &Declaration(ref decl) => self.add_declaration(decl),
} }
} }
@ -51,14 +52,14 @@ impl TypeContext {
use self::Type::*; use self::Type::*;
match decl { match decl {
&Binding { ref name, ref expr, .. } => { &Binding { ref name, ref expr, .. } => {
let ty = self.type_infer(expr)?; let ty = self.infer(expr)?;
self.bindings.insert(name.clone(), ty); self.bindings.insert(name.clone(), ty);
}, },
_ => return Err(format!("other formats not done")) _ => return Err(format!("other formats not done"))
} }
Ok(Void) Ok(Void)
} }
fn type_infer(&mut self, expr: &parsing::Expression) -> TypeResult<Type> { fn infer(&mut self, expr: &parsing::Expression) -> TypeResult<Type> {
use self::parsing::Expression; use self::parsing::Expression;
match expr { match expr {
&Expression(ref e, Some(ref anno)) => { &Expression(ref e, Some(ref anno)) => {
@ -77,9 +78,37 @@ impl TypeContext {
&FloatLiteral(_) => Ok(Const(Float)), &FloatLiteral(_) => Ok(Const(Float)),
&StringLiteral(_) => Ok(Const(StringT)), &StringLiteral(_) => Ok(Const(StringT)),
&BoolLiteral(_) => Ok(Const(Bool)), &BoolLiteral(_) => Ok(Const(Bool)),
&BinExp(ref op, ref lhs, ref rhs) => {
let _op_ty = self.infer_optype(op);
let _lhs_ty = self.infer(lhs);
let _rhs_ty = self.infer(rhs);
Ok(Const(Unit))
},
/*
BinExp(Operation, Box<Expression>, Box<Expression>),
PrefixExp(Operation, Box<Expression>),
TupleLiteral(Vec<Expression>),
Value(Rc<String>, Vec<(Rc<String>, Expression)>),
Call {
f: Box<Expression>,
arguments: Vec<Expression>,
},
Index {
indexee: Box<Expression>,
indexers: Vec<Expression>,
},
IfExpression(Box<Expression>, Vec<Statement>, Option<Vec<Statement>>),
MatchExpression(Box<Expression>, Vec<MatchArm>),
ForExpression
*/
_ => Err(format!("Type not yet implemented")) _ => Err(format!("Type not yet implemented"))
} }
} }
fn infer_optype(&mut self, _op: &parsing::Operation) -> TypeResult<Type> {
use self::Type::*; use self::TConst::*;
//this is a shim; not all ops are binops from int -> int -> int
Ok(Func(vec![Const(Int), Const(Int), Const(Int)]))
}
fn type_from_anno(&mut self, anno: &parsing::TypeName) -> TypeResult<Type> { fn type_from_anno(&mut self, anno: &parsing::TypeName) -> TypeResult<Type> {
use self::parsing::TypeSingletonName; use self::parsing::TypeSingletonName;
use self::parsing::TypeName::*; use self::parsing::TypeName::*;