From a547dc711cabcbf986d6c35b0572bef06f553211 Mon Sep 17 00:00:00 2001 From: Erin Date: Sat, 6 Aug 2022 00:49:25 +0200 Subject: [PATCH] basic formatting --- src/interpreter/value/mod.rs | 49 +++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/src/interpreter/value/mod.rs b/src/interpreter/value/mod.rs index 1380e50..9224fa5 100644 --- a/src/interpreter/value/mod.rs +++ b/src/interpreter/value/mod.rs @@ -7,12 +7,14 @@ pub use pair::DotPair; pub use string::Str; use crate::syntax::ast::{Expr, Spanned}; -use std::{collections::BTreeMap, rc::Rc}; +use std::{collections::BTreeMap, fmt::Display, rc::Rc}; pub type OrderedF64 = ordered_float::OrderedFloat; -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Default, Clone, PartialEq, Eq)] pub enum Value<'s> { + #[default] + Nil, DotPair(Rc>), Vector(Rc>), Map(Rc>), @@ -22,7 +24,6 @@ pub enum Value<'s> { String(Str<'s>), Function(Function), Macro(Function), - Nil, } impl<'s> From>> for Value<'s> { @@ -34,7 +35,9 @@ impl<'s> From>> for Value<'s> { impl<'s> From> for Value<'s> { fn from(e: Expr<'s>) -> Self { match e { - Expr::List(_) => todo!(), + Expr::List(v) => v.into_iter().rev().fold(Self::Nil, |acc, x| { + Value::DotPair(Rc::new(DotPair(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( @@ -48,3 +51,41 @@ impl<'s> From> for Value<'s> { } } } + +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::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}")) + } + Value::Symbol(s) => s.fmt(f), + Value::Keyword(k) => write!(f, ":{k}"), + Value::Number(n) => n.fmt(f), + Value::String(s) => write!(f, "\"{s}\""), + Value::Function(_) => "#fun#".fmt(f), + Value::Macro(_) => "#macro#".fmt(f), + } + } +} + +fn fmt_sequence<'s, T>( + f: &mut std::fmt::Formatter<'_>, + s: impl IntoIterator, + start: &str, + end: &str, + it_fmt: impl Fn(T, &mut std::fmt::Formatter<'_>) -> std::fmt::Result, +) -> std::fmt::Result { + let mut it = s.into_iter(); + start.fmt(f)?; + if let Some(i) = it.next() { + it_fmt(i, f)?; + } + for i in it { + " ".fmt(f)?; + it_fmt(i, f)?; + } + end.fmt(f) +}