1use std::cell::RefCell;
2use std::fmt::Debug;
3use std::rc::Rc;
4
5use crate::ast::{Inst, ToId};
6use crate::value::{DynamicValue, Value, Value_};
7use crate::vm_types::{Interruption, Store};
8
9pub use dyn_clone::DynClone;
10
11pub type Result<T = Value_, E = Interruption> = std::result::Result<T, E>;
12
13use crate::type_mismatch;
14
15pub trait Dynamic: Debug + DynClone + DynHash {
17 fn into_value(self) -> Value
18 where
19 Self: 'static + Sized,
20 {
21 Value::Dynamic(DynamicValue(Rc::new(RefCell::new(self))))
22 }
23
24 fn get_index(&self, _store: &Store, _index: Value_) -> Result {
25 Err(Interruption::IndexOutOfBounds)
26 }
27
28 fn set_index(&mut self, _store: &mut Store, _index: Value_, _value: Value_) -> Result<()> {
29 Err(Interruption::IndexOutOfBounds)
30 }
31
32 fn get_field(&self, _store: &Store, name: &str) -> Result {
33 Err(Interruption::UnboundIdentifer(name.to_id()))
34 }
35
36 fn call(&mut self, _store: &mut Store, _inst: &Option<Inst>, _args: Value_) -> Result {
41 type_mismatch!(file!(), line!())
42 }
43
44 fn iter_next(&mut self, _store: &mut Store) -> Result {
45 type_mismatch!(file!(), line!())
46 }
47}
48
49pub trait DynHash {
50 fn dyn_hash(&self, state: &mut dyn std::hash::Hasher);
51}
52
53impl<T: std::hash::Hash + ?Sized> DynHash for T {
54 fn dyn_hash(&self, mut state: &mut dyn std::hash::Hasher) {
55 self.hash(&mut state);
56 }
57}