]> Witch of Git - ess/commitdiff
Change List to use Cow<[Sexp]> instead of Vec<Sexp> develop
authorCassie Jones <code@witchoflight.com>
Tue, 11 Feb 2020 01:42:07 +0000 (20:42 -0500)
committerCassie Jones <code@witchoflight.com>
Tue, 11 Feb 2020 01:42:07 +0000 (20:42 -0500)
We would like to use Cow<[Sexp]> since this enables storing slices
inside the lists, and therefore allows you to calculate "cdr"
efficiently. It doesn't improve "cons" at all, however, so this might
not be the right option.

src/parser.rs
src/sexp.rs

index 6039a0df9f45349d53df171d14e2ff703dd0d955..0470fab44e180a1a02daaab9a70e67cab31c777b 100644 (file)
@@ -14,6 +14,7 @@
 
 use sexp::Sexp;
 use span::{ByteSpan, Span};
 
 use sexp::Sexp;
 use span::{ByteSpan, Span};
+use std::borrow::Cow;
 
 // Parsing Types ///////////////////////////////////////////////////////////////
 
 
 // Parsing Types ///////////////////////////////////////////////////////////////
 
@@ -206,7 +207,7 @@ pub fn parse_expression(input: &str, start_loc: usize) -> ParseResult<Sexp, Pars
     let (input, start_loc) = consume_whitespace!(input, start_loc, ParseError::Sexp);
 
     match input.chars().next() {
     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),
         Some('(') | Some('{') | Some('[') => parse_list(input, start_loc),
         Some('#') => parse_character(input, start_loc),
         Some('"') => parse_string(input, start_loc),
@@ -217,7 +218,7 @@ pub fn parse_expression(input: &str, start_loc: usize) -> ParseResult<Sexp, Pars
                 Done(
                     rest,
                     Sexp::List(
                 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),
                     ),
                 )
                         quote_span.union(&span),
                     ),
                 )
@@ -231,7 +232,7 @@ pub fn parse_expression(input: &str, start_loc: usize) -> ParseResult<Sexp, Pars
                 Done(
                     rest,
                     Sexp::List(
                 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),
                     ),
                 )
                         quote_span.union(&span),
                     ),
                 )
@@ -247,7 +248,7 @@ pub fn parse_expression(input: &str, start_loc: usize) -> ParseResult<Sexp, Pars
                         Done(
                             rest,
                             Sexp::List(
                         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),
                             ),
                         )
                                 quote_span.union(&span),
                             ),
                         )
@@ -262,7 +263,7 @@ pub fn parse_expression(input: &str, start_loc: usize) -> ParseResult<Sexp, Pars
                         Done(
                             rest,
                             Sexp::List(
                         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),
                             ),
                         )
                                 quote_span.union(&span),
                             ),
                         )
@@ -304,7 +305,7 @@ pub fn parse_list(input: &str, start_loc: usize) -> ParseResult<Sexp, ParseError
         match input.chars().nth(0) {
             Some(c @ ')') | Some(c @ '}') | Some(c @ ']') => match (first_char, c) {
                 ('(', ')') | ('{', '}') | ('[', ']') => {
         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(
                 }
                 _ => {
                     return Error(ParseError::List(
@@ -424,7 +425,7 @@ pub fn parse_symbol(input: &str, start_loc: usize) -> ParseResult<Sexp, ParseErr
     let (input, start_loc) = consume_whitespace!(input, start_loc, ParseError::Symbol);
 
     match input.chars().next() {
     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),
             return Error(ParseError::Symbol(
                 Box::new(ParseError::Unexpected(c, start_loc)),
                 (0, 0).offset(start_loc),
@@ -534,7 +535,6 @@ pub fn parse_character(input: &str, start_loc: usize) -> ParseResult<Sexp, Parse
 
 #[cfg(test)]
 mod test {
 
 #[cfg(test)]
 mod test {
-    use parser::ParseResult::*;
     use parser::*;
     use sexp::Sexp;
     use span::Span;
     use parser::*;
     use sexp::Sexp;
     use span::Span;
index 4484fd304951aad99440f7417199bc0b86f9a754..8eb72f0d1374fefe2cc8ae5d52ad573d6d6e503a 100644 (file)
@@ -1,6 +1,6 @@
 //! The `Sexp` type, the representation of s-expressions.
 
 //! The `Sexp` type, the representation of s-expressions.
 
-use std::borrow::Cow;
+use std::borrow::{Cow, ToOwned};
 
 use span::{ByteSpan, Span};
 
 
 use span::{ByteSpan, Span};
 
@@ -8,10 +8,10 @@ use span::{ByteSpan, Span};
 ///
 /// `Sexp` carries the source code location it came from along with it for later
 /// diagnostic purposes.
 ///
 /// `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
 pub enum Sexp<'a, Loc = ByteSpan>
 where
-    Loc: Span,
+    Loc: Span + Clone,
 {
     /// A value representing a symbol.
     Sym(Cow<'a, str>, Loc),
 {
     /// A value representing a symbol.
     Sym(Cow<'a, str>, Loc),
@@ -26,12 +26,12 @@ where
     /// decimal point will be parsed as a `Float`.
     Float(f64, Loc),
     /// A list of subexpressions.
     /// 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
 }
 
 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 {
 {
     /// Gives a reference to the source location contained in the `Sexp`.
     pub fn get_loc(&self) -> &Loc {
@@ -67,19 +67,21 @@ where
 
 impl<'a, Loc> Sexp<'a, Loc>
 where
 
 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.
 {
     /// 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(),
+            ),
         }
     }
 }
         }
     }
 }