From 4043b18b189137a99396fed09c5818ca86269b7f Mon Sep 17 00:00:00 2001 From: Caleb Jones Date: Wed, 4 Jan 2017 19:03:37 -0500 Subject: [PATCH] Add quote notation with ' ' parses the same as (quote ), but with smaller spans. --- src/parser.rs | 45 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index 1816afc..2041cf6 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -188,6 +188,18 @@ pub fn parse_expression(input: &str, start_loc: usize) -> ParseResult parse_list(input, start_loc), Some('#') => parse_character(input, start_loc), Some('"') => parse_string(input, start_loc), + Some('\'') => { + match parse_expression(&input[1..], start_loc + 1) { + Done(rest, result) => { + let span = *result.get_loc(); + let quote_span = (0, 1).offset(start_loc); + Done(rest, + Sexp::List(vec![Sexp::Sym("quote".into(), quote_span), result], + quote_span.union(&span))) + } + err => err, + } + } Some(_) => parse_symbol(input, start_loc), None => unreachable!(), } @@ -438,15 +450,40 @@ mod test { Done("", Sexp::List(vec![], (0, 2)))); assert_eq!(parse_expression("( 1 2 3 )", 0), Done("", Sexp::List(vec![ - Sexp::Int(1, (2, 3)), - Sexp::Int(2, (4, 5)), - Sexp::Int(3, (6, 7)), - ], (0, 9)))); + Sexp::Int(1, (2, 3)), + Sexp::Int(2, (4, 5)), + Sexp::Int(3, (6, 7)), + ], (0, 9)))); assert_eq!(parse_expression("", 0), Error(ParseError::Sexp(Box::new(ParseError::UnexpectedEof), (0, 0)))); } + #[test] + fn test_parse_expr_quote() { + assert_eq!(parse_expression("'a", 0), + Done("", Sexp::List(vec![ + Sexp::Sym("quote".into(), (0, 1)), + Sexp::Sym("a".into(), (1, 2)), + ], (0, 2)))); + assert_eq!(parse_expression("'1", 0), + Done("", Sexp::List(vec![ + Sexp::Sym("quote".into(), (0, 1)), + Sexp::Int(1, (1, 2)), + ], (0, 2)))); + assert_eq!(parse_expression("' (1 2 3)", 0), + Done("", Sexp::List(vec![ + Sexp::Sym("quote".into(), (0, 1)), + Sexp::List(vec![ + Sexp::Int(1, (3, 4)), + Sexp::Int(2, (5, 6)), + Sexp::Int(3, (7, 8)), + ], (2, 9)), + ], (0, 9)))); + assert_eq!(parse_expression("'", 0), + Error(ParseError::Sexp(Box::new(ParseError::UnexpectedEof), (1, 1)))); + } + #[test] fn test_parse_list() { assert_eq!(parse_list("()", 0), -- 2.43.2