use std::borrow::Cow;
use span::{ByteSpan, Span};
#[derive(Debug, PartialEq, Clone, PartialOrd)]
pub enum Sexp<'a, Loc = ByteSpan>
where
Loc: Span,
{
Sym(Cow<'a, str>, Loc),
Str(Cow<'a, str>, Loc),
Char(char, Loc),
Int(i64, Loc),
Float(f64, Loc),
List(Vec<Sexp<'a, Loc>>, Loc),
}
impl<'a, Loc> Sexp<'a, Loc>
where
Loc: Span,
{
pub fn get_loc(&self) -> &Loc {
match *self {
Sexp::Sym(.., ref l)
| Sexp::Str(.., ref l)
| Sexp::Char(.., ref l)
| Sexp::Int(.., ref l)
| Sexp::Float(.., ref l)
| Sexp::List(.., ref l) => l,
}
}
pub fn get_loc_mut(&mut self) -> &mut Loc {
match *self {
Sexp::Sym(.., ref mut l)
| Sexp::Str(.., ref mut l)
| Sexp::Char(.., ref mut l)
| Sexp::Int(.., ref mut l)
| Sexp::Float(.., ref mut l)
| Sexp::List(.., ref mut l) => l,
}
}
}
fn extend_cow<'a, T: ?Sized>(cow: &Cow<'a, T>) -> Cow<'static, T>
where
T: ToOwned,
{
Cow::Owned(cow.clone().into_owned())
}
impl<'a, Loc> Sexp<'a, Loc>
where
Loc: Span + Clone,
{
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())
}
}
}
}