use std::rc::Rc; use crate::util::unescape; #[derive(Debug, Clone)] pub enum Expr { Null, Bool(bool), Number(f64), String(String), Symbol(String), List(Rc>, Rc), Vector(Rc>, Rc), // Function(fn(Arguments) -> Return, Rc), } impl std::fmt::Display for Expr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Expr::Null => write!(f, "Null"), Expr::Bool(b) => write!(f, "{}", b), Expr::Number(n) => write!(f, "{}", n), Expr::String(s) => write!(f, "\"{}\"", unescape(s.to_string())), Expr::Symbol(s) => write!(f, "{}", s), Expr::List(l, _) => write!(f, "({})", l.iter().map(|e| format!("{}", e)).collect::>().join(" ")), Expr::Vector(l, _) => write!(f, "[{}]", l.iter().map(|e| format!("{}", e)).collect::>().join(", ")), } } } #[derive(Debug)] pub enum Error { ErrorString(String), } impl std::fmt::Display for Error { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Error::ErrorString(s) => write!(f, "{}", s), } } } // pub type Arguments = Vec; pub type Return = Result; #[macro_export] macro_rules! list { ($seq:expr) => {{ List(Rc::new($seq),Rc::new(Null)) }}; [$($args:expr),*] => {{ let v: Vec = vec![$($args),*]; List(Rc::new(v),Rc::new(Null)) }} } #[macro_export] macro_rules! vector { ($seq:expr) => {{ Vector(Rc::new($seq), Rc::new(Null)) }}; [$($args:expr),*] => {{ let v: Vec = vec![$($args),*]; Vector(Rc::new(v), Rc::new(Null)) }} }