diff options
Diffstat (limited to 'src/lisp/lex.rs')
-rw-r--r-- | src/lisp/lex.rs | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/src/lisp/lex.rs b/src/lisp/lex.rs index b307e80..1a34e53 100644 --- a/src/lisp/lex.rs +++ b/src/lisp/lex.rs | |||
@@ -8,7 +8,7 @@ pub enum Token<'a> { | |||
8 | RightParen, | 8 | RightParen, |
9 | Float(&'a str), | 9 | Float(&'a str), |
10 | Integer(&'a str), | 10 | Integer(&'a str), |
11 | // Char(&'a str), | 11 | Char(&'a str), |
12 | String(&'a str), | 12 | String(&'a str), |
13 | Name(&'a str), | 13 | Name(&'a str), |
14 | // Keyword(&'a str), | 14 | // Keyword(&'a str), |
@@ -26,7 +26,7 @@ impl<'a> Token<'a> { | |||
26 | Token::RightParen => ")", | 26 | Token::RightParen => ")", |
27 | Token::Float(_) => "float", | 27 | Token::Float(_) => "float", |
28 | Token::Integer(_) => "integer", | 28 | Token::Integer(_) => "integer", |
29 | // Token::Char(_) => "char", | 29 | Token::Char(_) => "char", |
30 | Token::String(_) => "string", | 30 | Token::String(_) => "string", |
31 | Token::Name(_) => "name", | 31 | Token::Name(_) => "name", |
32 | // Token::Keyword(_) => "keyword", | 32 | // Token::Keyword(_) => "keyword", |
@@ -46,7 +46,7 @@ impl<'a> fmt::Display for Token<'a> { | |||
46 | Token::RightParen => write!(f, ")"), | 46 | Token::RightParen => write!(f, ")"), |
47 | Token::Float(_) => write!(f, "float"), | 47 | Token::Float(_) => write!(f, "float"), |
48 | Token::Integer(_) => write!(f, "integer"), | 48 | Token::Integer(_) => write!(f, "integer"), |
49 | // Token::Char(_) => write!(f, "char"), | 49 | Token::Char(_) => write!(f, "char"), |
50 | Token::String(_) => write!(f, "string"), | 50 | Token::String(_) => write!(f, "string"), |
51 | Token::Name(_) => write!(f, "name"), | 51 | Token::Name(_) => write!(f, "name"), |
52 | // Token::Keyword(_) => write!(f, "keyword"), | 52 | // Token::Keyword(_) => write!(f, "keyword"), |
@@ -122,7 +122,10 @@ impl<'a> Lexer<'a> { | |||
122 | Some((_, '@')) => Ok((2, Token::CommaAt)), | 122 | Some((_, '@')) => Ok((2, Token::CommaAt)), |
123 | _ => Ok((1, Token::Comma)), | 123 | _ => Ok((1, Token::Comma)), |
124 | }, | 124 | }, |
125 | '#' => parse_name(&self.input[ind..]), | 125 | '#' => match chars.next() { |
126 | Some((_, '\\')) => parse_char(&self.input[ind..]), | ||
127 | _ => parse_name(&self.input[ind..]), | ||
128 | }, | ||
126 | '-' | '0'..='9' => parse_number(&self.input[ind..]), | 129 | '-' | '0'..='9' => parse_number(&self.input[ind..]), |
127 | '"' => parse_string(&self.input[ind..]), | 130 | '"' => parse_string(&self.input[ind..]), |
128 | ';' => { | 131 | ';' => { |
@@ -254,6 +257,12 @@ fn parse_name<'a>(input: &'a str) -> Result<(usize, Token<'a>), ParseErrorKind> | |||
254 | return Ok((input.len(), Token::Name(input))); | 257 | return Ok((input.len(), Token::Name(input))); |
255 | } | 258 | } |
256 | 259 | ||
260 | fn parse_char<'a>(input: &'a str) -> Result<(usize, Token<'a>), ParseErrorKind> { | ||
261 | // first two chars of input are '#' and '\' | ||
262 | let chr = &input[..3]; | ||
263 | return Ok((chr.len(), Token::Char(chr))); | ||
264 | } | ||
265 | |||
257 | #[cfg(test)] | 266 | #[cfg(test)] |
258 | mod tests { | 267 | mod tests { |
259 | use super::*; | 268 | use super::*; |
@@ -283,6 +292,14 @@ mod tests { | |||
283 | } | 292 | } |
284 | 293 | ||
285 | #[test] | 294 | #[test] |
295 | fn char_parsing() { | ||
296 | let input = r##"#\a"##; | ||
297 | let parsed = parse_char(input).unwrap(); | ||
298 | assert_eq!(parsed.0, 3); | ||
299 | assert_eq!(parsed.1, Token::Char(r##"#\a"##)); | ||
300 | } | ||
301 | |||
302 | #[test] | ||
286 | fn integer_parsing() { | 303 | fn integer_parsing() { |
287 | let input = "12345"; | 304 | let input = "12345"; |
288 | let parsed = parse_number(input).unwrap(); | 305 | let parsed = parse_number(input).unwrap(); |