Skip to content

Commit

Permalink
Rename (*) to Type
Browse files Browse the repository at this point in the history
Closes #70
  • Loading branch information
brendanzab committed Jul 25, 2016
1 parent 15b6ad5 commit 8a3e194
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 55 deletions.
24 changes: 14 additions & 10 deletions base/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -331,28 +331,30 @@ impl BuiltinType {

/// Kind representation
///
/// All types in gluon has a kind. Most types encountered are of the `Star` (*) kind which
/// All types in gluon has a kind. Most types encountered are of the `Type` kind which
/// includes things like `Int`, `String` and `Option Int`. There are however other types which
/// are said to be "higher kinded" and these use the `Function` (a -> b) variant.
/// These types include `Option` and `->` which both have the kind `* -> *` as well as `Functor`
/// which has the kind `(* -> *) -> *`.
/// These types include `Option` and `(->)` which both have the kind `Type -> Type` as well as
/// `Functor` which has the kind `(Type -> Type) -> Type`.
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub enum Kind {
/// Representation for a kind which is yet to be infered
/// Representation for a kind which is yet to be inferred.
Variable(u32),
/// The simplest possible kind. All values in a program have this kind.
Star,
/// Constructor which takes two kinds, taking the first as argument and returning the second
Type,
/// Constructor which takes two kinds, taking the first as argument and returning the second.
Function(RcKind, RcKind),
}

impl Kind {
pub fn variable(v: u32) -> RcKind {
RcKind::new(Kind::Variable(v))
}
pub fn star() -> RcKind {
RcKind::new(Kind::Star)

pub fn typ() -> RcKind {
RcKind::new(Kind::Type)
}

pub fn function(l: RcKind, r: RcKind) -> RcKind {
RcKind::new(Kind::Function(l, r))
}
Expand Down Expand Up @@ -658,8 +660,9 @@ impl<Id> ASTType<Id> {

impl TypeVariable {
pub fn new(var: u32) -> TypeVariable {
TypeVariable::with_kind(Kind::Star, var)
TypeVariable::with_kind(Kind::Type, var)
}

pub fn with_kind(kind: Kind, var: u32) -> TypeVariable {
TypeVariable {
kind: RcKind::new(kind),
Expand All @@ -675,11 +678,12 @@ impl fmt::Display for Kind {
write!(f, "{}", DisplayKind(Prec::Top, self))
}
}

impl<'a> fmt::Display for DisplayKind<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self.1 {
Kind::Variable(i) => i.fmt(f),
Kind::Star => '*'.fmt(f),
Kind::Type => "Type".fmt(f),
Kind::Function(ref arg, ref ret) => {
match self.0 {
Prec::Function => {
Expand Down
16 changes: 8 additions & 8 deletions base/tests/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ fn type_con<I, T>(s: I, args: Vec<T>) -> Type<I, T>
Ok(b) => Type::Builtin(b),
Err(()) if is_var => {
Type::Generic(Generic {
kind: RcKind::new(Kind::Star),
kind: RcKind::new(Kind::Type),
id: s,
})
}
Expand Down Expand Up @@ -56,7 +56,7 @@ fn show_record() {
typ: Alias::new(
"Test",
vec![Generic {
kind: Kind::star(),
kind: Kind::typ(),
id: "a",
}],
f.clone(),
Expand All @@ -72,7 +72,7 @@ fn show_record() {
typ: Alias::new(
"Test",
vec![Generic {
kind: Kind::star(),
kind: Kind::typ(),
id: "a",
}],
f.clone(),
Expand All @@ -93,7 +93,7 @@ fn show_record() {
typ: Alias::new(
"Test",
vec![Generic {
kind: Kind::star(),
kind: Kind::typ(),
id: "a",
}],
f.clone(),
Expand All @@ -112,8 +112,8 @@ fn variants() {

#[test]
fn show_kind() {
let two_args = Kind::function(Kind::star(), Kind::function(Kind::star(), Kind::star()));
assert_eq!(format!("{}", two_args), "* -> * -> *");
let function_arg = Kind::function(Kind::function(Kind::star(), Kind::star()), Kind::star());
assert_eq!(format!("{}", function_arg), "(* -> *) -> *");
let two_args = Kind::function(Kind::typ(), Kind::function(Kind::typ(), Kind::typ()));
assert_eq!(format!("{}", two_args), "Type -> Type -> Type");
let function_arg = Kind::function(Kind::function(Kind::typ(), Kind::typ()), Kind::typ());
assert_eq!(format!("{}", function_arg), "(Type -> Type) -> Type");
}
48 changes: 24 additions & 24 deletions check/src/kindcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ pub struct KindCheck<'a> {
info: &'a (KindEnv + 'a),
idents: &'a (ast::IdentEnv<Ident = Symbol> + 'a),
pub subs: Substitution<RcKind>,
/// A cached star kind, `*`
star_kind: RcKind,
/// A cached one argument kind function, `* -> *`
/// A cached type kind, `Type`
type_kind: RcKind,
/// A cached one argument kind function, `Type -> Type`
function1_kind: RcKind,
/// A cached two argument kind function, `* -> * -> *`
/// A cached two argument kind function, `Type -> Type -> Type`
function2_kind: RcKind,
}

Expand All @@ -56,7 +56,7 @@ fn walk_move_kind2<F>(kind: &RcKind, f: &mut F) -> Option<RcKind>
(None, None) => None,
}
}
Kind::Star |
Kind::Type |
Kind::Variable(_) => None,
}
};
Expand All @@ -68,16 +68,16 @@ impl<'a> KindCheck<'a> {
idents: &'a (ast::IdentEnv<Ident = Symbol> + 'a),
subs: Substitution<RcKind>)
-> KindCheck<'a> {
let star = Kind::star();
let typ = Kind::typ();
KindCheck {
variables: Vec::new(),
locals: Vec::new(),
info: info,
idents: idents,
subs: subs,
star_kind: star.clone(),
function1_kind: Kind::function(star.clone(), star.clone()),
function2_kind: Kind::function(star.clone(), Kind::function(star.clone(), star)),
type_kind: typ.clone(),
function1_kind: Kind::function(typ.clone(), typ.clone()),
function2_kind: Kind::function(typ.clone(), Kind::function(typ.clone(), typ)),
}
}

Expand All @@ -90,8 +90,8 @@ impl<'a> KindCheck<'a> {
self.variables.extend(variables.iter().cloned());
}

pub fn star_kind(&self) -> RcKind {
self.star_kind.clone()
pub fn type_kind(&self) -> RcKind {
self.type_kind.clone()
}

pub fn function1_kind(&self) -> RcKind {
Expand Down Expand Up @@ -133,12 +133,12 @@ impl<'a> KindCheck<'a> {
kind
}

// Kindhecks `typ`, infering it to be of kind `*`
// Kindhecks `typ`, infering it to be of kind `Type`
pub fn kindcheck_type(&mut self, typ: &mut TcType) -> Result<RcKind> {
debug!("Kindcheck {:?}", typ);
let (kind, t) = try!(self.kindcheck(typ));
let star = self.star_kind();
let kind = try!(self.unify(&star, kind));
let type_kind = self.type_kind();
let kind = try!(self.unify(&type_kind, kind));
*typ = self.finalize_type(t);
debug!("Done {:?}", typ);
Ok(kind)
Expand All @@ -151,7 +151,7 @@ impl<'a> KindCheck<'a> {
BuiltinType::Char |
BuiltinType::Int |
BuiltinType::Float |
BuiltinType::Unit => self.star_kind(),
BuiltinType::Unit => self.type_kind(),
BuiltinType::Array => self.function1_kind(),
BuiltinType::Function => self.function2_kind(),
}
Expand Down Expand Up @@ -191,26 +191,26 @@ impl<'a> KindCheck<'a> {
let variants = try!(variants.iter()
.map(|variant| {
let (kind, typ) = try!(self.kindcheck(&variant.1));
let star = self.star_kind();
try!(self.unify(&star, kind));
let type_kind = self.type_kind();
try!(self.unify(&type_kind, kind));
Ok((variant.0.clone(), typ))
})
.collect());
Ok((self.star_kind(), Type::variants(variants)))
Ok((self.type_kind(), Type::variants(variants)))
}
Type::Record { ref types, ref fields } => {
let fields = try!(fields.iter()
.map(|field| {
let (kind, typ) = try!(self.kindcheck(&field.typ));
let star = self.star_kind();
try!(self.unify(&star, kind));
let type_kind = self.type_kind();
try!(self.unify(&type_kind, kind));
Ok(types::Field {
name: field.name.clone(),
typ: typ,
})
})
.collect());
Ok((self.star_kind(), Type::record(types.clone(), fields)))
Ok((self.type_kind(), Type::record(types.clone(), fields)))
}
Type::Id(ref id) => self.find(id).map(|kind| (kind, typ.clone())),
Type::Alias(ref alias) => self.find(&alias.name).map(|kind| (kind, typ.clone())),
Expand All @@ -232,7 +232,7 @@ impl<'a> KindCheck<'a> {
}

pub fn finalize_type(&self, typ: TcType) -> TcType {
let default = Some(&self.star_kind);
let default = Some(&self.type_kind);
types::walk_move_type(typ,
&mut |typ| {
match *typ {
Expand All @@ -251,7 +251,7 @@ impl<'a> KindCheck<'a> {
}
pub fn finalize_generic(&self, var: &Generic<Symbol>) -> Generic<Symbol> {
let mut kind = var.kind.clone();
kind = update_kind(&self.subs, kind, Some(&self.star_kind));
kind = update_kind(&self.subs, kind, Some(&self.type_kind));
types::Generic {
id: var.id.clone(),
kind: kind,
Expand Down Expand Up @@ -321,7 +321,7 @@ impl Substitutable for RcKind {
walk_kind(r, f);
}
Kind::Variable(_) |
Kind::Star => (),
Kind::Type => (),
}
}
walk_kind(self, &mut f)
Expand Down
6 changes: 3 additions & 3 deletions check/src/typecheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ impl<'a> KindEnv for Environment<'a> {
self.stack_types
.get(type_name)
.map(|&(_, ref alias)| {
let mut kind = Kind::star();
let mut kind = Kind::typ();
for arg in alias.args.iter().rev() {
kind = Kind::function(arg.kind.clone(), kind);
}
Expand Down Expand Up @@ -720,10 +720,10 @@ impl<'a> Typecheck<'a> {
// this type expression into the kindcheck environment
for bind in bindings.iter_mut() {
// Create the kind for this binding
// Test a b: 2 -> 1 -> *
// Test a b: 2 -> 1 -> Type
// and bind the same variables to the arguments of the type binding
// ('a' and 'b' in the example)
let mut id_kind = check.star_kind();
let mut id_kind = check.type_kind();
let alias = Alias::make_mut(&mut bind.alias);
for gen in alias.args.iter_mut().rev() {
gen.kind = check.subs.new_var();
Expand Down
6 changes: 3 additions & 3 deletions check/tests/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ struct EmptyEnv(Alias<Symbol, TcType>);
impl KindEnv for EmptyEnv {
fn find_kind(&self, id: &SymbolRef) -> Option<RcKind> {
match id.as_ref() {
"Bool" => Some(Kind::star()),
"Bool" => Some(Kind::typ()),
_ => None,
}
}
Expand Down Expand Up @@ -129,7 +129,7 @@ pub fn typ_a<T>(s: &str, args: Vec<T>) -> T
Ok(b) => Type::builtin(b),
Err(()) if is_var => {
Type::generic(Generic {
kind: Kind::star(),
kind: Kind::typ(),
id: intern(s),
})
}
Expand All @@ -150,7 +150,7 @@ pub fn alias(s: &str, args: &[&str], typ: TcType) -> TcType {
args.iter()
.map(|id| {
Generic {
kind: Kind::star(),
kind: Kind::typ(),
id: intern(id),
}
})
Expand Down
4 changes: 2 additions & 2 deletions check/tests/pass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,15 +448,15 @@ return 1
Type::variants(vec![(intern(name), Type::function(vec![typ("a")], Type::app(typ(name), vec![typ("a")])))]);
let test = alias("Test", &["a"], variant("Test"));
let m = Generic {
kind: Kind::function(Kind::star(), Kind::star()),
kind: Kind::function(Kind::typ(), Kind::typ()),
id: intern("m"),
};

let id = alias("Id", &["a"], variant("Id"));
let id_t = Type::alias(intern("IdT"), vec![
m.clone(),
Generic {
kind: Kind::star(),
kind: Kind::typ(),
id: intern("a"),
}], Type::app(Type::generic(m), vec![Type::app(id, vec![typ("a")])]));
assert_eq!(result, Ok(Type::app(id_t, vec![test, typ("Int")])));
Expand Down
2 changes: 1 addition & 1 deletion parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -761,7 +761,7 @@ pub fn parse_tc
let mut env = ast::TcIdentEnv {
typ: Type::variable(TypeVariable {
id: 0,
kind: Kind::star(),
kind: Kind::typ(),
}),
env: symbols,
};
Expand Down
4 changes: 2 additions & 2 deletions src/repl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ fn find_kind(args: WithVM<RootStr>) -> IO<Result<String, String>> {
let args = args.value.trim();
IO::Value(match vm.find_type_info(args) {
Ok(ref alias) => {
let kind = alias.args.iter().rev().fold(Kind::star(), |acc, arg| {
let kind = alias.args.iter().rev().fold(Kind::typ(), |acc, arg| {
Kind::function(arg.kind.clone(), acc)
});
Ok(format!("{}", kind))
Expand Down Expand Up @@ -183,7 +183,7 @@ mod tests {
compile_repl(&vm).unwrap_or_else(|err| panic!("{}", err));
let mut find_kind: FunctionRef<QueryFn> = vm.get_global("repl_prim.find_kind").unwrap();
assert_eq!(find_kind.call("std.prelude.Option"),
Ok(IO::Value(Ok("* -> *".into()))));
Ok(IO::Value(Ok("Type -> Type".into()))));
}

#[test]
Expand Down
2 changes: 1 addition & 1 deletion vm/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ impl KindEnv for TypeInfos {
self.id_to_type
.get(type_name)
.map(|alias| {
alias.args.iter().rev().fold(types::Kind::star(), |acc, arg| {
alias.args.iter().rev().fold(types::Kind::typ(), |acc, arg| {
types::Kind::function(arg.kind.clone(), acc)
})
})
Expand Down
2 changes: 1 addition & 1 deletion vm/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ impl GlobalVMState {
}
let g: TcType = Type::generic(types::Generic {
id: Symbol::new(name),
kind: types::Kind::star(),
kind: types::Kind::typ(),
});
generics.insert(name.into(), g.clone());
g
Expand Down

0 comments on commit 8a3e194

Please sign in to comment.