Use UVars in type signatures of functions

This commit is contained in:
greg 2018-03-01 03:35:09 -08:00
parent ae2182db5d
commit 1a74e16af5

View File

@ -1,5 +1,6 @@
use std::rc::Rc; use std::rc::Rc;
use std::collections::HashMap; use std::collections::HashMap;
use std::char;
use schala_lang::parsing; use schala_lang::parsing;
@ -12,10 +13,27 @@ pub struct TypeContext {
pub enum Type { pub enum Type {
Const(TConst), Const(TConst),
Func(Box<Type>, Box<Type>), Func(Box<Type>, Box<Type>),
TVar(u64), UVar(String),
EVar(u64),
Void Void
} }
#[derive(Default)]
struct UVarGenerator {
n: u32,
}
impl UVarGenerator {
fn new() -> UVarGenerator {
UVarGenerator::default()
}
fn next(&mut self) -> Type {
//TODO handle this in the case where someone wants to make a function with more than 26 variables
let s = format!("{}", unsafe { char::from_u32_unchecked(self.n + ('a' as u32)) });
self.n += 1;
Type::UVar(s)
}
}
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub enum TConst { pub enum TConst {
Unit, Unit,
@ -55,7 +73,7 @@ impl TypeContext {
pub fn fresh(&mut self) -> Type { pub fn fresh(&mut self) -> Type {
let ret = self.type_var_count; let ret = self.type_var_count;
self.type_var_count += 1; self.type_var_count += 1;
Type::TVar(ret) Type::EVar(ret)
} }
} }
@ -68,11 +86,10 @@ impl TypeContext {
if let &self::parsing::Statement::Declaration(ref decl) = statement { if let &self::parsing::Statement::Declaration(ref decl) = statement {
match decl { match decl {
&FuncSig(ref signature) | &FuncDecl(ref signature, _) => { &FuncSig(ref signature) | &FuncDecl(ref signature, _) => {
//TODO this needs to be a type variable, not Void let mut uvar_gen = UVarGenerator::new();
let mut ty: Type = signature.type_anno.as_ref().map(|name: &TypeName| name.to_type()).unwrap_or(Ok(Void))?; let mut ty: Type = signature.type_anno.as_ref().map(|name: &TypeName| name.to_type()).unwrap_or_else(|| {Ok(uvar_gen.next())} )?;
for &(_, ref type_name) in signature.params.iter().rev() {
for &(_, ref type_name) in signature.params.iter() { let arg_type = type_name.as_ref().map(|name| name.to_type()).unwrap_or_else(|| {Ok(uvar_gen.next())} )?;
let arg_type = type_name.as_ref().map(|name| name.to_type()).unwrap_or(Ok(Void))?;
ty = Func(bx!(arg_type), bx!(ty)); ty = Func(bx!(arg_type), bx!(ty));
} }
self.bindings.insert(signature.name.clone(), ty); self.bindings.insert(signature.name.clone(), ty);