1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
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 myslip::r#type::{Type::*, util::*};
/// assert_eq!(Integer.to_string(), "Int".to_string());
/// assert_eq!(Boolean.to_string(), "Bool".to_string());
/// assert_eq!(arr(Integer, Boolean).to_string(), "(Int -> Bool)".to_string());
/// assert_eq!(List(vec![Integer, Boolean, Integer]).to_string(), "(Int Bool Int)".to_string());
/// ```
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Integer => write!(f, "{}", "Int"),
Boolean => write!(f, "{}", "Bool"),
QuoteTy => write!(f, "{}", "Quote"),
VecType => write!(f, "{}", "Vector"),
LetType => write!(f, "{}", "Let"),
VecOf(ty) => write!(f, "({} ... {})", *ty, *ty),
Arrow(a, b) => write!(f, "({} -> {})", a, b),
List(types) => write!(
f,
"({})",
types.into_iter()
.map(|t| t.to_string())
.collect::<Vec<String>>()
.join(" ")
),
VarType(name) => write!(f, "{}", name),
}
}
}
impl fmt::Display for TypeError {
/// Formats this type error for display to humans.
///
/// Examples:
/// ```rust
/// use myslip::r#type::{TypeError::*, Type::*, util::*};
/// use myslip::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(VarType("?".to_string()), VarType("?".to_string())),
/// 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()
/// );
/// assert_eq!(
/// UnboundGeneric(String::from("?")).to_string(),
/// "unbound generic type: '?'".to_string()
/// );
/// assert_eq!(
/// ArgumentsDontMatchGeneric {
/// argtype: Integer,
/// generictype: arr(VarType("T".to_string()), Integer)
/// }.to_string(),
/// "incompatible argument type 'Int' and generic operator type '(T -> Int)'".to_string()
/// );
/// ```
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
UndefinedVariable(name) => write!(f, "undefined variable: '{}'", name),
UnboundGeneric(name) => write!(f, "unbound generic type: '{}'", 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
)
},
ArgumentsDontMatchGeneric { argtype, generictype } => {
write!(
f,
"incompatible argument type '{}' and generic operator type '{}'",
argtype, generictype
)
},
OtherError => write!(f, "uncategorized error"),
}
}
}
|