aboutsummaryrefslogtreecommitdiff
path: root/src/type/display.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/type/display.rs')
-rw-r--r--src/type/display.rs85
1 files changed, 85 insertions, 0 deletions
diff --git a/src/type/display.rs b/src/type/display.rs
new file mode 100644
index 0000000..781d614
--- /dev/null
+++ b/src/type/display.rs
@@ -0,0 +1,85 @@
+
+use std::fmt;
+use crate::r#type::{Type, TypeError, Type::*, TypeError::*};
+
+
+impl fmt::Display for Type {
+ /// Formats the type for display to the programmer
+ /// using this programming language.
+ ///
+ /// Examples:
+ /// ```rust
+ /// use melisp::r#type::{Type::*, util::*};
+ /// assert_eq!(Integer.to_string(), "Int".to_string());
+ /// assert_eq!(arr(Integer, Integer).to_string(), "Int -> Int".to_string());
+ /// assert_eq!(List(vec![Integer, Integer, Integer]).to_string(), "(Int Int Int)".to_string());
+ /// ```
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ Integer => write!(f, "{}", "Int"),
+ Arrow(a, b) => write!(f, "{} -> {}", a, b),
+ List(types) => write!(
+ f,
+ "({})",
+ types.into_iter()
+ .map(|t| t.to_string())
+ .collect::<Vec<String>>()
+ .join(" ")
+ ),
+ UndefinedType => write!(f, "?"),
+ }
+ }
+}
+
+
+impl fmt::Display for TypeError {
+ /// Formats this type error for display to humans.
+ ///
+ /// Examples:
+ /// ```rust
+ /// use melisp::r#type::{TypeError::*, Type::*, util::*};
+ /// use melisp::sexp::{SExp, SExp::*, SLeaf::*, util::*};
+ ///
+ /// assert_eq!(
+ /// UndefinedVariable(String::from("x")).to_string(),
+ /// "undefined variable: 'x'".to_string()
+ /// );
+ /// assert_eq!(
+ /// InvalidOperator {
+ /// operator: Atom(Int(1)),
+ /// expected: arr(UndefinedType, UndefinedType),
+ /// found: Integer
+ /// }.to_string(),
+ /// "invalid operator: '1'\nexpected: '? -> ?'\nfound: 'Int'".to_string()
+ /// );
+ /// assert_eq!(
+ /// InvalidArgList {
+ /// arglist: scons(1, scons(2, scons(3, Nil))),
+ /// expected: List(vec![Integer, Integer]),
+ /// found: List(vec![Integer, Integer, Integer]),
+ /// }.to_string(),
+ /// "invalid argument list: '(1 2 3)'\nexpected: '(Int Int)'\nfound: '(Int Int Int)'".to_string()
+ /// );
+ /// ```
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ UndefinedVariable(name) => write!(f, "undefined variable: '{}'", name),
+ InvalidOperator { operator, expected, found } => {
+ write!(
+ f,
+ "invalid operator: '{}'\nexpected: '{}'\nfound: '{}'",
+ operator, expected, found
+ )
+ },
+ InvalidArgList { arglist, expected, found } => {
+ write!(
+ f,
+ "invalid argument list: '{}'\nexpected: '{}'\nfound: '{}'",
+ arglist, expected, found
+ )
+ },
+ OtherError => write!(f, "uncategorized error"),
+ }
+ }
+}
+