From cf0991fdff52d839eeaf4b4c24450c6f9f944a99 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sun, 13 Aug 2023 00:41:55 -0400 Subject: [PATCH] Add support for parsing vectors in the elisp parser. --- src/parser/sexp.rs | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/parser/sexp.rs b/src/parser/sexp.rs index 2b06892b..5b89153f 100644 --- a/src/parser/sexp.rs +++ b/src/parser/sexp.rs @@ -23,6 +23,7 @@ pub enum Token<'s> { Atom(&'s str), List(Vec>), TextWithProperties(TextWithProperties<'s>), + Vector(Vec>), } #[derive(Debug)] @@ -136,7 +137,7 @@ pub fn sexp<'s>(input: &'s str) -> Res<&'s str, Token<'s>> { #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] fn token<'s>(input: &'s str) -> Res<&'s str, Token<'s>> { - alt((list, atom))(input) + alt((list, vector, atom))(input) } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] @@ -151,16 +152,29 @@ fn list<'s>(input: &'s str) -> Res<&'s str, Token<'s>> { Ok((remaining, Token::List(children))) } +#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] +fn vector<'s>(input: &'s str) -> Res<&'s str, Token<'s>> { + let (remaining, _) = tag("[")(input)?; + let (remaining, children) = delimited( + multispace0, + separated_list1(multispace1, token), + multispace0, + )(remaining)?; + let (remaining, _) = tag("]")(remaining)?; + Ok((remaining, Token::Vector(children))) +} + #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] fn atom<'s>(input: &'s str) -> Res<&'s str, Token<'s>> { - not(peek(tag(")")))(input)?; + not(peek(one_of(")]")))(input)?; + // TODO: Add calls to hash notation alt((text_with_properties, quoted_atom, unquoted_atom))(input) } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] fn unquoted_atom<'s>(input: &'s str) -> Res<&'s str, Token<'s>> { let (remaining, body) = take_till1(|c| match c { - ' ' | '\t' | '\r' | '\n' | ')' => true, + ' ' | '\t' | '\r' | '\n' | ')' | ']' => true, _ => false, })(input)?; Ok((remaining, Token::Atom(body))) @@ -237,6 +251,7 @@ mod tests { Token::Atom(_) => false, Token::List(_) => true, Token::TextWithProperties(_) => false, + Token::Vector(_) => false, }); } @@ -249,6 +264,7 @@ mod tests { Token::Atom(_) => false, Token::List(_) => true, Token::TextWithProperties(_) => false, + Token::Vector(_) => false, }); let children = match parsed { Token::List(children) => children, @@ -308,6 +324,7 @@ mod tests { Token::Atom(_) => false, Token::List(_) => true, Token::TextWithProperties(_) => false, + Token::Vector(_) => false, }); let children = match parsed { Token::List(children) => children,