diff --git a/schala-lang/language/src/typechecking.rs b/schala-lang/language/src/typechecking.rs index f7e29ee..d9e6737 100644 --- a/schala-lang/language/src/typechecking.rs +++ b/schala-lang/language/src/typechecking.rs @@ -45,6 +45,12 @@ pub enum TypeConst { 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 impl Type { fn to_string(&self) -> String { @@ -63,27 +69,19 @@ impl Type { } fn from_string(string: &str) -> Option { - use self::Type::*; - use self::TypeConst::*; Some(match string { - "()" | "Unit" => Const(Unit), - "Nat" => Const(Nat), - "Int" => Const(Int), - "Float" => Const(Float), - "String" => Const(StringT), - "Bool" => Const(Bool), - "Ordering" => Const(Ordering), + "()" | "Unit" => ty!(Unit), + "Nat" => ty!(Nat), + "Int" => ty!(Int), + "Float" => ty!(Float), + "String" => ty!(StringT), + "Bool" => ty!(Bool), + "Ordering" => ty!(Ordering), _ => 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 /// existential. @@ -207,7 +205,7 @@ impl<'a> TypeContext<'a> { } fn decl(&mut self, _decl: &Declaration) -> InferResult { - Ok(Type::Const(TypeConst::Unit)) + Ok(ty!(Unit)) } fn expr(&mut self, expr: &Expression) -> InferResult { @@ -224,14 +222,14 @@ impl<'a> TypeContext<'a> { fn expr_type(&mut self, expr: &ExpressionType) -> InferResult { use self::ExpressionType::*; Ok(match expr { - NatLiteral(_) => Type::Const(TypeConst::Nat), - BoolLiteral(_) => Type::Const(TypeConst::Bool), - FloatLiteral(_) => Type::Const(TypeConst::Float), - StringLiteral(_) => Type::Const(TypeConst::StringT), + NatLiteral(_) => ty!(Nat), + BoolLiteral(_) => ty!(Bool), + FloatLiteral(_) => ty!(Float), + StringLiteral(_) => ty!(StringT), PrefixExp(op, expr) => self.prefix(op, expr.node())?, IfExpression { discriminator, body } => self.if_expr(discriminator, body)?, 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 { - Ok(Type::Const(TypeConst::Unit)) + Ok(ty!(Unit)) } fn if_expr(&mut self, discriminator: &Discriminator, body: &IfExpressionBody) -> InferResult { //only handle simple case for now - Ok(Type::Const(TypeConst::Unit)) + Ok(ty!(Unit)) } fn handle_value(&mut self, val: &Rc) -> InferResult {