From f94f22a3d0aeff98cc9169c94b683aa139e9c81c Mon Sep 17 00:00:00 2001 From: Akshay Date: Sat, 27 Mar 2021 13:16:25 +0530 Subject: implement char literals --- src/lisp/lex.rs | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'src/lisp/lex.rs') 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> { RightParen, Float(&'a str), Integer(&'a str), - // Char(&'a str), + Char(&'a str), String(&'a str), Name(&'a str), // Keyword(&'a str), @@ -26,7 +26,7 @@ impl<'a> Token<'a> { Token::RightParen => ")", Token::Float(_) => "float", Token::Integer(_) => "integer", - // Token::Char(_) => "char", + Token::Char(_) => "char", Token::String(_) => "string", Token::Name(_) => "name", // Token::Keyword(_) => "keyword", @@ -46,7 +46,7 @@ impl<'a> fmt::Display for Token<'a> { Token::RightParen => write!(f, ")"), Token::Float(_) => write!(f, "float"), Token::Integer(_) => write!(f, "integer"), - // Token::Char(_) => write!(f, "char"), + Token::Char(_) => write!(f, "char"), Token::String(_) => write!(f, "string"), Token::Name(_) => write!(f, "name"), // Token::Keyword(_) => write!(f, "keyword"), @@ -122,7 +122,10 @@ impl<'a> Lexer<'a> { Some((_, '@')) => Ok((2, Token::CommaAt)), _ => Ok((1, Token::Comma)), }, - '#' => parse_name(&self.input[ind..]), + '#' => match chars.next() { + Some((_, '\\')) => parse_char(&self.input[ind..]), + _ => parse_name(&self.input[ind..]), + }, '-' | '0'..='9' => parse_number(&self.input[ind..]), '"' => parse_string(&self.input[ind..]), ';' => { @@ -254,6 +257,12 @@ fn parse_name<'a>(input: &'a str) -> Result<(usize, Token<'a>), ParseErrorKind> return Ok((input.len(), Token::Name(input))); } +fn parse_char<'a>(input: &'a str) -> Result<(usize, Token<'a>), ParseErrorKind> { + // first two chars of input are '#' and '\' + let chr = &input[..3]; + return Ok((chr.len(), Token::Char(chr))); +} + #[cfg(test)] mod tests { use super::*; @@ -282,6 +291,14 @@ mod tests { assert_eq!(parsed.1, Token::String(r#""hello there""#)); } + #[test] + fn char_parsing() { + let input = r##"#\a"##; + let parsed = parse_char(input).unwrap(); + assert_eq!(parsed.0, 3); + assert_eq!(parsed.1, Token::Char(r##"#\a"##)); + } + #[test] fn integer_parsing() { let input = "12345"; -- cgit v1.2.3