Paramaterize Type

This commit is contained in:
greg 2018-11-09 02:05:59 -08:00
parent ff0294c56e
commit 21132a369c

View File

@ -6,7 +6,7 @@ use util::ScopeStack;
pub type TypeName = Rc<String>; pub type TypeName = Rc<String>;
pub struct TypeContext<'a> { pub struct TypeContext<'a> {
variable_map: ScopeStack<'a, Rc<String>, MonoType> variable_map: ScopeStack<'a, Rc<String>, Type<()>>
} }
type InferResult<T> = Result<T, TypeError>; type InferResult<T> = Result<T, TypeError>;
@ -21,24 +21,24 @@ impl TypeError {
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
enum MonoType { enum Type<a> {
Var(Rc<String>), Var(a),
Const(TConst), Const(TConst),
Arrow(Box<MonoType>, Box<MonoType>), Arrow(Box<Type<a>>, Box<Type<a>>),
ExistentialVar(u32) ExistentialVar(u32)
} }
impl TypeIdentifier { impl TypeIdentifier {
fn to_monotype(&self) -> MonoType { fn to_monotype(&self) -> Type<()> {
match self { match self {
TypeIdentifier::Tuple(items) => unimplemented!(), TypeIdentifier::Tuple(items) => unimplemented!(),
TypeIdentifier::Singleton(TypeSingletonName { name, .. }) => { TypeIdentifier::Singleton(TypeSingletonName { name, .. }) => {
match &name[..] { match &name[..] {
"Nat" => MonoType::Const(TConst::Nat), "Nat" => Type::Const(TConst::Nat),
"Int" => MonoType::Const(TConst::Int), "Int" => Type::Const(TConst::Int),
"Float" => MonoType::Const(TConst::Float), "Float" => Type::Const(TConst::Float),
"Bool" => MonoType::Const(TConst::Bool), "Bool" => Type::Const(TConst::Bool),
"String" => MonoType::Const(TConst::StringT), "String" => Type::Const(TConst::StringT),
_ => unimplemented!() _ => unimplemented!()
} }
} }
@ -66,7 +66,7 @@ impl TConst {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
struct PolyType { struct PolyType {
vars: Vec<Rc<String>>, vars: Vec<Rc<String>>,
ty: MonoType ty: Type<()>
} }
impl<'a> TypeContext<'a> { impl<'a> TypeContext<'a> {
@ -85,22 +85,22 @@ impl<'a> TypeContext<'a> {
} }
impl<'a> TypeContext<'a> { impl<'a> TypeContext<'a> {
fn infer_ast(&mut self, ast: &AST) -> InferResult<MonoType> { fn infer_ast(&mut self, ast: &AST) -> InferResult<Type<()>> {
let mut output = MonoType::Const(TConst::Unit); let mut output = Type::Const(TConst::Unit);
for statement in ast.0.iter() { for statement in ast.0.iter() {
output = self.infer_statement(statement)?; output = self.infer_statement(statement)?;
} }
Ok(output) Ok(output)
} }
fn infer_statement(&mut self, stmt: &Statement) -> InferResult<MonoType> { fn infer_statement(&mut self, stmt: &Statement) -> InferResult<Type<()>> {
match stmt { match stmt {
Statement::ExpressionStatement(ref expr) => self.infer_expr(expr), Statement::ExpressionStatement(ref expr) => self.infer_expr(expr),
Statement::Declaration(ref decl) => self.infer_decl(decl), Statement::Declaration(ref decl) => self.infer_decl(decl),
} }
} }
fn infer_expr(&mut self, expr: &Expression) -> InferResult<MonoType> { fn infer_expr(&mut self, expr: &Expression) -> InferResult<Type<()>> {
match expr { match expr {
Expression(expr_type, Some(type_anno)) => { Expression(expr_type, Some(type_anno)) => {
let tx = self.infer_expr_type(expr_type)?; let tx = self.infer_expr_type(expr_type)?;
@ -111,17 +111,17 @@ impl<'a> TypeContext<'a> {
} }
} }
fn infer_decl(&mut self, expr: &Declaration) -> InferResult<MonoType> { fn infer_decl(&mut self, expr: &Declaration) -> InferResult<Type<()>> {
Ok(MonoType::Const(TConst::user("unimplemented"))) Ok(Type::Const(TConst::user("unimplemented")))
} }
fn infer_expr_type(&mut self, expr_type: &ExpressionType) -> InferResult<MonoType> { fn infer_expr_type(&mut self, expr_type: &ExpressionType) -> InferResult<Type<()>> {
use self::ExpressionType::*; use self::ExpressionType::*;
Ok(match expr_type { Ok(match expr_type {
NatLiteral(_) => MonoType::Const(TConst::Nat), NatLiteral(_) => Type::Const(TConst::Nat),
FloatLiteral(_) => MonoType::Const(TConst::Float), FloatLiteral(_) => Type::Const(TConst::Float),
StringLiteral(_) => MonoType::Const(TConst::StringT), StringLiteral(_) => Type::Const(TConst::StringT),
BoolLiteral(_) => MonoType::Const(TConst::Bool), BoolLiteral(_) => Type::Const(TConst::Bool),
Value(name) => { Value(name) => {
//TODO handle the distinction between 0-arg constructors and variables at some point //TODO handle the distinction between 0-arg constructors and variables at some point
// need symbol table for that // need symbol table for that
@ -132,10 +132,10 @@ impl<'a> TypeContext<'a> {
}, },
IfExpression { discriminator, body } => self.infer_if_expr(discriminator, body)?, IfExpression { discriminator, body } => self.infer_if_expr(discriminator, body)?,
Call { f, arguments } => { Call { f, arguments } => {
let tf: MonoType = self.infer_expr(f)?; //has to be an Arrow MonoType let tf: Type<()> = self.infer_expr(f)?; //has to be an Arrow Type
let targ = self.infer_expr(&arguments[0])?; // TODO make this work with functions with more than one arg let targ = self.infer_expr(&arguments[0])?; // TODO make this work with functions with more than one arg
match tf { match tf {
MonoType::Arrow(t1, t2) => { Type::Arrow(t1, t2) => {
self.unify(&t1, &targ)?; self.unify(&t1, &targ)?;
*t2.clone() *t2.clone()
}, },
@ -148,13 +148,13 @@ impl<'a> TypeContext<'a> {
let arg_type = unimplemented!(); let arg_type = unimplemented!();
let result_type = unimplemented!(); let result_type = unimplemented!();
MonoType::Arrow(Box::new(arg_type), Box::new(result_type)) Type::Arrow(Box::new(arg_type), Box::new(result_type))
} }
_ => MonoType::Const(TConst::user("unimplemented")) _ => Type::Const(TConst::user("unimplemented"))
}) })
} }
fn infer_if_expr(&mut self, discriminator: &Discriminator, body: &IfExpressionBody) -> InferResult<MonoType> { fn infer_if_expr(&mut self, discriminator: &Discriminator, body: &IfExpressionBody) -> InferResult<Type<()>> {
let test = match discriminator { let test = match discriminator {
Discriminator::Simple(expr) => expr, Discriminator::Simple(expr) => expr,
_ => return TypeError::new("Dame desu") _ => return TypeError::new("Dame desu")
@ -168,20 +168,20 @@ impl<'a> TypeContext<'a> {
unimplemented!() unimplemented!()
} }
fn infer_block(&mut self, block: &Block) -> InferResult<MonoType> { fn infer_block(&mut self, block: &Block) -> InferResult<Type<()>> {
let mut output = MonoType::Const(TConst::Unit); let mut output = Type::Const(TConst::Unit);
for statement in block.iter() { for statement in block.iter() {
output = self.infer_statement(statement)?; output = self.infer_statement(statement)?;
} }
Ok(output) Ok(output)
} }
fn unify(&mut self, t1: &MonoType, t2: &MonoType) -> InferResult<MonoType> { fn unify(&mut self, t1: &Type<()>, t2: &Type<()>) -> InferResult<Type<()>> {
unimplemented!() unimplemented!()
} }
fn allocate_existential(&mut self) -> MonoType { fn allocate_existential(&mut self) -> Type<()> {
MonoType::ExistentialVar(0) Type::ExistentialVar(0)
} }
} }