1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
use std::sync::Arc; use crate::span::Span; pub type DataStr = Arc<str>; #[derive(PartialEq, Debug, Clone)] pub enum Datum { Bool(Span, bool), Char(Span, char), Int(Span, i64), Float(Span, f64), List(Span, Box<[Datum]>), Str(Span, DataStr), Sym(Span, DataStr), Vector(Span, Box<[Datum]>), Map(Span, Box<[(Datum, Datum)]>), Set(Span, Box<[Datum]>), } impl Datum { pub fn span(&self) -> Span { match self { Datum::Bool(span, _) | Datum::Char(span, _) | Datum::Int(span, _) | Datum::Float(span, _) | Datum::List(span, _) | Datum::Str(span, _) | Datum::Sym(span, _) | Datum::Vector(span, _) | Datum::Map(span, _) | Datum::Set(span, _) => *span, } } pub fn description(&self) -> &'static str { match self { Datum::Bool(_, true) => "boolean true", Datum::Bool(_, false) => "boolean false", Datum::Char(_, _) => "character", Datum::Int(_, _) => "integer", Datum::Float(_, _) => "floating point number", Datum::Str(_, _) => "string", Datum::Sym(_, name) => { if name.starts_with(':') { "keyword" } else { "symbol" } } Datum::List(_, vs) if vs.is_empty() => "empty list", Datum::List(_, _) => "list", Datum::Vector(_, vs) if vs.is_empty() => "empty vector", Datum::Vector(_, _) => "vector", Datum::Set(_, vs) if vs.is_empty() => "empty set", Datum::Set(_, _) => "set", Datum::Map(_, vs) if vs.is_empty() => "empty map", Datum::Map(_, _) => "map", } } }