1use 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
14pub(crate) type Copier = fn(&dyn Any) -> Box<dyn Any>;
16
17#[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 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 pub fn cloneable<T: Clone + 'static>(type_name: &'static str, value: T) -> Self {
34 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 pub(crate) fn held_type(&self) -> Option<std::any::TypeId> {
46 self.cell.borrow().as_ref().map(|any| (**any).type_id())
47 }
48
49 pub fn type_name(&self) -> &'static str {
51 self.type_name
52 }
53
54 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 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
92pub(crate) fn short(path: &str) -> &str {
94 path.rsplit("::").next().unwrap_or(path)
95}
96
97#[derive(Clone)]
99pub enum Value {
100 Unit,
102 Bool(bool),
104 Int(i64),
106 Float(f64),
108 Char(char),
110 Str(String),
112 Tuple(Vec<Value>),
114 List(Vec<Value>),
116 Option(Option<Box<Value>>),
118 Range(i64, i64),
120 FloatRange(f64, f64),
122 Closure(Rc<Closure>),
124 State(State<Value>),
126 Binding(Binding<Value>),
128 Result(Result<Box<Value>, Box<Value>>),
130 Record(Rc<Record>),
132 Place(Rc<RefCell<Value>>),
134 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
194pub struct Record {
196 pub name: String,
198 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 pub fn field(&self, name: &str) -> Option<Value> {
220 self.fields.borrow().iter().find(|(n, _)| n == name).map(|(_, v)| v.clone())
221 }
222
223 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 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 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 pub fn read(&self) -> Value {
254 match self {
255 Self::Place(place) => place.borrow().read(),
256 other => other.clone(),
257 }
258 }
259
260 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 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
296pub trait FromLive: Sized {
298 fn from_live(value: Value) -> Result<Self, String>;
300}
301
302pub trait IntoLive {
304 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
527pub 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
540pub(crate) fn print(text: &str) {
542 PRINTED.with(|printed| printed.borrow_mut().push_str(text));
543 tell_watcher();
544}
545
546pub 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
557pub fn on_output(watcher: impl Fn() + 'static) {
560 WATCHER.with(|kept| *kept.borrow_mut() = Some(Rc::new(watcher)));
561}
562
563fn tell_watcher() {
564 let watcher = WATCHER.with(|kept| kept.borrow().clone());
566 if let Some(watcher) = watcher {
567 watcher();
568 }
569}
570
571pub fn late_problems() -> Vec<LiveError> {
573 LATE.with(|late| std::mem::take(&mut *late.borrow_mut()))
574}