dot-pair pretty-print

This commit is contained in:
Erin 2022-08-06 21:25:47 +02:00 committed by ondra05
parent d1d7ab4067
commit a592cf80f2
2 changed files with 63 additions and 9 deletions

View file

@ -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}"))

View file

@ -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;