use sexp::Sexp;
use span::{ByteSpan, Span};
+use std::borrow::Cow;
// Parsing Types ///////////////////////////////////////////////////////////////
let (input, start_loc) = consume_whitespace!(input, start_loc, ParseError::Sexp);
match input.chars().next() {
- Some('0'...'9') => parse_number(input, start_loc),
+ Some('0'..='9') => parse_number(input, start_loc),
Some('(') | Some('{') | Some('[') => parse_list(input, start_loc),
Some('#') => parse_character(input, start_loc),
Some('"') => parse_string(input, start_loc),
Done(
rest,
Sexp::List(
- vec![Sexp::Sym("quote".into(), quote_span), result],
+ Cow::from(vec![Sexp::Sym("quote".into(), quote_span), result]),
quote_span.union(&span),
),
)
Done(
rest,
Sexp::List(
- vec![Sexp::Sym("quasiquote".into(), quote_span), result],
+ Cow::from(vec![Sexp::Sym("quasiquote".into(), quote_span), result]),
quote_span.union(&span),
),
)
Done(
rest,
Sexp::List(
- vec![Sexp::Sym("unquote-splicing".into(), quote_span), result],
+ Cow::from(vec![Sexp::Sym("unquote-splicing".into(), quote_span), result]),
quote_span.union(&span),
),
)
Done(
rest,
Sexp::List(
- vec![Sexp::Sym("unquote".into(), quote_span), result],
+ Cow::from(vec![Sexp::Sym("unquote".into(), quote_span), result]),
quote_span.union(&span),
),
)
match input.chars().nth(0) {
Some(c @ ')') | Some(c @ '}') | Some(c @ ']') => match (first_char, c) {
('(', ')') | ('{', '}') | ('[', ']') => {
- return Done(&input[1..], Sexp::List(members, (start_loc, loc + 1)))
+ return Done(&input[1..], Sexp::List(Cow::from(members), (start_loc, loc + 1)))
}
_ => {
return Error(ParseError::List(
let (input, start_loc) = consume_whitespace!(input, start_loc, ParseError::Symbol);
match input.chars().next() {
- Some(c @ '#') | Some(c @ ':') | Some(c @ '0'...'9') => {
+ Some(c @ '#') | Some(c @ ':') | Some(c @ '0'..='9') => {
return Error(ParseError::Symbol(
Box::new(ParseError::Unexpected(c, start_loc)),
(0, 0).offset(start_loc),
#[cfg(test)]
mod test {
- use parser::ParseResult::*;
use parser::*;
use sexp::Sexp;
use span::Span;
//! The `Sexp` type, the representation of s-expressions.
-use std::borrow::Cow;
+use std::borrow::{Cow, ToOwned};
use span::{ByteSpan, Span};
///
/// `Sexp` carries the source code location it came from along with it for later
/// diagnostic purposes.
-#[derive(Debug, PartialEq, Clone, PartialOrd)]
+#[derive(Clone, Debug, PartialEq, PartialOrd)]
pub enum Sexp<'a, Loc = ByteSpan>
where
- Loc: Span,
+ Loc: Span + Clone,
{
/// A value representing a symbol.
Sym(Cow<'a, str>, Loc),
/// decimal point will be parsed as a `Float`.
Float(f64, Loc),
/// A list of subexpressions.
- List(Vec<Sexp<'a, Loc>>, Loc),
+ List(Cow<'a, [Sexp<'a, Loc>]>, Loc),
}
impl<'a, Loc> Sexp<'a, Loc>
where
- Loc: Span,
+ Loc: Span + Clone,
{
/// Gives a reference to the source location contained in the `Sexp`.
pub fn get_loc(&self) -> &Loc {
impl<'a, Loc> Sexp<'a, Loc>
where
- Loc: Span + Clone,
+ Loc: Span + ToOwned + Clone,
+ Loc::Owned: Span + Clone,
{
/// Take ownership of an s-expression's contents.
- pub fn to_owned(&self) -> Sexp<'static, Loc> {
- match *self {
- Sexp::Sym(ref s, ref l) => Sexp::Sym(extend_cow(s), l.clone()),
- Sexp::Str(ref s, ref l) => Sexp::Str(extend_cow(s), l.clone()),
- Sexp::Char(c, ref l) => Sexp::Char(c, l.clone()),
- Sexp::Int(i, ref l) => Sexp::Int(i, l.clone()),
- Sexp::Float(f, ref l) => Sexp::Float(f, l.clone()),
- Sexp::List(ref xs, ref l) => {
- Sexp::List(xs.iter().map(Sexp::to_owned).collect(), l.clone())
- }
+ pub fn to_owned(&self) -> Sexp<'static, Loc::Owned> {
+ match self {
+ Sexp::Sym(s, l) => Sexp::Sym(extend_cow(s), l.to_owned()),
+ Sexp::Str(s, l) => Sexp::Str(extend_cow(s), l.to_owned()),
+ Sexp::Char(c, l) => Sexp::Char(*c, l.to_owned()),
+ Sexp::Int(i, l) => Sexp::Int(*i, l.to_owned()),
+ Sexp::Float(f, l) => Sexp::Float(*f, l.to_owned()),
+ Sexp::List(xs, l) => Sexp::List(
+ xs.iter().map(Sexp::to_owned).collect(),
+ l.to_owned(),
+ ),
}
}
}