| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -13,7 +13,8 @@ use std::fmt; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					use std::str::{self, FromStr}; | 
					 | 
					 | 
					 | 
					use std::str::{self, FromStr}; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					pub use error::Error; | 
					 | 
					 | 
					 | 
					pub use error::Error; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					use error::{ERes, err}; | 
					 | 
					 | 
					 | 
					pub use error::SourcePosition; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					use error::{ERes, err, spos}; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#[cfg(test)] | 
					 | 
					 | 
					 | 
					#[cfg(test)] | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					mod test; | 
					 | 
					 | 
					 | 
					mod test; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -34,11 +35,26 @@ pub enum Atom { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/// An s-expression is either an atom or a list of s-expressions. This is
 | 
					 | 
					 | 
					 | 
					/// An s-expression is either an atom or a list of s-expressions. This is
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/// similar to the data format used by lisp.
 | 
					 | 
					 | 
					 | 
					/// similar to the data format used by lisp.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#[derive(PartialEq, Clone, PartialOrd)] | 
					 | 
					 | 
					 | 
					#[derive(Clone)] | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#[allow(missing_docs)] | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					pub enum Sexp { | 
					 | 
					 | 
					 | 
					pub enum Sexp { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    Atom(Atom), | 
					 | 
					 | 
					 | 
					    /// Atom
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    List(Vec<Sexp>), | 
					 | 
					 | 
					 | 
					    Atom(Atom, Option<Box<SourcePosition>>), | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    /// List of expressions
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    List(Vec<Sexp>, Option<Box<SourcePosition>>), | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					impl PartialEq for Sexp { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    fn eq(&self, other: &Self) -> bool { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        match (self, other) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            (Sexp::Atom(a, _), Sexp::Atom(b, _)) => { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                a == b | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            (Sexp::List(a, _), Sexp::List(b, _)) => { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                a == b | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            _ => false | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -180,30 +196,33 @@ fn parse_sexp(s: &str, pos: &mut usize) -> ERes<Sexp> { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    trace!("parse_sexp {}", pos); | 
					 | 
					 | 
					 | 
					    trace!("parse_sexp {}", pos); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    zspace(s, pos)?; | 
					 | 
					 | 
					 | 
					    zspace(s, pos)?; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    let (c, _) = peek(s, pos)?; | 
					 | 
					 | 
					 | 
					    let (c, _) = peek(s, pos)?; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    let r = | 
					 | 
					 | 
					 | 
					    let r = if c == '(' { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        if c == '(' { Ok(Sexp::List(parse_list(s, pos)?)) } else { Ok(Sexp::Atom(parse_atom(s, pos)?)) }; | 
					 | 
					 | 
					 | 
					        Ok(Sexp::List(parse_list(s, pos)?, spos(s, pos))) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        Ok(Sexp::Atom(parse_atom(s, pos)?, spos(s, pos))) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    }; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    zspace(s, pos)?; | 
					 | 
					 | 
					 | 
					    zspace(s, pos)?; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    r | 
					 | 
					 | 
					 | 
					    r | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/// Constructs an atomic s-expression from a string.
 | 
					 | 
					 | 
					 | 
					/// Constructs an atomic s-expression from a string.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					pub fn atom_s(s: &str) -> Sexp { | 
					 | 
					 | 
					 | 
					pub fn atom_s(s: &str) -> Sexp { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    Sexp::Atom(Atom::S(s.to_owned())) | 
					 | 
					 | 
					 | 
					    Sexp::Atom(Atom::S(s.to_owned()), None) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/// Constructs an atomic s-expression from an int.
 | 
					 | 
					 | 
					 | 
					/// Constructs an atomic s-expression from an int.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					pub fn atom_i(i: i64) -> Sexp { | 
					 | 
					 | 
					 | 
					pub fn atom_i(i: i64) -> Sexp { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    Sexp::Atom(Atom::I(i)) | 
					 | 
					 | 
					 | 
					    Sexp::Atom(Atom::I(i), None) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/// Constructs an atomic s-expression from a float.
 | 
					 | 
					 | 
					 | 
					/// Constructs an atomic s-expression from a float.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					pub fn atom_f(f: f64) -> Sexp { | 
					 | 
					 | 
					 | 
					pub fn atom_f(f: f64) -> Sexp { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    Sexp::Atom(Atom::F(f)) | 
					 | 
					 | 
					 | 
					    Sexp::Atom(Atom::F(f), None) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/// Constructs a list s-expression given a slice of s-expressions.
 | 
					 | 
					 | 
					 | 
					/// Constructs a list s-expression given a slice of s-expressions.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					pub fn list(xs: &[Sexp]) -> Sexp { | 
					 | 
					 | 
					 | 
					pub fn list(xs: &[Sexp]) -> Sexp { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    Sexp::List(xs.to_owned()) | 
					 | 
					 | 
					 | 
					    Sexp::List(xs.to_owned(), None) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/// Reads an s-expression out of a `&str`.
 | 
					 | 
					 | 
					 | 
					/// Reads an s-expression out of a `&str`.
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -256,8 +275,8 @@ impl fmt::Display for Atom { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					impl fmt::Display for Sexp { | 
					 | 
					 | 
					 | 
					impl fmt::Display for Sexp { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { | 
					 | 
					 | 
					 | 
					    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        match *self { | 
					 | 
					 | 
					 | 
					        match *self { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            Sexp::Atom(ref a) => write!(f, "{}", a), | 
					 | 
					 | 
					 | 
					            Sexp::Atom(ref a, _) => write!(f, "{}", a), | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            Sexp::List(ref xs) => { | 
					 | 
					 | 
					 | 
					            Sexp::List(ref xs, _) => { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                write!(f, "(")?; | 
					 | 
					 | 
					 | 
					                write!(f, "(")?; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                for (i, x) in xs.iter().enumerate() { | 
					 | 
					 | 
					 | 
					                for (i, x) in xs.iter().enumerate() { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    let s = if i == 0 { "" } else { " " }; | 
					 | 
					 | 
					 | 
					                    let s = if i == 0 { "" } else { " " }; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
  |