1use std::any::Any;
9use std::collections::HashMap;
10use std::fmt;
11use std::sync::Arc;
12
13use tatara_lisp::{Sexp, Span, Spanned};
14
15use crate::env::Env;
16use crate::ffi::Arity;
17
18#[derive(Clone)]
20pub enum Value {
21 Nil,
22 Bool(bool),
23 Int(i64),
24 Float(f64),
25 Str(Arc<str>),
26 Symbol(Arc<str>),
27 Keyword(Arc<str>),
28 List(Arc<Vec<Value>>),
29 Map(Arc<HashMap<MapKey, Value>>),
33 Closure(Arc<Closure>),
34 NativeFn(Arc<NativeFn>),
35 Promise(Arc<std::sync::Mutex<PromiseState>>),
41 Error(Arc<ErrorObj>),
46 Sexp(Sexp, Span),
49 Foreign(Arc<dyn Any + Send + Sync>),
53}
54
55#[derive(Debug, Clone)]
60pub struct ErrorObj {
61 pub tag: Arc<str>,
62 pub message: Arc<str>,
63 pub data: Vec<(Value, Value)>,
64}
65
66#[derive(Debug, Clone, PartialEq, Eq, Hash)]
73pub enum MapKey {
74 Nil,
75 Bool(bool),
76 Int(i64),
77 Float(u64),
78 Str(Arc<str>),
79 Symbol(Arc<str>),
80 Keyword(Arc<str>),
81}
82
83impl MapKey {
84 pub fn from_value(v: &Value) -> Option<Self> {
88 Some(match v {
89 Value::Nil => Self::Nil,
90 Value::Bool(b) => Self::Bool(*b),
91 Value::Int(n) => Self::Int(*n),
92 Value::Float(n) => Self::Float(n.to_bits()),
93 Value::Str(s) => Self::Str(s.clone()),
94 Value::Symbol(s) => Self::Symbol(s.clone()),
95 Value::Keyword(s) => Self::Keyword(s.clone()),
96 _ => return None,
97 })
98 }
99
100 pub fn to_value(&self) -> Value {
103 match self {
104 Self::Nil => Value::Nil,
105 Self::Bool(b) => Value::Bool(*b),
106 Self::Int(n) => Value::Int(*n),
107 Self::Float(b) => Value::Float(f64::from_bits(*b)),
108 Self::Str(s) => Value::Str(s.clone()),
109 Self::Symbol(s) => Value::Symbol(s.clone()),
110 Self::Keyword(s) => Value::Keyword(s.clone()),
111 }
112 }
113}
114
115impl fmt::Display for MapKey {
116 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117 write!(f, "{}", self.to_value())
118 }
119}
120
121pub enum PromiseState {
126 Pending(Arc<Closure>),
127 Forced(Value),
128}
129
130impl fmt::Debug for PromiseState {
131 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
132 match self {
133 Self::Pending(_) => f.write_str("Pending(…)"),
134 Self::Forced(v) => write!(f, "Forced({v:?})"),
135 }
136 }
137}
138
139pub struct Closure {
141 pub params: Vec<Arc<str>>,
142 pub rest: Option<Arc<str>>,
145 pub body: Vec<Spanned>,
148 pub captured_env: Env,
149 pub source: Span,
150}
151
152#[derive(Clone, Debug)]
157pub struct NativeFn {
158 pub name: Arc<str>,
159 pub arity: Arity,
160}
161
162impl Value {
165 pub fn symbol(s: impl Into<Arc<str>>) -> Self {
166 Self::Symbol(s.into())
167 }
168
169 pub fn keyword(s: impl Into<Arc<str>>) -> Self {
170 Self::Keyword(s.into())
171 }
172
173 pub fn string(s: impl Into<Arc<str>>) -> Self {
174 Self::Str(s.into())
175 }
176
177 pub fn list<I: IntoIterator<Item = Value>>(xs: I) -> Self {
178 Self::List(Arc::new(xs.into_iter().collect()))
179 }
180
181 pub fn is_truthy(&self) -> bool {
182 !matches!(self, Self::Nil | Self::Bool(false))
183 }
184
185 #[must_use]
209 pub fn is_unique(&self) -> bool {
210 fn solo<T: ?Sized>(a: &Arc<T>) -> bool {
211 Arc::strong_count(a) == 1 && Arc::weak_count(a) == 0
212 }
213 match self {
214 Self::Nil | Self::Bool(_) | Self::Int(_) | Self::Float(_) => true,
215 Self::Str(s) | Self::Symbol(s) | Self::Keyword(s) => solo(s),
216 Self::List(xs) => solo(xs),
217 Self::Map(m) => solo(m),
218 Self::Closure(c) => solo(c),
219 Self::NativeFn(f) => solo(f),
220 Self::Promise(p) => solo(p),
221 Self::Error(e) => solo(e),
222 Self::Sexp(..) => false,
223 Self::Foreign(f) => solo(f),
224 }
225 }
226
227 pub fn type_name(&self) -> &'static str {
229 match self {
230 Self::Nil => "nil",
231 Self::Bool(_) => "bool",
232 Self::Int(_) => "int",
233 Self::Float(_) => "float",
234 Self::Str(_) => "string",
235 Self::Symbol(_) => "symbol",
236 Self::Keyword(_) => "keyword",
237 Self::List(_) => "list",
238 Self::Map(_) => "map",
239 Self::Closure(_) => "closure",
240 Self::NativeFn(_) => "native-fn",
241 Self::Promise(_) => "promise",
242 Self::Error(_) => "error",
243 Self::Sexp(..) => "sexp",
244 Self::Foreign(_) => "foreign",
245 }
246 }
247}
248
249impl fmt::Debug for Value {
252 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
253 match self {
254 Self::Nil => f.write_str("Nil"),
255 Self::Bool(b) => write!(f, "Bool({b})"),
256 Self::Int(n) => write!(f, "Int({n})"),
257 Self::Float(n) => write!(f, "Float({n})"),
258 Self::Str(s) => write!(f, "Str({s:?})"),
259 Self::Symbol(s) => write!(f, "Symbol({s})"),
260 Self::Keyword(s) => write!(f, "Keyword(:{s})"),
261 Self::List(xs) => f.debug_list().entries(xs.iter()).finish(),
262 Self::Map(m) => write!(f, "Map({} entries)", m.len()),
263 Self::Closure(_) => f.write_str("Closure(…)"),
264 Self::NativeFn(n) => write!(f, "NativeFn({})", n.name),
265 Self::Promise(_) => f.write_str("Promise(…)"),
266 Self::Error(e) => write!(f, "Error({}: {})", e.tag, e.message),
267 Self::Sexp(s, sp) => write!(f, "Sexp({s} @ {sp})"),
268 Self::Foreign(_) => f.write_str("Foreign(…)"),
269 }
270 }
271}
272
273impl fmt::Display for Value {
274 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
275 match self {
276 Self::Nil => f.write_str("()"),
277 Self::Bool(true) => f.write_str("#t"),
278 Self::Bool(false) => f.write_str("#f"),
279 Self::Int(n) => write!(f, "{n}"),
280 Self::Float(n) => write!(f, "{n}"),
281 Self::Str(s) => write!(f, "{s:?}"),
282 Self::Symbol(s) => f.write_str(s),
283 Self::Keyword(s) => write!(f, ":{s}"),
284 Self::List(xs) => {
285 f.write_str("(")?;
286 for (i, v) in xs.iter().enumerate() {
287 if i > 0 {
288 f.write_str(" ")?;
289 }
290 write!(f, "{v}")?;
291 }
292 f.write_str(")")
293 }
294 Self::Map(m) => {
295 f.write_str("{")?;
299 for (i, (k, v)) in m.iter().enumerate() {
300 if i > 0 {
301 f.write_str(", ")?;
302 }
303 write!(f, "{k} {v}")?;
304 }
305 f.write_str("}")
306 }
307 Self::Closure(c) => {
308 write!(f, "#<closure")?;
309 if !c.params.is_empty() {
310 write!(f, " ({}", c.params.join(" "))?;
311 if let Some(rest) = &c.rest {
312 write!(f, " . {rest}")?;
313 }
314 write!(f, ")")?;
315 }
316 write!(f, ">")
317 }
318 Self::NativeFn(n) => write!(f, "#<native {}>", n.name),
319 Self::Promise(p) => {
320 let state = p.lock().unwrap();
321 match &*state {
322 PromiseState::Pending(_) => f.write_str("#<promise pending>"),
323 PromiseState::Forced(v) => write!(f, "#<promise {v}>"),
324 }
325 }
326 Self::Error(e) => {
327 write!(f, "#<error :{} {:?}", e.tag, e.message.as_ref())?;
328 if !e.data.is_empty() {
329 f.write_str(" {")?;
330 for (i, (k, v)) in e.data.iter().enumerate() {
331 if i > 0 {
332 f.write_str(" ")?;
333 }
334 write!(f, "{k} {v}")?;
335 }
336 f.write_str("}")?;
337 }
338 f.write_str(">")
339 }
340 Self::Sexp(s, _) => write!(f, "'{s}"),
341 Self::Foreign(_) => f.write_str("#<foreign>"),
342 }
343 }
344}
345
346impl From<bool> for Value {
349 fn from(b: bool) -> Self {
350 Self::Bool(b)
351 }
352}
353
354impl From<i64> for Value {
355 fn from(n: i64) -> Self {
356 Self::Int(n)
357 }
358}
359
360impl From<f64> for Value {
361 fn from(n: f64) -> Self {
362 Self::Float(n)
363 }
364}
365
366impl From<String> for Value {
367 fn from(s: String) -> Self {
368 Self::Str(Arc::from(s))
369 }
370}
371
372impl From<&str> for Value {
373 fn from(s: &str) -> Self {
374 Self::Str(Arc::from(s))
375 }
376}
377
378#[cfg(test)]
379mod tests {
380 use super::*;
381
382 #[test]
383 fn truthiness() {
384 assert!(Value::Bool(true).is_truthy());
385 assert!(!Value::Bool(false).is_truthy());
386 assert!(!Value::Nil.is_truthy());
387 assert!(Value::Int(0).is_truthy(), "zero is truthy (Scheme-ish)");
388 assert!(Value::list(std::iter::empty::<Value>()).is_truthy());
389 }
390
391 #[test]
392 fn display_primitives() {
393 assert_eq!(Value::Int(42).to_string(), "42");
394 assert_eq!(Value::Bool(true).to_string(), "#t");
395 assert_eq!(Value::Bool(false).to_string(), "#f");
396 assert_eq!(Value::symbol("foo").to_string(), "foo");
397 assert_eq!(Value::keyword("k").to_string(), ":k");
398 assert_eq!(Value::Nil.to_string(), "()");
399 }
400
401 #[test]
402 fn display_list() {
403 let v = Value::list([Value::Int(1), Value::Int(2), Value::Int(3)]);
404 assert_eq!(v.to_string(), "(1 2 3)");
405 }
406
407 #[test]
408 fn type_names() {
409 assert_eq!(Value::Int(0).type_name(), "int");
410 assert_eq!(Value::Str(Arc::from("x")).type_name(), "string");
411 assert_eq!(Value::Nil.type_name(), "nil");
412 }
413}