Paramaterize Type
This commit is contained in:
parent
ff0294c56e
commit
21132a369c
@ -6,7 +6,7 @@ use util::ScopeStack;
|
||||
pub type TypeName = Rc<String>;
|
||||
|
||||
pub struct TypeContext<'a> {
|
||||
variable_map: ScopeStack<'a, Rc<String>, MonoType>
|
||||
variable_map: ScopeStack<'a, Rc<String>, Type<()>>
|
||||
}
|
||||
|
||||
type InferResult<T> = Result<T, TypeError>;
|
||||
@ -21,24 +21,24 @@ impl TypeError {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum MonoType {
|
||||
Var(Rc<String>),
|
||||
enum Type<a> {
|
||||
Var(a),
|
||||
Const(TConst),
|
||||
Arrow(Box<MonoType>, Box<MonoType>),
|
||||
Arrow(Box<Type<a>>, Box<Type<a>>),
|
||||
ExistentialVar(u32)
|
||||
}
|
||||
|
||||
impl TypeIdentifier {
|
||||
fn to_monotype(&self) -> MonoType {
|
||||
fn to_monotype(&self) -> Type<()> {
|
||||
match self {
|
||||
TypeIdentifier::Tuple(items) => unimplemented!(),
|
||||
TypeIdentifier::Singleton(TypeSingletonName { name, .. }) => {
|
||||
match &name[..] {
|
||||
"Nat" => MonoType::Const(TConst::Nat),
|
||||
"Int" => MonoType::Const(TConst::Int),
|
||||
"Float" => MonoType::Const(TConst::Float),
|
||||
"Bool" => MonoType::Const(TConst::Bool),
|
||||
"String" => MonoType::Const(TConst::StringT),
|
||||
"Nat" => Type::Const(TConst::Nat),
|
||||
"Int" => Type::Const(TConst::Int),
|
||||
"Float" => Type::Const(TConst::Float),
|
||||
"Bool" => Type::Const(TConst::Bool),
|
||||
"String" => Type::Const(TConst::StringT),
|
||||
_ => unimplemented!()
|
||||
}
|
||||
}
|
||||
@ -66,7 +66,7 @@ impl TConst {
|
||||
#[derive(Debug, Clone)]
|
||||
struct PolyType {
|
||||
vars: Vec<Rc<String>>,
|
||||
ty: MonoType
|
||||
ty: Type<()>
|
||||
}
|
||||
|
||||
impl<'a> TypeContext<'a> {
|
||||
@ -85,22 +85,22 @@ impl<'a> TypeContext<'a> {
|
||||
}
|
||||
|
||||
impl<'a> TypeContext<'a> {
|
||||
fn infer_ast(&mut self, ast: &AST) -> InferResult<MonoType> {
|
||||
let mut output = MonoType::Const(TConst::Unit);
|
||||
fn infer_ast(&mut self, ast: &AST) -> InferResult<Type<()>> {
|
||||
let mut output = Type::Const(TConst::Unit);
|
||||
for statement in ast.0.iter() {
|
||||
output = self.infer_statement(statement)?;
|
||||
}
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
fn infer_statement(&mut self, stmt: &Statement) -> InferResult<MonoType> {
|
||||
fn infer_statement(&mut self, stmt: &Statement) -> InferResult<Type<()>> {
|
||||
match stmt {
|
||||
Statement::ExpressionStatement(ref expr) => self.infer_expr(expr),
|
||||
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 {
|
||||
Expression(expr_type, Some(type_anno)) => {
|
||||
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> {
|
||||
Ok(MonoType::Const(TConst::user("unimplemented")))
|
||||
fn infer_decl(&mut self, expr: &Declaration) -> InferResult<Type<()>> {
|
||||
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::*;
|
||||
Ok(match expr_type {
|
||||
NatLiteral(_) => MonoType::Const(TConst::Nat),
|
||||
FloatLiteral(_) => MonoType::Const(TConst::Float),
|
||||
StringLiteral(_) => MonoType::Const(TConst::StringT),
|
||||
BoolLiteral(_) => MonoType::Const(TConst::Bool),
|
||||
NatLiteral(_) => Type::Const(TConst::Nat),
|
||||
FloatLiteral(_) => Type::Const(TConst::Float),
|
||||
StringLiteral(_) => Type::Const(TConst::StringT),
|
||||
BoolLiteral(_) => Type::Const(TConst::Bool),
|
||||
Value(name) => {
|
||||
//TODO handle the distinction between 0-arg constructors and variables at some point
|
||||
// need symbol table for that
|
||||
@ -132,10 +132,10 @@ impl<'a> TypeContext<'a> {
|
||||
},
|
||||
IfExpression { discriminator, body } => self.infer_if_expr(discriminator, body)?,
|
||||
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
|
||||
match tf {
|
||||
MonoType::Arrow(t1, t2) => {
|
||||
Type::Arrow(t1, t2) => {
|
||||
self.unify(&t1, &targ)?;
|
||||
*t2.clone()
|
||||
},
|
||||
@ -148,13 +148,13 @@ impl<'a> TypeContext<'a> {
|
||||
let arg_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 {
|
||||
Discriminator::Simple(expr) => expr,
|
||||
_ => return TypeError::new("Dame desu")
|
||||
@ -168,20 +168,20 @@ impl<'a> TypeContext<'a> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn infer_block(&mut self, block: &Block) -> InferResult<MonoType> {
|
||||
let mut output = MonoType::Const(TConst::Unit);
|
||||
fn infer_block(&mut self, block: &Block) -> InferResult<Type<()>> {
|
||||
let mut output = Type::Const(TConst::Unit);
|
||||
for statement in block.iter() {
|
||||
output = self.infer_statement(statement)?;
|
||||
}
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
fn unify(&mut self, t1: &MonoType, t2: &MonoType) -> InferResult<MonoType> {
|
||||
fn unify(&mut self, t1: &Type<()>, t2: &Type<()>) -> InferResult<Type<()>> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn allocate_existential(&mut self) -> MonoType {
|
||||
MonoType::ExistentialVar(0)
|
||||
fn allocate_existential(&mut self) -> Type<()> {
|
||||
Type::ExistentialVar(0)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user