Use ty! macro

This commit is contained in:
greg 2019-02-17 04:25:38 -08:00
parent 993741e67f
commit abbd02eaef

View File

@ -45,6 +45,12 @@ pub enum TypeConst {
UserDefined UserDefined
} }
macro_rules! ty {
($type_name:ident) => { Type::Const(TypeConst::$type_name) };
($t1:ident -> $t2:ident) => { Type::Arrow(Box::new(ty!($t1)), Box::new(ty!($t2))) };
($t1:ident -> $t2:ident -> $t3:ident) => { Type::Arrow(Box::new(ty!($t1)), Box::new(ty!($t2 -> $t3))) };
}
//TODO find a better way to capture the to/from string logic //TODO find a better way to capture the to/from string logic
impl Type { impl Type {
fn to_string(&self) -> String { fn to_string(&self) -> String {
@ -63,27 +69,19 @@ impl Type {
} }
fn from_string(string: &str) -> Option<Type> { fn from_string(string: &str) -> Option<Type> {
use self::Type::*;
use self::TypeConst::*;
Some(match string { Some(match string {
"()" | "Unit" => Const(Unit), "()" | "Unit" => ty!(Unit),
"Nat" => Const(Nat), "Nat" => ty!(Nat),
"Int" => Const(Int), "Int" => ty!(Int),
"Float" => Const(Float), "Float" => ty!(Float),
"String" => Const(StringT), "String" => ty!(StringT),
"Bool" => Const(Bool), "Bool" => ty!(Bool),
"Ordering" => Const(Ordering), "Ordering" => ty!(Ordering),
_ => return None _ => return None
}) })
} }
} }
macro_rules! ty {
($type_name:ident) => { Type::Const(TypeConst::$type_name) };
($t1:ident -> $t2:ident) => { Type::Arrow(Box::new(ty!($t1)), Box::new(ty!($t2))) };
($t1:ident -> $t2:ident -> $t3:ident) => { Type::Arrow(Box::new(ty!($t1)), Box::new(ty!($t2 -> $t3))) };
}
/* /*
/// `Type` is parameterized by whether the type variables can be just universal, or universal or /// `Type` is parameterized by whether the type variables can be just universal, or universal or
/// existential. /// existential.
@ -207,7 +205,7 @@ impl<'a> TypeContext<'a> {
} }
fn decl(&mut self, _decl: &Declaration) -> InferResult<Type> { fn decl(&mut self, _decl: &Declaration) -> InferResult<Type> {
Ok(Type::Const(TypeConst::Unit)) Ok(ty!(Unit))
} }
fn expr(&mut self, expr: &Expression) -> InferResult<Type> { fn expr(&mut self, expr: &Expression) -> InferResult<Type> {
@ -224,14 +222,14 @@ impl<'a> TypeContext<'a> {
fn expr_type(&mut self, expr: &ExpressionType) -> InferResult<Type> { fn expr_type(&mut self, expr: &ExpressionType) -> InferResult<Type> {
use self::ExpressionType::*; use self::ExpressionType::*;
Ok(match expr { Ok(match expr {
NatLiteral(_) => Type::Const(TypeConst::Nat), NatLiteral(_) => ty!(Nat),
BoolLiteral(_) => Type::Const(TypeConst::Bool), BoolLiteral(_) => ty!(Bool),
FloatLiteral(_) => Type::Const(TypeConst::Float), FloatLiteral(_) => ty!(Float),
StringLiteral(_) => Type::Const(TypeConst::StringT), StringLiteral(_) => ty!(StringT),
PrefixExp(op, expr) => self.prefix(op, expr.node())?, PrefixExp(op, expr) => self.prefix(op, expr.node())?,
IfExpression { discriminator, body } => self.if_expr(discriminator, body)?, IfExpression { discriminator, body } => self.if_expr(discriminator, body)?,
Value(val) => self.handle_value(val)?, Value(val) => self.handle_value(val)?,
_ => Type::Const(TypeConst::Unit) _ => ty!(Unit),
}) })
} }
@ -246,13 +244,13 @@ impl<'a> TypeContext<'a> {
} }
fn handle_apply(&mut self, f: Type, x: Type) -> InferResult<Type> { fn handle_apply(&mut self, f: Type, x: Type) -> InferResult<Type> {
Ok(Type::Const(TypeConst::Unit)) Ok(ty!(Unit))
} }
fn if_expr(&mut self, discriminator: &Discriminator, body: &IfExpressionBody) -> InferResult<Type> { fn if_expr(&mut self, discriminator: &Discriminator, body: &IfExpressionBody) -> InferResult<Type> {
//only handle simple case for now //only handle simple case for now
Ok(Type::Const(TypeConst::Unit)) Ok(ty!(Unit))
} }
fn handle_value(&mut self, val: &Rc<String>) -> InferResult<Type> { fn handle_value(&mut self, val: &Rc<String>) -> InferResult<Type> {