Add support for parsing vectors in the elisp parser.

This commit is contained in:
Tom Alexander 2023-08-13 00:41:55 -04:00
parent d1e0ee831c
commit cf0991fdff
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
1 changed files with 20 additions and 3 deletions

View File

@ -23,6 +23,7 @@ pub enum Token<'s> {
Atom(&'s str), Atom(&'s str),
List(Vec<Token<'s>>), List(Vec<Token<'s>>),
TextWithProperties(TextWithProperties<'s>), TextWithProperties(TextWithProperties<'s>),
Vector(Vec<Token<'s>>),
} }
#[derive(Debug)] #[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"))] #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn token<'s>(input: &'s str) -> Res<&'s str, Token<'s>> { 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"))] #[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))) 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"))] #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn atom<'s>(input: &'s str) -> Res<&'s str, Token<'s>> { 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) alt((text_with_properties, quoted_atom, unquoted_atom))(input)
} }
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn unquoted_atom<'s>(input: &'s str) -> Res<&'s str, Token<'s>> { fn unquoted_atom<'s>(input: &'s str) -> Res<&'s str, Token<'s>> {
let (remaining, body) = take_till1(|c| match c { let (remaining, body) = take_till1(|c| match c {
' ' | '\t' | '\r' | '\n' | ')' => true, ' ' | '\t' | '\r' | '\n' | ')' | ']' => true,
_ => false, _ => false,
})(input)?; })(input)?;
Ok((remaining, Token::Atom(body))) Ok((remaining, Token::Atom(body)))
@ -237,6 +251,7 @@ mod tests {
Token::Atom(_) => false, Token::Atom(_) => false,
Token::List(_) => true, Token::List(_) => true,
Token::TextWithProperties(_) => false, Token::TextWithProperties(_) => false,
Token::Vector(_) => false,
}); });
} }
@ -249,6 +264,7 @@ mod tests {
Token::Atom(_) => false, Token::Atom(_) => false,
Token::List(_) => true, Token::List(_) => true,
Token::TextWithProperties(_) => false, Token::TextWithProperties(_) => false,
Token::Vector(_) => false,
}); });
let children = match parsed { let children = match parsed {
Token::List(children) => children, Token::List(children) => children,
@ -308,6 +324,7 @@ mod tests {
Token::Atom(_) => false, Token::Atom(_) => false,
Token::List(_) => true, Token::List(_) => true,
Token::TextWithProperties(_) => false, Token::TextWithProperties(_) => false,
Token::Vector(_) => false,
}); });
let children = match parsed { let children = match parsed {
Token::List(children) => children, Token::List(children) => children,