1use error::ScanError;
2use int::Int;
3
4#[derive(Debug)]
6#[derive(PartialEq)]
7pub enum Token {
8 Num(f64),
10 Int(i64),
12 Str(String),
14 Iden(String),
16 Char(char),
18 Error(ScanError),
20 End
22}
23
24fn type_error<T>(t: Token, expected: &str) -> Result<T,ScanError> {
25 Err(ScanError{details: format!("{} expected, got {:?}",expected,t), lineno: 1})
26}
27
28fn int_error<T>(msg: &str, tname: &str) -> Result<T,ScanError> {
29 Err(ScanError{details: format!("integer {} for {}",msg,tname), lineno: 1})
30}
31
32impl Token {
33 pub fn finished(&self) -> bool {
35 match *self {
36 Token::End => true,
37 _ => false
38 }
39 }
40
41 pub fn is_float(&self) -> bool {
43 match *self {
44 Token::Num(_) => true,
45 _ => false
46 }
47 }
48
49 pub fn to_float(self) -> Option<f64> {
51 match self {
52 Token::Num(n) => Some(n),
53 _ => None
54 }
55 }
56
57 pub fn to_float_result(self) -> Result<f64,ScanError> {
59 match self {
60 Token::Num(n) => Ok(n),
61 t => type_error(t,"float")
62 }
63 }
64
65 pub fn is_integer(&self) -> bool {
67 match *self {
68 Token::Int(_) => true,
69 _ => false
70 }
71 }
72
73 pub fn to_integer(self) -> Option<i64> {
75 match self {
76 Token::Int(n) => Some(n),
77 _ => None
78 }
79 }
80
81 pub fn to_integer_result(self) -> Result<i64,ScanError> {
83 match self {
84 Token::Int(n) => Ok(n),
85 t => type_error(t,"integer")
86 }
87 }
88
89 pub fn to_int_result<I: Int>(self) -> Result<I::Type,ScanError> {
91 let num = self.to_integer_result()?;
92 if num < I::min_value() {
93 return int_error("underflow",I::name());
94 } else
95 if num > I::max_value() {
96 return int_error("overflow",I::name());
97 }
98 Ok(I::cast(num))
99 }
100
101 pub fn is_number(&self) -> bool {
103 match *self {
104 Token::Int(_) | Token::Num(_) => true,
105 _ => false
106 }
107 }
108
109 pub fn to_number(self) -> Option<f64> {
111 match self {
112 Token::Num(n) => Some(n),
113 Token::Int(n) => Some(n as f64),
114 _ => None
115 }
116 }
117
118 pub fn to_number_result(self) -> Result<f64,ScanError> {
120 match self {
121 Token::Num(n) => Ok(n),
122 Token::Int(n) => Ok(n as f64),
123 t => type_error(t,"number")
124 }
125 }
126
127 pub fn is_string(&self) -> bool {
129 match *self {
130 Token::Str(_) => true,
131 _ => false
132 }
133 }
134
135 pub fn to_string(self) -> Option<String> {
137 match self {
138 Token::Str(s) => Some(s),
139 _ => None
140 }
141 }
142
143 pub fn as_string(&self) -> Option<&str> {
145 match *self {
146 Token::Str(ref s) => Some(s.as_str()),
147 _ => None
148 }
149 }
150
151 pub fn to_string_result(self) -> Result<String,ScanError> {
153 match self {
154 Token::Str(s) => Ok(s),
155 t => type_error(t,"string")
156 }
157 }
158
159 pub fn is_iden(&self) -> bool {
161 match *self {
162 Token::Iden(_) => true,
163 _ => false
164 }
165 }
166
167 pub fn to_iden(self) -> Option<String> {
169 match self {
170 Token::Iden(n) => Some(n),
171 _ => None
172 }
173 }
174
175 pub fn as_iden(&self) -> Option<&str> {
177 match *self {
178 Token::Iden(ref n) => Some(n.as_str()),
179 _ => None
180 }
181 }
182
183
184 pub fn to_iden_result(self) -> Result<String,ScanError> {
186 match self {
187 Token::Iden(n) => Ok(n),
188 t => type_error(t,"iden")
189 }
190 }
191
192 pub fn is_char(&self) -> bool {
194 match *self {
195 Token::Char(_) => true,
196 _ => false
197 }
198 }
199
200 pub fn to_char(self) -> Option<char> {
202 match self {
203 Token::Char(c) => Some(c),
204 _ => None
205 }
206 }
207
208 pub fn as_char(&self) -> Option<char> {
210 match *self {
211 Token::Char(c) => Some(c),
212 _ => None
213 }
214 }
215
216 pub fn to_char_result(self) -> Result<char,ScanError> {
218 match self {
219 Token::Char(c) => Ok(c),
220 t => type_error(t,"char")
221 }
222 }
223
224 pub fn is_error(&self) -> bool {
226 match *self {
227 Token::Error(_) => true,
228 _ => false
229 }
230 }
231
232 pub fn to_error(self) -> Option<ScanError> {
234 match self {
235 Token::Error(e) => Some(e),
236 _ => None
237 }
238 }
239
240}