1use serde::{Deserialize, Serialize};
2use std::cell::RefCell;
3use std::collections::{HashMap, HashSet};
4use std::fmt::Debug;
5use std::hash::{Hash, Hasher};
6use std::rc::Rc;
7
8use crate::{ty::Type, upvalue::UpValue};
9
10#[derive(Clone)]
11#[derive(Deserialize, Serialize)]
12pub enum Value {
13 Field(String),
14 Ty(Type),
15 Blob(usize),
16 Instance(usize, Rc<RefCell<HashMap<String, Value>>>),
17 Tuple(Rc<Vec<Value>>),
18 List(Rc<RefCell<Vec<Value>>>),
19 Set(Rc<RefCell<HashSet<Value>>>),
20 Dict(Rc<RefCell<HashMap<Value, Value>>>),
21 Union(HashSet<Value>),
22 Float(f64),
23 Int(i64),
24 Bool(bool),
25 String(Rc<String>),
26 Function(Rc<Vec<Rc<RefCell<UpValue>>>>, Type, usize),
27 ExternFunction(usize),
28 Unknown,
31 Nil,
33}
34
35impl From<&str> for Value {
36 fn from(s: &str) -> Self {
37 Value::String(Rc::new(s.to_string()))
38 }
39}
40
41impl From<&Type> for Value {
42 fn from(ty: &Type) -> Self {
43 match ty {
44 Type::Field(s) => Value::Field(s.clone()),
45 Type::Void => Value::Nil,
46 Type::Blob(b) => Value::Blob(*b),
47 Type::Instance(b) => Value::Instance(*b, Rc::new(RefCell::new(HashMap::new()))),
48 Type::Tuple(fields) => Value::Tuple(Rc::new(fields.iter().map(Value::from).collect())),
49 Type::Union(v) => Value::Union(v.iter().map(Value::from).collect()),
50 Type::List(v) => Value::List(Rc::new(RefCell::new(vec![Value::from(v.as_ref())]))),
51 Type::Set(v) => {
52 let mut s = HashSet::new();
53 s.insert(Value::from(v.as_ref()));
54 Value::Set(Rc::new(RefCell::new(s)))
55 }
56 Type::Dict(k, v) => {
57 let mut s = HashMap::new();
58 s.insert(Value::from(k.as_ref()), Value::from(v.as_ref()));
59 Value::Dict(Rc::new(RefCell::new(s)))
60 }
61 Type::Unknown | Type::Invalid => Value::Unknown,
62 Type::Int => Value::Int(1),
63 Type::Float => Value::Float(1.0),
64 Type::Bool => Value::Bool(true),
65 Type::String => Value::String(Rc::new("".to_string())),
66 Type::Function(a, r) => {
67 Value::Function(Rc::new(Vec::new()), Type::Function(a.clone(), r.clone()), 0)
68 }
69 Type::ExternFunction(x) => Value::ExternFunction(*x),
70 Type::Ty => Value::Ty(Type::Void),
71 }
72 }
73}
74
75impl From<Type> for Value {
76 fn from(ty: Type) -> Self {
77 Value::from(&ty)
78 }
79}
80
81impl From<&Value> for f64 {
84 fn from(v: &Value) -> Self {
85 if let Value::Float(f) = v {
86 *f
87 } else {
88 panic!("Value is not a float")
89 }
90 }
91}
92
93impl From<&Value> for i64 {
94 fn from(v: &Value) -> Self {
95 if let Value::Int(i) = v {
96 *i
97 } else {
98 panic!("Value is not a float")
99 }
100 }
101}
102
103impl Debug for Value {
104 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
105 match self {
107 Value::Field(s) => write!(fmt, "( .{} )", s),
108 Value::Ty(ty) => write!(fmt, "(type {:?})", ty),
109 Value::Blob(b) => write!(fmt, "(blob b{})", b),
110 Value::Instance(b, v) => write!(fmt, "(inst b{} {:?})", b, v),
111 Value::Float(f) => write!(fmt, "(float {})", f),
112 Value::Int(i) => write!(fmt, "(int {})", i),
113 Value::Bool(b) => write!(fmt, "(bool {})", b),
114 Value::String(s) => write!(fmt, "(string \"{}\")", s),
115 Value::List(v) => write!(fmt, "(array {:?})", v),
116 Value::Set(v) => write!(fmt, "(set {:?})", v),
117 Value::Dict(v) => write!(fmt, "(dict {:?})", v),
118 Value::Function(_, ty, block) => {
119 write!(fmt, "(fn #{} {:?})", block, ty)
120 }
121 Value::ExternFunction(slot) => write!(fmt, "(extern fn {})", slot),
122 Value::Unknown => write!(fmt, "(unknown)"),
123 Value::Nil => write!(fmt, "(nil)"),
124 Value::Tuple(v) => write!(fmt, "({:?})", v),
125 Value::Union(v) => write!(fmt, "(U {:?})", v),
126 }
127 }
128}
129
130impl PartialEq<Value> for Value {
131 fn eq(&self, other: &Value) -> bool {
132 match (self, other) {
133 (Value::Float(a), Value::Float(b)) => a == b,
134 (Value::Int(a), Value::Int(b)) => a == b,
135 (Value::Bool(a), Value::Bool(b)) => a == b,
136 (Value::String(a), Value::String(b)) => a == b,
137 (Value::Tuple(a), Value::Tuple(b)) => {
138 a.len() == b.len() && a.iter().zip(b.iter()).all(|(a, b)| a == b)
139 }
140 (Value::List(a), Value::List(b)) => a == b,
141 (Value::Set(a), Value::Set(b)) => a == b,
142 (Value::Dict(a), Value::Dict(b)) => a == b,
143 (Value::Union(a), b) | (b, Value::Union(a)) => a.iter().any(|x| x == b),
144 (Value::Nil, Value::Nil) => true,
145 _ => false,
146 }
147 }
148}
149
150impl Eq for Value {}
151
152impl Hash for Value {
153 fn hash<H: Hasher>(&self, state: &mut H) {
154 match self {
155 Value::Float(a) => {
156 assert!(a.is_finite());
159 a.to_bits().hash(state);
160 }
161 Value::Int(a) => a.hash(state),
162 Value::Bool(a) => a.hash(state),
163 Value::String(a) => a.hash(state),
164 Value::Tuple(a) => a.hash(state),
165 Value::Nil => state.write_i8(0),
166 _ => {}
167 };
168 }
169}
170
171impl Value {
172 pub fn is_nil(&self) -> bool {
173 matches!(self, Value::Nil)
174 }
175
176 pub fn unique_id(&self) -> usize {
177 match self {
178 Value::Field(s) => s as *const _ as usize,
179 Value::Ty(ty) => ty as *const _ as usize,
180 Value::Blob(b) => b as *const _ as usize,
181 Value::Float(f) => f as *const _ as usize,
182 Value::Int(i) => i as *const _ as usize,
183 Value::Bool(b) => b as *const _ as usize,
184 Value::Union(v) => v as *const _ as usize,
185 Value::Instance(_, v) => Rc::as_ptr(v) as usize,
186 Value::String(s) => Rc::as_ptr(s) as usize,
187 Value::List(v) => Rc::as_ptr(v) as usize,
188 Value::Set(v) => Rc::as_ptr(v) as usize,
189 Value::Dict(v) => Rc::as_ptr(v) as usize,
190 Value::Function(v, _, _) => Rc::as_ptr(v) as usize,
191 Value::Tuple(v) => Rc::as_ptr(v) as usize,
192 Value::Nil => 0, Value::Unknown => 1, Value::ExternFunction(slot) => slot + 2,
195 }
196 }
197}
198
199#[derive(Clone)]
200pub enum MatchableValue<'t> {
201 Empty,
202 One(&'t Value),
203 Two(&'t Value, &'t Value),
204 Three(&'t Value, &'t Value, &'t Value),
205 Four(&'t Value, &'t Value, &'t Value, &'t Value),
206 Five(&'t Value, &'t Value, &'t Value, &'t Value, &'t Value),
207}
208
209pub fn make_matchable<'t>(value: &'t Value) -> MatchableValue<'t> {
210 use MatchableValue::*;
211 use Value::*;
212
213 match value {
214 #[rustfmt::skip]
215 Tuple(inner) => {
216 match (inner.get(0), inner.get(1), inner.get(2), inner.get(3), inner.get(4)) {
217 (Some(a), Some(b), Some(c), Some(d), Some(e), ..) => Five(a, b, c, d, e),
218 (Some(a), Some(b), Some(c), Some(d), ..) => Four(a, b, c, d),
219 (Some(a), Some(b), Some(c), ..) => Three(a, b, c),
220 (Some(a), Some(b), ..) => Two(a, b),
221 (Some(a), ..) => One(a),
222 _ => Empty,
223 }
224 },
225 x => One(x),
226 }
227}