Skip to main content

ravenrs_live/
value.rs

1//! What the interpreter works with: plain values, its own closures and state, and objects
2//! of the host program it only passes along.
3
4use std::any::Any;
5use std::cell::RefCell;
6use std::fmt;
7use std::rc::Rc;
8
9use ravenrs_reactive::{Binding, State};
10
11use crate::LiveError;
12use crate::eval::Closure;
13
14/// Copies a host value, for types that can be copied.
15pub(crate) type Copier = fn(&dyn Any) -> Box<dyn Any>;
16
17/// An object of the host program: a component being built, a color, a binding. Builders take
18/// it by value, so using it moves it out, as in Rust; a second use is an error.
19#[derive(Clone)]
20pub struct Host {
21    pub(crate) type_name: &'static str,
22    pub(crate) cell: Rc<RefCell<Option<Box<dyn Any>>>>,
23    pub(crate) copy: Option<Copier>,
24}
25
26impl Host {
27    /// Wraps a host value, known to the interpreter by `type_name`.
28    pub fn new<T: 'static>(type_name: &'static str, value: T) -> Self {
29        Self { type_name, cell: Rc::new(RefCell::new(Some(Box::new(value)))), copy: None }
30    }
31
32    /// Wraps a value that `.clone()` and reading by reference copy instead of moving.
33    pub fn cloneable<T: Clone + 'static>(type_name: &'static str, value: T) -> Self {
34        // The cell only ever holds a T, so the empty box never comes out.
35        fn copy<T: Clone + 'static>(any: &dyn Any) -> Box<dyn Any> {
36            match any.downcast_ref::<T>() {
37                Some(value) => Box::new(value.clone()),
38                None => Box::new(()),
39            }
40        }
41        Self { copy: Some(copy::<T>), ..Self::new(type_name, value) }
42    }
43
44    /// The Rust type it holds, while it holds one.
45    pub(crate) fn held_type(&self) -> Option<std::any::TypeId> {
46        self.cell.borrow().as_ref().map(|any| (**any).type_id())
47    }
48
49    /// The name the interpreter knows its type by.
50    pub fn type_name(&self) -> &'static str {
51        self.type_name
52    }
53
54    /// Takes the value out, or copies it when it can be copied.
55    pub fn take<T: 'static>(&self) -> Result<T, String> {
56        if let Some(copy) = self.copy {
57            let cell = self.cell.borrow();
58            let any = cell.as_ref().ok_or_else(|| format!("this {} was moved", self.type_name))?;
59            return copy(any.as_ref())
60                .downcast::<T>()
61                .map(|b| *b)
62                .map_err(|_| format!("a {} is not a {}", self.type_name, std::any::type_name::<T>()));
63        }
64        let boxed = self.cell.borrow_mut().take().ok_or_else(|| {
65            format!(
66                "this {} was already used: in Rust it moved, so clone it first or build it again",
67                self.type_name
68            )
69        })?;
70        match boxed.downcast::<T>() {
71            Ok(value) => Ok(*value),
72            Err(back) => {
73                *self.cell.borrow_mut() = Some(back);
74                Err(format!("a {} is not a {}", self.type_name, short(std::any::type_name::<T>())))
75            }
76        }
77    }
78
79    /// A copy that shares nothing, when the type can be copied.
80    pub(crate) fn duplicate(&self) -> Option<Self> {
81        let copy = self.copy?;
82        let cell = self.cell.borrow();
83        let any = cell.as_ref()?;
84        Some(Self {
85            type_name: self.type_name,
86            cell: Rc::new(RefCell::new(Some(copy(any.as_ref())))),
87            copy: self.copy,
88        })
89    }
90}
91
92/// The last part of a Rust type's path, for messages.
93pub(crate) fn short(path: &str) -> &str {
94    path.rsplit("::").next().unwrap_or(path)
95}
96
97/// A value of the interpreted program.
98#[derive(Clone)]
99pub enum Value {
100    /// `()`.
101    Unit,
102    /// `true` or `false`.
103    Bool(bool),
104    /// A whole number of any integer type.
105    Int(i64),
106    /// A number with a fraction, of either float type.
107    Float(f64),
108    /// A character.
109    Char(char),
110    /// Text: a `String` or a `&str`.
111    Str(String),
112    /// A tuple.
113    Tuple(Vec<Value>),
114    /// A vector, an array or what an iterator yields.
115    List(Vec<Value>),
116    /// `Some(..)` or `None`.
117    Option(Option<Box<Value>>),
118    /// `a..b` or `a..=b`, as the numbers it gives.
119    Range(i64, i64),
120    /// A range of floats, which only says what it contains: `0.1..0.9`.
121    FloatRange(f64, f64),
122    /// A closure of the program.
123    Closure(Rc<Closure>),
124    /// A `State` of the program, holding interpreter values.
125    State(State<Value>),
126    /// A binding that reads and writes part of another, as `Binding::map` makes.
127    Binding(Binding<Value>),
128    /// `Ok(..)` or `Err(..)`.
129    Result(Result<Box<Value>, Box<Value>>),
130    /// A value of a struct the program declares itself.
131    Record(Rc<Record>),
132    /// A place a closure was given to change, as `|n| *n += 1` gets.
133    Place(Rc<RefCell<Value>>),
134    /// An object of the host program.
135    Host(Host),
136}
137
138impl fmt::Debug for Value {
139    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
140        match self {
141            Self::Unit => f.write_str("()"),
142            Self::Bool(b) => write!(f, "{b}"),
143            Self::Int(n) => write!(f, "{n}"),
144            Self::Float(n) => write!(f, "{n:?}"),
145            Self::Char(c) => write!(f, "{c:?}"),
146            Self::Str(s) => write!(f, "{s:?}"),
147            Self::Tuple(items) => f.debug_tuple("").field(items).finish(),
148            Self::List(items) => f.debug_list().entries(items).finish(),
149            Self::Option(Some(v)) => write!(f, "Some({v:?})"),
150            Self::Option(None) => f.write_str("None"),
151            Self::Range(a, b) => write!(f, "{a}..{b}"),
152            Self::FloatRange(a, b) => write!(f, "{a:?}..{b:?}"),
153            Self::Closure(_) => f.write_str("<closure>"),
154            Self::State(state) => write!(f, "State({:?})", state.get()),
155            Self::Binding(binding) => write!(f, "Binding({:?})", binding.get()),
156            Self::Result(Ok(v)) => write!(f, "Ok({v:?})"),
157            Self::Result(Err(v)) => write!(f, "Err({v:?})"),
158            Self::Record(record) => {
159                let mut out = f.debug_struct(&record.name);
160                for (name, value) in record.fields.borrow().iter() {
161                    out.field(name, value);
162                }
163                out.finish()
164            }
165            Self::Place(place) => write!(f, "&mut {:?}", place.borrow()),
166            Self::Host(host) => write!(f, "<{}>", host.type_name),
167        }
168    }
169}
170
171impl PartialEq for Value {
172    fn eq(&self, other: &Self) -> bool {
173        match (self.read(), other.read()) {
174            (Self::Unit, Self::Unit) => true,
175            (Self::Bool(a), Self::Bool(b)) => a == b,
176            (Self::Int(a), Self::Int(b)) => a == b,
177            (Self::Float(a), Self::Float(b)) => a == b,
178            (Self::Int(a), Self::Float(b)) | (Self::Float(b), Self::Int(a)) => a as f64 == b,
179            (Self::Char(a), Self::Char(b)) => a == b,
180            (Self::Str(a), Self::Str(b)) => a == b,
181            (Self::Tuple(a), Self::Tuple(b)) | (Self::List(a), Self::List(b)) => a == b,
182            (Self::Option(a), Self::Option(b)) => a == b,
183            (Self::Range(a, b), Self::Range(c, d)) => (a, b) == (c, d),
184            (Self::FloatRange(a, b), Self::FloatRange(c, d)) => (a, b) == (c, d),
185            (Self::Result(a), Self::Result(b)) => a == b,
186            (Self::Record(a), Self::Record(b)) => {
187                Rc::ptr_eq(&a, &b) || (a.name == b.name && *a.fields.borrow() == *b.fields.borrow())
188            }
189            _ => false,
190        }
191    }
192}
193
194/// A value of a struct the program declares itself: its fields, which methods can change.
195pub struct Record {
196    /// The struct's name.
197    pub name: String,
198    /// Its fields, in the order written; a tuple struct's are named `0`, `1`, ...
199    pub fields: RefCell<Vec<(String, Value)>>,
200    pub(crate) program: Option<Rc<crate::eval::Program>>,
201}
202
203impl fmt::Debug for Record {
204    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
205        write!(
206            f,
207            "{:?}",
208            Value::Record(Rc::new(Record {
209                name: self.name.clone(),
210                fields: RefCell::new(self.fields.borrow().clone()),
211                program: None
212            }))
213        )
214    }
215}
216
217impl Record {
218    /// The value of a field.
219    pub fn field(&self, name: &str) -> Option<Value> {
220        self.fields.borrow().iter().find(|(n, _)| n == name).map(|(_, v)| v.clone())
221    }
222
223    /// Whether the program gave its type a method of this name, in any `impl` block.
224    pub fn has_method(&self, name: &str) -> bool {
225        self.program.as_ref().is_some_and(|program| program.method(&self.name, name).is_some())
226    }
227
228    /// Calls a method the program gave its type, with `this` as the receiver.
229    pub fn call_method(this: &Rc<Self>, name: &str, arguments: Vec<Value>) -> Result<Value, LiveError> {
230        let Some(program) = this.program.clone() else {
231            return Err(LiveError::nowhere(format!("a {} has no methods", this.name)));
232        };
233        let Some(method) = program.method(&this.name, name) else {
234            return Err(LiveError::nowhere(format!("a {} has no method `{name}`", this.name)));
235        };
236        let mut all = vec![Value::Record(this.clone())];
237        all.extend(arguments);
238        crate::eval::call_function(&program, &method, all)
239    }
240}
241
242impl Value {
243    /// A binding to what it holds, when it is a `State` or a binding.
244    pub fn as_binding(&self) -> Option<Binding<Value>> {
245        match self.read() {
246            Self::State(state) => Some(state.binding()),
247            Self::Binding(binding) => Some(binding),
248            _ => None,
249        }
250    }
251
252    /// What a place holds, or the value itself.
253    pub fn read(&self) -> Value {
254        match self {
255            Self::Place(place) => place.borrow().read(),
256            other => other.clone(),
257        }
258    }
259
260    /// The name of its kind, for messages.
261    pub fn kind(&self) -> String {
262        match self {
263            Self::Unit => "()".into(),
264            Self::Bool(_) => "bool".into(),
265            Self::Int(_) => "integer".into(),
266            Self::Float(_) => "float".into(),
267            Self::Char(_) => "char".into(),
268            Self::Str(_) => "String".into(),
269            Self::Tuple(_) => "tuple".into(),
270            Self::List(_) => "Vec".into(),
271            Self::Option(_) => "Option".into(),
272            Self::Range(..) | Self::FloatRange(..) => "range".into(),
273            Self::Closure(_) => "closure".into(),
274            Self::State(_) => "State".into(),
275            Self::Binding(_) => "Binding".into(),
276            Self::Result(_) => "Result".into(),
277            Self::Record(record) => record.name.clone(),
278            Self::Place(place) => place.borrow().kind(),
279            Self::Host(host) => host.type_name.into(),
280        }
281    }
282
283    /// The items it gives when iterated: a list's, a range's numbers, an option's one or none.
284    pub fn items(&self) -> Result<Vec<Value>, String> {
285        match self.read() {
286            Self::List(items) | Self::Tuple(items) => Ok(items),
287            Self::Range(a, b) => Ok((a..b).map(Value::Int).collect()),
288            Self::Option(option) => Ok(option.map(|v| *v).into_iter().collect()),
289            Self::Result(result) => Ok(result.ok().map(|v| *v).into_iter().collect()),
290            Self::Str(text) => Ok(text.chars().map(Value::Char).collect()),
291            other => Err(format!("a {} cannot be iterated", other.kind())),
292        }
293    }
294}
295
296/// What a host function's argument can be made from.
297pub trait FromLive: Sized {
298    /// The value as this type, or why it cannot be.
299    fn from_live(value: Value) -> Result<Self, String>;
300}
301
302/// What a host function's result becomes.
303pub trait IntoLive {
304    /// The value for the interpreter.
305    fn into_live(self) -> Value;
306}
307
308impl FromLive for Value {
309    fn from_live(value: Value) -> Result<Self, String> {
310        Ok(value)
311    }
312}
313
314impl IntoLive for Value {
315    fn into_live(self) -> Value {
316        self
317    }
318}
319
320impl IntoLive for () {
321    fn into_live(self) -> Value {
322        Value::Unit
323    }
324}
325
326impl FromLive for () {
327    fn from_live(_: Value) -> Result<Self, String> {
328        Ok(())
329    }
330}
331
332fn wrong(expected: &str, value: &Value) -> String {
333    format!("expected {expected}, found {}", value.kind())
334}
335
336impl FromLive for bool {
337    fn from_live(value: Value) -> Result<Self, String> {
338        match value.read() {
339            Value::Bool(b) => Ok(b),
340            other => Err(wrong("bool", &other)),
341        }
342    }
343}
344
345impl IntoLive for bool {
346    fn into_live(self) -> Value {
347        Value::Bool(self)
348    }
349}
350
351macro_rules! whole {
352    ($($ty:ty),*) => {$(
353        impl FromLive for $ty {
354            fn from_live(value: Value) -> Result<Self, String> {
355                match value.read() {
356                    Value::Int(n) => <$ty>::try_from(n).map_err(|_| format!("{n} does not fit in {}", stringify!($ty))),
357                    other => Err(wrong(stringify!($ty), &other)),
358                }
359            }
360        }
361        impl IntoLive for $ty {
362            fn into_live(self) -> Value {
363                Value::Int(self as i64)
364            }
365        }
366    )*};
367}
368
369whole!(i8, i16, i32, i64, u8, u16, u32, u64, usize, isize);
370
371impl FromLive for f64 {
372    fn from_live(value: Value) -> Result<Self, String> {
373        match value.read() {
374            Value::Float(n) => Ok(n),
375            Value::Int(n) => Ok(n as f64),
376            other => Err(wrong("f64", &other)),
377        }
378    }
379}
380
381impl IntoLive for f64 {
382    fn into_live(self) -> Value {
383        Value::Float(self)
384    }
385}
386
387impl FromLive for f32 {
388    fn from_live(value: Value) -> Result<Self, String> {
389        f64::from_live(value).map(|n| n as f32)
390    }
391}
392
393impl IntoLive for f32 {
394    fn into_live(self) -> Value {
395        Value::Float(f64::from(self))
396    }
397}
398
399impl FromLive for char {
400    fn from_live(value: Value) -> Result<Self, String> {
401        match value.read() {
402            Value::Char(c) => Ok(c),
403            other => Err(wrong("char", &other)),
404        }
405    }
406}
407
408impl IntoLive for char {
409    fn into_live(self) -> Value {
410        Value::Char(self)
411    }
412}
413
414impl FromLive for String {
415    fn from_live(value: Value) -> Result<Self, String> {
416        match value.read() {
417            Value::Str(s) => Ok(s),
418            Value::Char(c) => Ok(c.to_string()),
419            other => Err(wrong("text", &other)),
420        }
421    }
422}
423
424impl IntoLive for String {
425    fn into_live(self) -> Value {
426        Value::Str(self)
427    }
428}
429
430impl IntoLive for &str {
431    fn into_live(self) -> Value {
432        Value::Str(self.to_owned())
433    }
434}
435
436impl<T: FromLive> FromLive for Option<T> {
437    fn from_live(value: Value) -> Result<Self, String> {
438        match value.read() {
439            Value::Option(None) => Ok(None),
440            Value::Option(Some(inner)) => T::from_live(*inner).map(Some),
441            other => Err(wrong("Option", &other)),
442        }
443    }
444}
445
446impl<T: IntoLive> IntoLive for Option<T> {
447    fn into_live(self) -> Value {
448        Value::Option(self.map(|v| Box::new(v.into_live())))
449    }
450}
451
452impl<T: FromLive, E: FromLive> FromLive for Result<T, E> {
453    fn from_live(value: Value) -> Result<Self, String> {
454        match value.read() {
455            Value::Result(Ok(inner)) => T::from_live(*inner).map(Ok),
456            Value::Result(Err(inner)) => E::from_live(*inner).map(Err),
457            other => Err(wrong("Ok(..) or Err(..)", &other)),
458        }
459    }
460}
461
462impl<T: IntoLive, E: IntoLive> IntoLive for Result<T, E> {
463    fn into_live(self) -> Value {
464        Value::Result(match self {
465            Ok(v) => Ok(Box::new(v.into_live())),
466            Err(e) => Err(Box::new(e.into_live())),
467        })
468    }
469}
470
471impl<T: FromLive> FromLive for Vec<T> {
472    fn from_live(value: Value) -> Result<Self, String> {
473        value.items()?.into_iter().map(T::from_live).collect()
474    }
475}
476
477impl<T: IntoLive> IntoLive for Vec<T> {
478    fn into_live(self) -> Value {
479        Value::List(self.into_iter().map(IntoLive::into_live).collect())
480    }
481}
482
483impl<T: FromLive + Ord> FromLive for std::collections::BTreeSet<T> {
484    fn from_live(value: Value) -> Result<Self, String> {
485        value.items()?.into_iter().map(T::from_live).collect()
486    }
487}
488
489impl<T: IntoLive> IntoLive for std::collections::BTreeSet<T> {
490    fn into_live(self) -> Value {
491        Value::List(self.into_iter().map(IntoLive::into_live).collect())
492    }
493}
494
495macro_rules! tuples {
496    ($(($($name:ident),+)),*) => {$(
497        impl<$($name: FromLive),+> FromLive for ($($name,)+) {
498            #[allow(non_snake_case)]
499            fn from_live(value: Value) -> Result<Self, String> {
500                let Value::Tuple(items) = value.read() else { return Err(wrong("a tuple", &value)) };
501                let mut items = items.into_iter();
502                $(let $name = $name::from_live(items.next().ok_or("the tuple is too short")?)?;)+
503                Ok(($($name,)+))
504            }
505        }
506        impl<$($name: IntoLive),+> IntoLive for ($($name,)+) {
507            #[allow(non_snake_case)]
508            fn into_live(self) -> Value {
509                let ($($name,)+) = self;
510                Value::Tuple(vec![$($name.into_live()),+])
511            }
512        }
513    )*};
514}
515
516tuples!((A, B), (A, B, C), (A, B, C, D));
517
518impl FromLive for State<Value> {
519    fn from_live(value: Value) -> Result<Self, String> {
520        match value.read() {
521            Value::State(state) => Ok(state),
522            other => Err(wrong("State", &other)),
523        }
524    }
525}
526
527/// Something that failed inside a closure the host called later, such as on a click: it
528/// cannot stop the program, so it is kept for whoever shows problems.
529pub fn report(problem: LiveError) {
530    LATE.with(|late| late.borrow_mut().push(problem));
531    tell_watcher();
532}
533
534thread_local! {
535    static LATE: RefCell<Vec<LiveError>> = const { RefCell::new(Vec::new()) };
536    static PRINTED: RefCell<String> = const { RefCell::new(String::new()) };
537    static WATCHER: RefCell<Option<Rc<dyn Fn()>>> = const { RefCell::new(None) };
538}
539
540/// Keeps what `print!` and `println!` (and the `e` ones) wrote, for whoever shows it.
541pub(crate) fn print(text: &str) {
542    PRINTED.with(|printed| printed.borrow_mut().push_str(text));
543    tell_watcher();
544}
545
546/// The lines the program printed since the last time this was asked. A line still being
547/// written, with `print!` and no newline yet, waits for its end.
548pub fn printed() -> Vec<String> {
549    PRINTED.with(|printed| {
550        let mut printed = printed.borrow_mut();
551        let Some(end) = printed.rfind('\n') else { return Vec::new() };
552        let done: String = printed.drain(..=end).collect();
553        done.trim_end_matches('\n').split('\n').map(str::to_owned).collect()
554    })
555}
556
557/// Calls `watcher` whenever the program prints or a closure it gave fails later, so whoever
558/// shows that can read [`printed`] and [`late_problems`]. One at a time: a new one replaces it.
559pub fn on_output(watcher: impl Fn() + 'static) {
560    WATCHER.with(|kept| *kept.borrow_mut() = Some(Rc::new(watcher)));
561}
562
563fn tell_watcher() {
564    // Taken out first, so a watcher that prints does not find it borrowed.
565    let watcher = WATCHER.with(|kept| kept.borrow().clone());
566    if let Some(watcher) = watcher {
567        watcher();
568    }
569}
570
571/// What failed in closures the host called since the last time this was asked.
572pub fn late_problems() -> Vec<LiveError> {
573    LATE.with(|late| std::mem::take(&mut *late.borrow_mut()))
574}