From 4360b8b33c5baf030a468023bb32d5df2947afd7 Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Sat, 24 Dec 2016 21:16:38 -0500 Subject: [PATCH] Parse character literals --- src/lib.rs | 66 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b4aba8c..011d9fb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -77,6 +77,7 @@ use ParseResult::*; pub enum ParseError where Loc: Span { /// We can't explain how the parsing failed. UnexpectedEof, + Char(Box, Loc), String(Box, Loc), Symbol(Box, Loc), Number(Box, Loc), @@ -274,6 +275,52 @@ pub fn parse_string(input: &str, start_loc: usize) -> ParseResult ParseResult { + let end_of_white = if let Some(pos) = input.find(|c: char| !c.is_whitespace()) { + pos + } else { + return Error(ParseError::String( + Box::new(ParseError::UnexpectedEof), + (input.len(), input.len()).offset(start_loc))); + }; + + let input = &input[end_of_white..]; + let start_loc = start_loc + end_of_white; + + match input.chars().nth(0) { + Some('#') => (), + Some(c) => + return Error(ParseError::Char( + Box::new(ParseError::Unexpected(c, start_loc)), + (0, 0).offset(start_loc))), + None => + return Error(ParseError::Char( + Box::new(ParseError::UnexpectedEof), + (0, 0).offset(start_loc))), + } + + match input.chars().nth(1) { + Some('\\') => (), + Some(c) => + return Error(ParseError::Char( + Box::new(ParseError::Unexpected(c, start_loc + 1)), + (1, 1).offset(start_loc))), + None => + return Error(ParseError::Char( + Box::new(ParseError::UnexpectedEof), + (1, 1).offset(start_loc))) + } + + match input.chars().nth(2) { + Some(c) => + Done(&input[3..], Sexp::Char(c, (0, 3).offset(start_loc))), + None => + Error(ParseError::Char( + Box::new(ParseError::UnexpectedEof), + (2, 2).offset(start_loc))) + } +} + // Tests /////////////////////////////////////////////////////////////////////// @@ -325,18 +372,17 @@ with 0123 things in it""#, 0), Done("", Sexp::Str("this is a nice string\nwith 0123 things in it".into(), (2, 48)))); assert_eq!(parse_string(r#""hi"#, 0), Error(ParseError::String(Box::new(ParseError::UnexpectedEof), (0, 3)))); } -} -// #[cfg(test)] -// #[test] -// fn test_parse_char() { -// assert_eq!(character(r#"#\""#), IResult::Done("", Sexp::Char('"'))); -// assert_eq!(character(r#"#\ "#), IResult::Done("", Sexp::Char(' '))); -// assert_eq!(character(r#" #\\"#), IResult::Done("", Sexp::Char('\\'))); + #[test] + fn test_parse_char() { + assert_eq!(parse_character(r#"#\""#, 0), Done("", Sexp::Char('"', (0, 3)))); + assert_eq!(parse_character(r#"#\ "#, 0), Done("", Sexp::Char(' ', (0, 3)))); + assert_eq!(parse_character(r#" #\\"#, 0), Done("", Sexp::Char('\\', (2, 5)))); -// assert!(character("#").is_incomplete()); -// assert!(character("a").is_err()); -// } + assert_eq!(parse_character("#", 0), Error(ParseError::Char(Box::new(ParseError::UnexpectedEof), (1, 1)))); + assert_eq!(parse_character("a", 0), Error(ParseError::Char(Box::new(ParseError::Unexpected('a', 0)), (0, 0)))); + } +} // #[cfg(test)] -- 2.43.2