use crate::parser::*; use crate::spans::*; use imbl::*; use std::fmt; #[derive(Clone, Debug, PartialEq)] pub struct Clause<'src> { patt: Pattern<'src>, span: Span, body: Ast<'src>, } #[derive(Clone, Debug, PartialEq)] pub struct Fn<'src> { name: &'src str, span: Span, body: Vec>, } #[derive(Clone, Debug, PartialEq)] pub enum Value<'src> { Nil, Boolean(bool), Number(f64), Keyword(&'src str), String(&'src str), Tuple(Vec), // on the heap for now List(Vector), // ref-counted, immutable, persistent Dict(HashMap<&'src str, Self>), // ref-counted, immutable, persistent Fn(&'src Fn<'src>), // Set(HashSet), // Sets are hard // Sets require Eq // Eq is not implemented on f64, because NaNs // We could use ordered_float::NotNan // Let's defer that // We're not really using sets in Ludus // Other things we're not implementing yet: // pkgs, nses, tests } impl<'src> fmt::Display for Value<'src> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Value::Nil => write!(f, "nil"), Value::Boolean(b) => write!(f, "{}", b), Value::Number(n) => write!(f, "{}", n), Value::Keyword(k) => write!(f, ":{}", k), Value::String(s) => write!(f, "\"{}\"", s), Value::Fn(fun) => write!(f, "fn {}", fun.name), Value::Tuple(t) => write!( f, "({})", t.iter() .map(|x| x.to_string()) .collect::>() .join(", ") ), Value::List(l) => write!( f, "[{}]", l.iter() .map(|x| x.to_string()) .collect::>() .join(", ") ), Value::Dict(d) => write!(f, "#{{{:?}}}", d), } } }