From e6a881de481045b440019f735f6915b122191853 Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Sat, 24 Dec 2016 21:33:47 -0500 Subject: [PATCH] Parse general s-expressions --- src/lib.rs | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 011d9fb..11dfc18 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -126,9 +126,27 @@ impl IsDelimeter for char { // Parsers ///////////////////////////////////////////////////////////////////// -// pub fn parse_one(input: &str) -> Result; +pub fn parse_sexp(input: &str, start_loc: usize) -> ParseResult { + let end_of_white = if let Some(pos) = input.find(|c: char| !c.is_whitespace()) { + pos + } else { + return Error(ParseError::Number( + Box::new(ParseError::UnexpectedEof), + (input.len(), input.len()).offset(start_loc))); + }; -// pub fn parse(input: &str) -> Result, ParseError>; + let input = &input[end_of_white..]; + let start_loc = start_loc + end_of_white; + + match input.chars().next() { + Some('0'...'9') => parse_number(input, start_loc), + Some('(') => unimplemented!(), + Some('#') => parse_character(input, start_loc), + Some('"') => parse_string(input, start_loc), + Some(_) => parse_symbol(input, start_loc), + None => unreachable!(), + } +} pub fn parse_number(input: &str, start_loc: usize) -> ParseResult { // Consume all the whitespace at the beginning of the string @@ -329,6 +347,15 @@ mod test { use super::*; use super::ParseResult::*; + #[test] + fn test_parse_sexp() { + assert_eq!(parse_sexp(" 1", 0), Done("", Sexp::Int(1, (1, 2)))); + assert_eq!(parse_sexp("2.2", 0), Done("", Sexp::Float(2.2, (0, 3)))); + assert_eq!(parse_sexp(" a", 0), Done("", Sexp::Sym("a".into(), (1, 2)))); + assert_eq!(parse_sexp("#\\c", 0), Done("", Sexp::Char('c', (0, 3)))); + assert_eq!(parse_sexp(r#""hi""#, 0), Done("", Sexp::Str("hi".into(), (0, 4)))); + } + #[test] fn test_parse_number() { assert_eq!(parse_number("1", 0), Done("", Sexp::Int(1, (0, 1)))); -- 2.43.2