scheme_rs/
value.rs

1use crate::{
2    ast,
3    continuation::Continuation,
4    error::RuntimeError,
5    expand::Transformer,
6    gc::{Gc, Trace},
7    num::Number,
8    proc::{Callable, ExternalFn, Procedure},
9    syntax::Syntax,
10};
11use futures::future::{BoxFuture, Shared};
12use scheme_rs_macros::builtin;
13use std::sync::Arc;
14
15#[derive(Clone, Trace, derive_more::Debug)]
16pub enum Value {
17    Null,
18    Boolean(bool),
19    Number(Number),
20    Character(char),
21    String(String),
22    Symbol(String),
23    Pair(#[debug(skip)] Gc<Value>, #[debug(skip)] Gc<Value>),
24    Vector(#[debug(skip)] Vec<Gc<Value>>),
25    ByteVector(Vec<u8>),
26    Syntax(Syntax),
27    Procedure(Procedure),
28    ExternalFn(ExternalFn),
29    Future(#[debug(skip)] Shared<BoxFuture<'static, Result<Vec<Gc<Value>>, RuntimeError>>>),
30    Transformer(#[debug(skip)] Transformer),
31    Continuation(#[debug(skip)] Option<Arc<Continuation>>),
32    Undefined,
33}
34
35impl Value {
36    pub fn is_callable(&self) -> bool {
37        matches!(
38            self,
39            Self::Procedure(_) | Self::ExternalFn(_) | Self::Transformer(_)
40        )
41    }
42
43    /// #f is false, everything else is true
44    pub fn is_true(&self) -> bool {
45        !matches!(self, Self::Boolean(x) if !x)
46    }
47
48    pub fn is_variable_transformer(&self) -> bool {
49        match self {
50            Self::Procedure(ref proc) => proc.is_variable_transformer,
51            Self::Transformer(ref trans) => trans.is_variable_transformer,
52            _ => false,
53        }
54    }
55
56    pub fn as_callable(&self) -> Option<Box<dyn Callable>> {
57        match self {
58            // Having to clone and box these kind of sucks. Hopefully we can
59            // fix this at some point
60            Self::Procedure(ref proc) => Some(Box::new(proc.clone())),
61            Self::ExternalFn(ref proc) => Some(Box::new(proc.clone())),
62            Self::Continuation(ref proc) => Some(Box::new(proc.clone())),
63            _ => None,
64        }
65    }
66
67    pub fn fmt(&self) -> BoxFuture<'_, String> {
68        Box::pin(async move {
69            match self {
70                Self::Boolean(true) => "#t".to_string(),
71                Self::Boolean(false) => "#f".to_string(),
72                Self::Number(number) => number.to_string(),
73                Self::String(string) => format!("\"{string}\""),
74                Self::Symbol(symbol) => symbol.clone(),
75                Self::Pair(car, cdr) => crate::lists::fmt_list(car, cdr).await,
76                Self::Vector(vec) => {
77                    let mut iter = vec.iter().peekable();
78                    let mut output = String::from("#(");
79                    while let Some(item) = iter.next() {
80                        output.push_str(&item.read().await.fmt().await);
81                        if iter.peek().is_some() {
82                            output.push(' ');
83                        }
84                    }
85                    output.push(')');
86                    output
87                }
88                Self::Null => "()".to_string(),
89                Self::Character(c) => format!("\\x{c}"),
90                Self::ByteVector(_) => "<byte_vector>".to_string(),
91                Self::Syntax(syntax) => format!("{:#?}", syntax),
92                Self::Procedure(proc) => format!("<{proc:?}>"),
93                Self::ExternalFn(_) => "<external_fn>".to_string(),
94                Self::Future(_) => "<future>".to_string(),
95                Self::Transformer(_) => "<transformer>".to_string(),
96                Self::Continuation(_) => "<continuation>".to_string(),
97                Self::Undefined => "<undefined>".to_string(),
98            }
99        })
100    }
101
102    pub fn from_literal(literal: &ast::Literal) -> Self {
103        match literal {
104            ast::Literal::Number(n) => Value::Number(n.clone()),
105            ast::Literal::Boolean(b) => Value::Boolean(*b),
106            ast::Literal::String(s) => Value::String(s.clone()),
107            _ => todo!("Literal evaluation not implemented"),
108        }
109    }
110
111    pub fn from_syntax(syntax: &Syntax) -> Self {
112        match syntax {
113            Syntax::Null { .. } => Self::Null,
114            Syntax::List { list, .. } => {
115                let mut curr = Self::from_syntax(list.last().unwrap());
116                for item in list[..list.len() - 1].iter().rev() {
117                    curr = Self::Pair(Gc::new(Self::from_syntax(item)), Gc::new(curr));
118                }
119                curr
120            }
121            Syntax::Vector { vector, .. } => {
122                Self::Vector(vector.iter().map(Self::from_syntax).map(Gc::new).collect())
123            }
124            Syntax::Literal { literal, .. } => Self::from_literal(literal),
125            Syntax::Identifier { ident, .. } => Self::Symbol(ident.name.clone()),
126        }
127    }
128
129    pub fn type_name(&self) -> &'static str {
130        match self {
131            Self::Boolean(_) => "bool",
132            Self::Number(_) => "number",
133            Self::Character(_) => "character",
134            Self::String(_) => "string",
135            Self::Symbol(_) => "symbol",
136            Self::Pair(_, _) | Self::Null => "pair",
137            Self::Vector(_) => "vector",
138            Self::ByteVector(_) => "byte vector",
139            Self::Syntax(_) => "syntax",
140            Self::Procedure(_) | Self::ExternalFn(_) | Self::Transformer(_) => "procedure",
141            Self::Future(_) => "future",
142            Self::Continuation(_) => "continuation",
143            Self::Undefined => "undefined",
144        }
145    }
146
147    pub async fn eqv(&self, other: &Self) -> bool {
148        match (self, other) {
149            (Self::Null, Self::Null) => true,
150            (Self::Boolean(a), Self::Boolean(b)) => a == b,
151            (Self::Number(a), Self::Number(b)) => a == b,
152            (Self::Character(a), Self::Character(b)) => a == b,
153            (Self::Symbol(a), Self::Symbol(b)) => a == b,
154            (Self::Pair(a1, a2), Self::Pair(b1, b2)) => eqv(a1, b1).await && eqv(a2, b2).await,
155            (Self::Vector(a), Self::Vector(b)) => {
156                for (a, b) in a.iter().zip(b.iter()) {
157                    if !eqv(a, b).await {
158                        return false;
159                    }
160                }
161                true
162            }
163            (Self::ByteVector(a), Self::ByteVector(b)) => a == b,
164            // TODO: Syntax
165            _ => false,
166        }
167    }
168}
169
170impl From<ExternalFn> for Value {
171    fn from(ef: ExternalFn) -> Self {
172        Value::ExternalFn(ef)
173    }
174}
175
176/// Create a proper list from a vector of values
177impl From<Vec<Gc<Value>>> for Value {
178    fn from(mut vec: Vec<Gc<Value>>) -> Value {
179        if vec.is_empty() {
180            Value::Null
181        } else {
182            // I'm not spending too much time thinking about a better way to do this
183            let tail = vec.split_off(1);
184            Value::Pair(vec.pop().unwrap(), Gc::new(Value::from(tail)))
185        }
186    }
187}
188
189impl<'a> TryFrom<&'a Value> for bool {
190    type Error = RuntimeError;
191
192    fn try_from(v: &'a Value) -> Result<bool, Self::Error> {
193        match v {
194            Value::Boolean(b) => Ok(*b),
195            x => Err(RuntimeError::invalid_type("bool", x.type_name())),
196        }
197    }
198}
199
200impl<'a> TryFrom<&'a Value> for &'a Number {
201    type Error = RuntimeError;
202
203    fn try_from(v: &'a Value) -> Result<&'a Number, Self::Error> {
204        match v {
205            Value::Number(n) => Ok(n),
206            x => Err(RuntimeError::invalid_type("number", x.type_name())),
207        }
208    }
209}
210
211pub fn eqv<'a>(a: &'a Gc<Value>, b: &'a Gc<Value>) -> BoxFuture<'a, bool> {
212    Box::pin(async move {
213        let a = a.read().await;
214        let b = b.read().await;
215        a.eqv(&b).await
216    })
217}
218
219#[builtin("not")]
220pub async fn not(
221    _cont: &Option<Arc<Continuation>>,
222    a: &Gc<Value>,
223) -> Result<Vec<Gc<Value>>, RuntimeError> {
224    let a = a.read().await;
225    Ok(vec![Gc::new(Value::Boolean(matches!(
226        &*a,
227        Value::Boolean(false)
228    )))])
229}
230
231#[builtin("eqv?")]
232pub async fn eqv_pred(
233    _cont: &Option<Arc<Continuation>>,
234    a: &Gc<Value>,
235    b: &Gc<Value>,
236) -> Result<Vec<Gc<Value>>, RuntimeError> {
237    Ok(vec![Gc::new(Value::Boolean(eqv(a, b).await))])
238}
239
240#[builtin("boolean?")]
241pub async fn boolean_pred(
242    _cont: &Option<Arc<Continuation>>,
243    arg: &Gc<Value>,
244) -> Result<Vec<Gc<Value>>, RuntimeError> {
245    let arg = arg.read().await;
246    Ok(vec![Gc::new(Value::Boolean(matches!(
247        &*arg,
248        Value::Boolean(_)
249    )))])
250}
251
252#[builtin("symbol?")]
253pub async fn symbol_pred(
254    _cont: &Option<Arc<Continuation>>,
255    arg: &Gc<Value>,
256) -> Result<Vec<Gc<Value>>, RuntimeError> {
257    let arg = arg.read().await;
258    Ok(vec![Gc::new(Value::Boolean(matches!(
259        &*arg,
260        Value::Symbol(_)
261    )))])
262}
263
264#[builtin("char?")]
265pub async fn char_pred(
266    _cont: &Option<Arc<Continuation>>,
267    arg: &Gc<Value>,
268) -> Result<Vec<Gc<Value>>, RuntimeError> {
269    let arg = arg.read().await;
270    Ok(vec![Gc::new(Value::Boolean(matches!(
271        &*arg,
272        Value::Character(_)
273    )))])
274}
275
276#[builtin("vector?")]
277pub async fn vector_pred(
278    _cont: &Option<Arc<Continuation>>,
279    arg: &Gc<Value>,
280) -> Result<Vec<Gc<Value>>, RuntimeError> {
281    let arg = arg.read().await;
282    Ok(vec![Gc::new(Value::Boolean(matches!(
283        &*arg,
284        Value::Vector(_)
285    )))])
286}
287
288#[builtin("null?")]
289pub async fn null_pred(
290    _cont: &Option<Arc<Continuation>>,
291    arg: &Gc<Value>,
292) -> Result<Vec<Gc<Value>>, RuntimeError> {
293    let arg = arg.read().await;
294    Ok(vec![Gc::new(Value::Boolean(matches!(&*arg, Value::Null)))])
295}
296
297#[builtin("pair?")]
298pub async fn pair_pred(
299    _cont: &Option<Arc<Continuation>>,
300    arg: &Gc<Value>,
301) -> Result<Vec<Gc<Value>>, RuntimeError> {
302    let arg = arg.read().await;
303    Ok(vec![Gc::new(Value::Boolean(matches!(
304        &*arg,
305        Value::Pair(_, _)
306    )))])
307}
308
309#[builtin("number?")]
310pub async fn number_pred(
311    _cont: &Option<Arc<Continuation>>,
312    arg: &Gc<Value>,
313) -> Result<Vec<Gc<Value>>, RuntimeError> {
314    let arg = arg.read().await;
315    Ok(vec![Gc::new(Value::Boolean(matches!(
316        &*arg,
317        Value::Number(_)
318    )))])
319}
320
321#[builtin("string?")]
322pub async fn string_pred(
323    _cont: &Option<Arc<Continuation>>,
324    arg: &Gc<Value>,
325) -> Result<Vec<Gc<Value>>, RuntimeError> {
326    let arg = arg.read().await;
327    Ok(vec![Gc::new(Value::Boolean(matches!(
328        &*arg,
329        Value::String(_)
330    )))])
331}
332
333#[builtin("procedure?")]
334pub async fn procedure_pred(
335    _cont: &Option<Arc<Continuation>>,
336    arg: &Gc<Value>,
337) -> Result<Vec<Gc<Value>>, RuntimeError> {
338    let arg = arg.read().await;
339    Ok(vec![Gc::new(Value::Boolean(matches!(
340        &*arg,
341        Value::Procedure(_) | Value::ExternalFn(_) | Value::Transformer(_)
342    )))])
343}
344
345#[builtin("future?")]
346pub async fn future_pred(
347    _cont: &Option<Arc<Continuation>>,
348    arg: &Gc<Value>,
349) -> Result<Vec<Gc<Value>>, RuntimeError> {
350    let arg = arg.read().await;
351    Ok(vec![Gc::new(Value::Boolean(matches!(
352        &*arg,
353        Value::Future(_)
354    )))])
355}
356
357#[builtin("display")]
358pub async fn disp(
359    _cont: &Option<Arc<Continuation>>,
360    arg: &Gc<Value>,
361) -> Result<Vec<Gc<Value>>, RuntimeError> {
362    println!("{}", arg.read().await.fmt().await);
363    Ok(vec![Gc::new(Value::Null)])
364}