aboutsummaryrefslogtreecommitdiff
path: root/src/lisp/lex.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lisp/lex.rs')
-rw-r--r--src/lisp/lex.rs25
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
260fn 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)]
258mod tests { 267mod 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();