aplang_lib/interpreter/
value.rs1use std::any::Any;
2use std::cell::RefCell;
3use std::fmt::{Display, Formatter};
4use std::hash::{Hash, Hasher};
5use std::rc::Rc;
6
7#[derive(Clone, Debug)]
10pub enum Value {
11 Null,
12 Number(f64),
13 Bool(bool),
14 String(String),
15 List(Rc<RefCell<Vec<Value>>>),
16 NativeObject(Rc<RefCell<dyn Any>>),
17 NativeFunction(), Function(), }
20
21impl Eq for Value {}
22impl PartialEq for Value {
23 fn eq(&self, other: &Self) -> bool {
24 match (self, other) {
25 (Value::Null, Value::Null) => true,
26 (Value::Number(a), Value::Number(b)) => a == b,
27 (Value::Bool(a), Value::Bool(b)) => a == b,
28 (Value::String(a), Value::String(b)) => a == b,
29 (Value::List(a), Value::List(b)) => *a.borrow() == *b.borrow(),
30 (Value::NativeObject(a), Value::NativeObject(b)) => Rc::ptr_eq(a, b),
31 (Value::NativeFunction(), Value::NativeFunction()) => false, (Value::Function(), Value::Function()) => false, _ => false,
34 }
35 }
36}
37
38impl Hash for Value {
39 fn hash<H: Hasher>(&self, state: &mut H) {
40 match self {
41 Value::Null => state.write_u8(0),
42 Value::Number(n) => state.write_u64(n.to_bits()), Value::Bool(b) => state.write_u8(if *b { 1 } else { 0 }),
44 Value::String(s) => s.hash(state),
45 Value::List(list) => {
46 state.write_u8(4);
47 for item in list.borrow().iter() {
48 item.hash(state);
49 }
50 }
51 Value::NativeObject(obj) => {
52 state.write_u8(5);
53 let ptr = Rc::as_ptr(obj) as * const ();
54 ptr.hash(state);
55 }
56 Value::NativeFunction() => state.write_u8(6), Value::Function() => state.write_u8(7), }
59 }
60}
61
62
63impl Display for Value {
64 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
65 match self {
66 Value::Null => write!(f, "NULL"),
67 Value::List(l) => {
68 let list = l.borrow();
70
71 write!(f, "[")?;
73
74 for (i, item) in list.iter().enumerate() {
76 if i > 0 {
77 write!(f, ", ")?;
79 }
80 write!(f, "{}", item)?;
82 }
83
84 write!(f, "]")
86 }
87 Value::String(s) => write!(f, "{s}"),
88 Value::Number(v) => write!(f, "{v}"),
89 Value::Bool(true) => write!(f, "TRUE"),
90 Value::Bool(false) => write!(f, "FALSE"),
91 _ => {
92 write!(f, "NATIVE")
93 }
94 }
95 }
96}