dot-pair pretty-print
This commit is contained in:
parent
d1d7ab4067
commit
a592cf80f2
|
@ -7,6 +7,7 @@ pub use pair::DotPair;
|
|||
pub use string::Str;
|
||||
|
||||
use crate::syntax::ast::{Expr, Spanned};
|
||||
use pair::list;
|
||||
use std::{collections::BTreeMap, fmt::Display, rc::Rc};
|
||||
|
||||
pub type OrderedF64 = ordered_float::OrderedFloat<f64>;
|
||||
|
@ -15,7 +16,7 @@ pub type OrderedF64 = ordered_float::OrderedFloat<f64>;
|
|||
pub enum Value<'s> {
|
||||
#[default]
|
||||
Nil,
|
||||
DotPair(Rc<DotPair<'s>>),
|
||||
DotPair(DotPair<'s>),
|
||||
Vector(Rc<Vec<Self>>),
|
||||
Map(Rc<BTreeMap<Self, Self>>),
|
||||
Symbol(Str<'s>),
|
||||
|
@ -36,14 +37,11 @@ impl<'s> From<Expr<'s>> for Value<'s> {
|
|||
fn from(e: Expr<'s>) -> Self {
|
||||
match e {
|
||||
Expr::List(v) => v.into_iter().rev().fold(Self::Nil, |acc, x| {
|
||||
Value::DotPair(Rc::new(DotPair(x.into(), acc)))
|
||||
Value::DotPair(DotPair::new(x.into(), acc))
|
||||
}),
|
||||
Expr::Vector(v) => Self::Vector(Rc::new(v.into_iter().map(Into::into).collect())),
|
||||
Expr::Pair((l, r)) => Self::DotPair(Rc::new(DotPair((*l).into(), (*r).into()))),
|
||||
Expr::Quote(e) => Self::DotPair(Rc::new(DotPair(
|
||||
Self::Symbol("quote".into()),
|
||||
Self::DotPair(Rc::new(DotPair((*e).into(), Self::Nil))),
|
||||
))),
|
||||
Expr::Pair((l, r)) => Self::DotPair(DotPair::new((*l).into(), (*r).into())),
|
||||
Expr::Quote(e) => list!(Self::Symbol("quote".into()), (*e).into()),
|
||||
Expr::Symbol("nil") => Self::Nil,
|
||||
Expr::Symbol(s) => Self::Symbol(s.into()),
|
||||
Expr::Keyword(s) => Self::Keyword(s.into()),
|
||||
|
@ -57,7 +55,7 @@ impl<'s> Display for Value<'s> {
|
|||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Value::Nil => "nil".fmt(f),
|
||||
Value::DotPair(p) => write!(f, "({} . {})", p.0, p.1),
|
||||
Value::DotPair(p) => p.fmt(f),
|
||||
Value::Vector(v) => fmt_sequence(f, v.as_ref(), "#(", ")", |i, f| i.fmt(f)),
|
||||
Value::Map(m) => {
|
||||
fmt_sequence(f, m.as_ref(), "(", ")", |(k, v), f| write!(f, "{k} -> {v}"))
|
||||
|
|
|
@ -1,4 +1,60 @@
|
|||
use super::Value;
|
||||
use std::{fmt::Display, rc::Rc};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct DotPair<'s>(pub Value<'s>, pub Value<'s>);
|
||||
pub struct DotPair<'s>(pub Rc<(Value<'s>, Value<'s>)>);
|
||||
impl<'s> DotPair<'s> {
|
||||
pub fn new(first: Value<'s>, second: Value<'s>) -> Self {
|
||||
Self(Rc::new((first, second)))
|
||||
}
|
||||
|
||||
pub fn first(&self) -> &Value<'s> {
|
||||
&self.0 .0
|
||||
}
|
||||
|
||||
pub fn second(&self) -> &Value<'s> {
|
||||
&self.0 .1
|
||||
}
|
||||
}
|
||||
|
||||
impl<'s> Display for DotPair<'s> {
|
||||
fn fmt(mut self: &Self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
"(".fmt(f)?;
|
||||
loop {
|
||||
self.first().fmt(f)?;
|
||||
match self.second() {
|
||||
Value::Nil => break,
|
||||
Value::DotPair(p) => {
|
||||
" ".fmt(f)?;
|
||||
self = p;
|
||||
}
|
||||
val => break write!(f, " . {val}")?,
|
||||
}
|
||||
}
|
||||
")".fmt(f)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! list {
|
||||
() => {
|
||||
$crate::interpreter::value::Value::Nil
|
||||
};
|
||||
|
||||
($item: expr $(,)?) => {
|
||||
Value::DotPair(
|
||||
$crate::interpreter::value::DotPair::new($item, $crate::interpreter::value::Value::Nil)
|
||||
)
|
||||
};
|
||||
|
||||
($first: expr, $($rest: expr),* $(,)?) => {
|
||||
Value::DotPair(
|
||||
$crate::interpreter::value::DotPair::new(
|
||||
$first,
|
||||
$crate::interpreter::value::pair::list!($($rest),*)
|
||||
)
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) use list;
|
||||
|
|
Loading…
Reference in a new issue