1use std::{cell::RefCell, rc::Rc};
2
3use hashbrown::HashMap;
4
5use crate::{
6 error::{ErrorTypes, SiltError},
7 function::{Closure, FunctionObject, NativeObject},
8 lua::Lua,
9 table::Table,
10 token::Operator,
11 userdata::UserData,
12};
13
14macro_rules! binary_self_op {
19 ($l:ident, $op:tt, $fallback:tt, $r:ident, $opp:tt) => {
20 {
21 match(&mut *$l, $r){
22 (Value::Number(left), Value::Number(right)) => *left $op right,
23 (Value::Integer(left), Value::Integer(right)) =>*left $op right,
24 (Value::Number(left), Value::Integer(right)) => *left $op (*right as f64),
25 (Value::Integer(left), Value::Number(right)) => *$l= Value::Number((*left as f64) $fallback right),
27 (ll,rr) => return Err(SiltError::ExpOpValueWithValue(ll.to_error(), Operator::$opp, rr.to_error()))
29 }
30 Ok(())
31 }
32 };
33}
34
35pub enum Value {
37 Nil,
38 Integer(i64),
39 Number(f64),
40 Bool(bool),
41 Infinity(bool),
43 String(Box<String>),
47 Table(Rc<RefCell<Table>>),
50 Function(Rc<FunctionObject>), Closure(Rc<Closure>),
54 NativeFunction(Rc<NativeObject>),
56 UserData(Rc<dyn UserData>),
57}
58
59pub enum ReferneceStore {
60 Table(HashMap<Value, Value>),
61}
62pub struct Reference<T> {
63 pub value: Rc<T>,
64 pub id: usize,
65}
66
67impl std::fmt::Display for Value {
68 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
69 match self {
70 Value::Integer(i) => write!(f, "{}", i),
71 Value::Number(n) => write!(f, "{}", n),
72 Value::Bool(b) => write!(f, "{}", b),
73 Value::Nil => write!(f, "nil"),
74 Value::String(s) => write!(f, "\"{}\"", s),
75 Value::Infinity(_) => write!(f, "inf"),
76 Value::NativeFunction(_) => write!(f, "native_function"),
77 Value::Closure(c) => write!(f, "=>({})", c.function),
78 Value::Function(ff) => write!(f, "{}", ff),
79 Value::Table(t) => write!(f, "{}", t.borrow().to_string()),
80 Value::UserData(u) => write!(f, "{}", u.to_string()),
81 }
82 }
83}
84
85impl core::fmt::Debug for Value {
86 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
87 write!(f, "{}", self)
88 }
89}
90
91impl Value {
92 pub fn to_error(&self) -> ErrorTypes {
94 match self {
95 Value::Integer(_) => ErrorTypes::Integer,
96 Value::Number(_) => ErrorTypes::Number,
97 Value::Bool(_) => ErrorTypes::Bool,
98 Value::Nil => ErrorTypes::Nil,
99 Value::String(_) => ErrorTypes::String,
100 Value::Infinity(_) => ErrorTypes::Infinity,
101 Value::NativeFunction(_) => ErrorTypes::NativeFunction,
102 Value::Function { .. } => ErrorTypes::Function,
103 Value::Closure(_) => ErrorTypes::Closure,
104 Value::Table(_) => ErrorTypes::Table,
105 Value::UserData(_) => ErrorTypes::UserData,
106 }
107 }
108
109 pub fn force_to_int(&mut self, n: i64) {
110 *self = Value::Integer(n);
111 }
112 pub fn force_to_float(&mut self, n: f64) {
113 *self = Value::Number(n);
114 }
115
116 pub fn increment(&mut self, value: &Value) -> Result<(), SiltError> {
117 binary_self_op!(self, +=,+, value, Add)
118 }
135}
136
137impl Clone for Value {
138 fn clone(&self) -> Self {
139 match self {
140 Value::Integer(i) => Value::Integer(*i),
141 Value::Number(n) => Value::Number(*n),
142 Value::Bool(b) => Value::Bool(*b),
143 Value::Nil => Value::Nil,
144 Value::String(s) => Value::String(s.clone()),
145 Value::Infinity(b) => Value::Infinity(*b),
146 Value::NativeFunction(f) => Value::NativeFunction(f.clone()),
147 Value::Function(r) => Value::Function(Rc::clone(r)),
149 Value::Closure(c) => Value::Closure(Rc::clone(c)),
150 Value::Table(t) => Value::Table(Rc::clone(t)),
155 Value::UserData(u) => Value::UserData(Rc::clone(u)),
156 }
157 }
158}
159
160impl PartialEq for Value {
161 fn eq(&self, other: &Self) -> bool {
162 match (self, other) {
163 (Value::Integer(i), Value::Integer(j)) => i == j,
164 (Value::Number(i), Value::Number(j)) => i == j,
165 (Value::Bool(i), Value::Bool(j)) => i == j,
166 (Value::Nil, Value::Nil) => true,
167 (Value::String(i), Value::String(j)) => i == j,
168 (Value::Infinity(i), Value::Infinity(j)) => i == j,
169 (Value::NativeFunction(i), Value::NativeFunction(j)) => {
170 i.function as *const fn(&mut Lua, Vec<Value>) -> Value
171 == j.function as *const fn(&mut Lua, Vec<Value>) -> Value
172 }
173 (Value::Function(i), Value::Function(j)) => Rc::ptr_eq(i, j),
174 (Value::Table(i), Value::Table(j)) => Rc::ptr_eq(&i, &j),
175 _ => false,
176 }
177 }
178}
179
180impl Default for Value {
181 fn default() -> Self {
182 Value::Nil
183 }
184}
185
186impl core::hash::Hash for Value {
187 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
188 core::mem::discriminant(self).hash(state);
189 }
190}
191
192impl Eq for Value {}
193
194